简介

站在内存管理的角度看eCos操作系统,就是一个进程。eCos系统中只有线程概念(任务),并没有进程概念。整个内存规划简单看就是一个进程的内存分布。

alt text

既然一个进程,内存中会有text、data、bss、heap段等。

eCos查看内存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 mbuf
twork stack mbuf stats:
mbufs 69, clusters 2360, free clusters 56
Failed to get 0 times
Waited to get 0 times
Drained queues to get 0 times
VM zone 'ripcb':
Total: 32, Free: 31, Allocs: 88, Frees: 87, Fails: 0
VM zone 'divcb':
Total: 2, Free: 2, Allocs: 0, Frees: 0, Fails: 0
VM zone 'tcpcb':
Total: 256, Free: 250, Allocs: 172, Frees: 166, Fails: 0
VM zone 'udpcb':
Total: 256, Free: 248, Allocs: 9244, Frees: 9236, Fails: 0
VM zone 'socket':
Total: 256, Free: 241, Allocs: 9504, Frees: 9489, Fails: 0
Misc mpool: total 7602176, free 1797136, max free block 1794852
Mbufs pool: total 1834752, free 1816064, blocksize 256
Clust pool: total 14801600, free 10419584, blocksize 1856

Memory system:
Total 33554432 bytes
Heap 533024 bytes, Free 309052 bytes, Max 304532 bytes

乍一看,mbuf打印信息很多,系统到底剩余多少内存呢?我第一次看就是一头雾水,并不像linux那么直观.

1
2
3
4
$ free
total used free shared buff/cache available
Mem: 32508724 1443468 22506000 175600 8559256 30422568
Swap: 31999996 0 31999996

拆解mbuf命令

  • 系统内存总共32M,先看Memory system
1
2
3
Memory system:
Total 33554432 bytes
Heap 533024 bytes, Free 309052 bytes, Max 304532 bytes

Total 为总内存:

33554432/1024/1024
32.0

Heap为应用线程使用的内存。533024 bytes.

这里的Heap内存为上图中的heap区域。

  • pool内存
1
2
3
Misc mpool: total 7602176, free 1797136, max free block 1794852
Mbufs pool: total 1834752, free 1816064, blocksize 256
Clust pool: total 14801600, free 10419584, blocksize 1856
  1. Misc mpool为驱动kmalloc提供内存分配(没有slab机制,后期内存碎片化较严重)
  2. Mbufs pool是一个真正意义上的内存池(固定长度内存),为网络协议栈mbuf m_mballoc提供内存。
  3. Clust pool是另一个内存池,为网络协议栈mbuf m_clalloc提供内存。

Misc mpool、Mbufs pool、Clust pool这三块内存是eCos定义的三个大buff,然后自己玩的。这点可以从bss段大小可以说明,这三个buf占了总内存的72%。

(7602176+1834752+14801600)/1024/1024
23.11566162109375

  • bss段

通过readelf -sa ecos.elf | grep __bss命令,查看bss段。

1
2
12329: 8063d5a0     0 NOTYPE  GLOBAL DEFAULT    7 __bss_start
15222: 81f80000 0 NOTYPE GLOBAL DEFAULT 9 __bss_end

可以看到bss段有25M以上。

1
2
>>> int('81f80000',16) - int('8063d5a0',16) = 26487392
>>> 26487392/1024/1024 = 25.260345458984375

这里也可以说明eCos的内存管理方式很暴力,在程序中开一个buff,然后自己来玩这块buff。

alt text

eCos提供两种内存机制

  • 固定大小内存

固定大小内存分配其实就时内存中,在ecos中使用cyg_mempool_fix_create创建,使用cyg_mempool_fix_alloccyg_mempool_fix_try_alloc申请。

  • 不固定大小内存

不固定大小内存系统启动前期可以最大限度使用内存,但是随着系统运行会产生内存碎片。ecos中使用cyg_mempool_var_create创建,cyg_mempool_var_alloccyg_mempool_var_try_alloc申请内存。

eCos中的函数接口

1
2
3
4
5
6
./ecos-3.0/packages/net/bsd_tcpip/v3_0/src/ecos/support.c

cyg_net_malloc();

cyg_net_mbuf_alloc();
cyg_net_cluster_alloc();
  • cyg_net_malloc

驱动中kmalloc的内存申请,

  • cyg_net_mbuf_alloc
1
2
3
// ./ecos-3.0/packages/net/bsd_tcpip/v3_0/src/sys/kern/uipc_mbuf.c
m_mballoc();
cyg_net_mbuf_alloc();
  • cyg_net_cluster_alloc
1
2
3
// ./ecos-3.0/packages/net/bsd_tcpip/v3_0/src/sys/kern/uipc_mbuf.c
m_clalloc();
cyg_net_cluster_alloc();

总结

eCos再我所在的公司目前用在家用路由器产品中,可以看到内存基本都是在服务协议栈mbuf这块。而供给驱动(kmalloc)内存较少,而且目前内存模块老旧,不支持slab等先进内存分配机制。顾随着系统运行时间增加,kmalloc部分内存碎片化验证,在设备高负载情况下,后期驱动很难分配出大块内存。