最近在做系统剪裁,发现可见物理内存为103MB(128M),其中有24M内存消失了,表示对这一现象很是奇怪,下面讲述了我找这24MB的心路历程。
目标板子配置:
板子为ARM架构、板子上有256MB内存,内核版本为4.9.54
Linux version 4.9.54 (jenkins@localhost.localdomain) (gcc version 6.3.1 20170109 (Linaro GCC 6.3-2017.02) ) #8 SMP PREEMPT Fri Jul 27 17:29:51 HKT 2018
为了避免由于内存硬件差异导致的内存差异,(这一点我还真不清楚,真实的可用物理内存,比标签的内存要小点,小多少我不知道),在dts设置中,设定给系统内存设置为128M,设置如下
memory@00000000 {
device_type = "memory";
linux,usable-memory = <0x0 0x000000 0x0 0x8000000>;
};
重新编译后,进入系统,查看系统内存使用情况如下,系统可用物理内存为105600KB,即为103MB(使用htop更能明显的看出来)
cat /proc/meminfo
MemTotal: 105600 kB
MemFree: 2732 kB
.......
CmaTotal: 8192 kB
CmaFree: 0 kB
# free
total used free shared buffers cached
Mem: 105600 102332 3268 116 0 29740
-/+ buffers/cache: 72592 33008
Swap: 0 0 0
从这里可以发现,系统的可见物理内存只有103MB,还有128MB - 103MB = 24MB不知道去哪里了。
然后网上查查查查,发现系统kernel和用户层的内存是不能相互可见的,都是相对独立的,想在用户层访问kernel的内存,可以通过某些方式把这块内存的地址读取上来(还有更多方法,不多介绍)。然后就去找kernel的二进制文件vmlinux.o,使用size和objdump查看此文件
size vmlinux
text data bss dec hex filename
8423164 2480188 509012 11412364 ae238c vmlinux
test为代码段,data和bss也都是放在内存的段,data是放初始化了的全局静态变量和局部静态变量,bss是放未初始化的全局变量和局部静态变量,bss也是会提前在内存中预留空间,所以这三段在kernel运行时候都是在内存中分配的,计算得
(8423164 + 2480188 + 509012) / 1024 / 1024.0 = 10.8828125MB
这大约11MB的内存是kernel在运行时候被划分给kernel的,用户层无法访问,对用户层也是不可见的,所以使用htop、free看到的可用物理内存是没有这一部分的,24MB - 11MB = 13MB,然而还有13MB不知道是哪里拿走了。
接着网上查查查查,发现是系统预留了,但是网上没有找到具体是什么预留怎么预留的,继续研究,发现dts文件中有 reserved-memory的关键字,有两部分ramoops预留了1M,secmon_reserved分配了4M内存,这部分内存对用户层也是不可见的。