zImage内核与ramdisk及bmem及vmalloc关系的研究探索


问题的初衷:
将zImage的内核读入一段内存后,能否将rootfs(ramdisk方式运行)加载到紧挨着kernel之后?
担心的问题:由于zImage内核的特殊性,在跳转至内核执行入口之后,内核会自己解压缩自己,解压缩时是否占用额外内存?如过占用kernel之后的内存做为解压缩缓冲,那么就会和rootfs地址发生冲突。

测试:
给定不带rootfs的kernel vmlinuz-7260a(SDK17.1),rootfs.squashfs(大小是0x31E108)

test01:
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x41E108  usbdisk0:rootfs.squashfs;go 0x100000 'initrd=0x41E108,10M'
fail
分析:挂载rootfs失败的原因很可能是rootfs起始地址不对齐导致的,结合下文,其实不是地址不对齐问题
test02:将rootfs紧挨kernel,但做一个地址对齐:
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x420000  usbdisk0:rootfs.squashfs;go 0x100000 'initrd=0x420000,10M'
fail
test03:将rootfs远离kernel,做一个地址对齐:
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x820000  usbdisk0:rootfs.squashfs;go 0x100000 'initrd=0x820000,10M'
fail
分析:结合test01-03,最终发现无法挂载的原因是,go命令无法传递bootargs。

改为利用dram0(bolt中设定的dram0起始地址为0x100000)来启动内核:
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x41E108  usbdisk0:rootfs.squashfs;boot DRAM0: 'initrd=0x41E108,10M'
fail:此时加载失败是显而易见的,因为kernel解压缩之后的尺寸会远大于原来尺寸。

load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x800000  usbdisk0:rootfs.squashfs;boot DRAM0 'root=/dev/ram0 rootwait rw rootfstype=squashfs initrd=0x800000,10M'
fail
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x2000000  usbdisk0:rootfs.squashfs;boot DRAM0: 'initrd=0x2000000,10M'
ok,由此可以看出,rootfs的起始地址不能太靠前

load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0xB00000  usbdisk0:rootfs.squashfs;boot DRAM0: 'initrd=0xB00000,10M'
fail
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0xBE0000  usbdisk0:rootfs.squashfs;boot DRAM0: 'initrd=0xBE0000,10M'
fail
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0xBF0000  usbdisk0:rootfs.squashfs;boot DRAM0: 'initrd=0xBF0000,10M'
ok
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0xC00000  usbdisk0:rootfs.squashfs;boot DRAM0: 'initrd=0xC00000,10M'
ok
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x1000000  usbdisk0:rootfs.squashfs;boot DRAM0: 'initrd=0x1000000,5586944'
ok

内核启动时的内存布局:
[    0.000000] Memory: 227868K/1048576K available (6145K kernel code, 268K rwdata, 2172K rodata, 312K init, 188K bss, 804324K reserved, 16384K cma-reserved, 0K highmem)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0xd0800000 - 0xff000000   ( 744 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xd0000000   ( 256 MB)
[    0.000000]     pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
[    0.000000]     modules : 0xbf000000 - 0xbfe00000   (  14 MB)
[    0.000000]       .text : 0xc0008000 - 0xc0827a7c   (8319 kB)
[    0.000000]       .init : 0xc0828000 - 0xc0876000   ( 312 kB)
[    0.000000]       .data : 0xc0876000 - 0xc08b9268   ( 269 kB)
[    0.000000]        .bss : 0xc08bc000 - 0xc08eb1e0   ( 189 kB)

分析:rootfs即使放在bss之后,如果间隔不算大也不能挂载成功。



其它测试:
load -raw -addr=0x2000000 usbdisk0:rootfs.squashfs ; boot usbdisk0:vmlinuz-7260a0 'ramdisk_size=28000 rootfstype=squashfs initrd=0x2000000,10M'
ok
load -raw -addr=0x2000000 usbdisk0:rootfs.squashfs ; boot usbdisk0:vmlinuz-7260a0 'ramdisk_size=28000 initrd=0x2000000,10M'
ok
load -raw -addr=0x2000000 usbdisk0:rootfs.squashfs ; boot usbdisk0:vmlinuz-7260a0 'initrd=0x2000000,10M'
ok
load -raw -addr=0x2000000 usbdisk0:rootfs.squashfs ; boot usbdisk0:vmlinuz-7260a0 'root=/dev/ram0 rootwait rw ramdisk_size=28000 rootfstype=squashfs initrd=0x2000000,10M'
分析:ramdisk_size只是指定内核启动之后/dev/ram*的大小,和rootfs其实并没有关系,rootfs并没有存在/dev/ram0中,一个验证方法是用dd将/dev/ram0写满zero,并没有影响系统运行


load -raw -addr=0x231E108 usbdisk0:rootfs.squashfs ; boot usbdisk0:vmlinuz-7260a0 'initrd=0x231E108,10M'
ok,由此看出。rootfs的起始地址并不需要页对齐,当然最好对齐
# mount
/dev/root.old on / type squashfs (ro,relatime)

load -raw -addr=0x231E108 usbdisk0:rootfs.squashfs ; boot usbdisk0:vmlinuz-7260a0 'root=/dev/ram0 rootwait rw ramdisk_size=28000 rootfstype=squashfs initrd=0x231E108,10M'
# mount
/dev/root on / type squashfs (ro,relatime)
分析:root=/dev/ram0是否存在,会导致rootfs的挂在设备不一样,一个是/dev/root.old,一个是/dev/root,但似乎并没什么影响;



initrd=xxx,yyy 中的yyy远大于rootfs实际大小时,是否会造成内存浪费?
test1:
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x1000000  usbdisk0:rootfs.squashfs;boot DRAM0: 'initrd=0x1000000,6M'
# df /
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/root.old             5504      5504         0 100% /
# free
             total         used         free       shared      buffers
Mem:        244252        17704       226548            0         1208
-/+ buffers:              16496       227756
Swap:            0            0            0

test2:
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x1000000  usbdisk0:rootfs.squashfs;boot DRAM0: 'initrd=0x1000000,100M'
# df /
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/root.old             5504      5504         0 100% /
# free
             total         used         free       shared      buffers
Mem:        244316        17064       227252            0         1208
-/+ buffers:              15856       228460
Swap:            0            0            0

通过test1&2得出结论:yyy过大并不会导致内存浪费,但yyy过小会导致rootfs挂载失败。

test3:
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x1000000  usbdisk0:rootfs.squashfs;boot DRAM0: 'initrd=0x1000000,256M'
结果:kernel无法启动,因此,initrd的size又不能过大,否则系统无法启动,但rootfs的上限和什么有关系呢?

load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x9300000  usbdisk0:rootfs.squashfs;boot DRAM0: 'bmem=100M@924M initrd=0x9300000,256M'
fail:内核无法启动,因此rootfs的大小上限可能和bmem并没有直接关系
注:0x9300000是位于bolt内存之后的地址

load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x9300000  usbdisk0:rootfs.squashfs;boot DRAM0: 'bmem=100M@924M initrd=0x9300000,128M'
fail: 内核无法启动

load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x9300000  usbdisk0:rootfs.squashfs;boot DRAM0: 'bmem=100M@924M initrd=0x9300000,16M'
ok:启动、挂载正常

load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x9300000  usbdisk0:rootfs.squashfs;boot DRAM0: 'bmem=100M@924M initrd=0x9300000,100M'
ok

分析:此bootargs下,kernel的内存布局是:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0xd0800000 - 0xff000000   ( 744 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xd0000000   ( 256 MB)
[    0.000000]     pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
[    0.000000]     modules : 0xbf000000 - 0xbfe00000   (  14 MB)
[    0.000000]       .text : 0xc0008000 - 0xc0827a7c   (8319 kB)
[    0.000000]       .init : 0xc0828000 - 0xc0876000   ( 312 kB)
[    0.000000]       .data : 0xc0876000 - 0xc08b9268   ( 269 kB)
[    0.000000]        .bss : 0xc08bc000 - 0xc08eb1e0   ( 189 kB)
其中,lowmem共256M,而我们从0x9300000也就是147M开始加载rootfs,那么lowmem中共剩余109M。

为了验证rootfs和lowmem有关,我们将initrd的大小设置为超过lowmem,比如110M,如下:
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x9300000  usbdisk0:rootfs.squashfs;boot DRAM0: 'bmem=100M@924M initrd=0x9300000,110M'
结果fail:因此,我们有理由怀疑,kernel中可能必须要将rootfs必须放到低端内存区(lowmem,也即ZONE_NORMAL)
而如果将rootfs大小设为lowmem的边界,也就是109M:
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x9300000  usbdisk0:rootfs.squashfs;boot DRAM0: 'bmem=100M@924M initrd=0x9300000,109M'
ok!

继续深入分析:这种情况下我们没有在bootargs中设定vmalloc,导致vmalloc过大,lowmem过小。
我们知道,上述kernel中的内存布局是指虚拟内存的布局,而非物理内存的布局,且虚拟地址空间的lowmem与物理内存的低端内存管理区(ZONE_NORMAL)其实是线性映射关系,也就是说,lowmem的0xc0000000~0xd0000000就是对应着物理内存的前256M;
vmalloc区位于虚拟地址空间的highmem段,vmalloc分配的内存并不是连续的物理内存,而是从伙伴系统获取的零散物理页框,然后通过修改主内核页表的方式把这些零散的物理页框映射到连续的虚拟地址上;vmalloc一般会优先从物理内存的高端管理区ZONE_HIGHMEM中获取页框,但是当条件不允许时,也可以从低端内存区ZONE_NORMAL中获取页框,一般不从ZONE_NORMAL中获取页框的原因是防止频繁修改normal区的内核页表,进而频繁刷新TLB缓冲导致影响系统性能。
对与bmem=100M@924M,可能有人会认为bmem与vmalloc区间发生了重叠,其实这是错误的理解,因为bmem指的物理地址空间,而vmalloc位于虚拟地址空间,两者根本不在一个维度内!

现在,我们通过bootargs来增大lowmem,减小vmalloc,看看rootfs能否做成很大的值:
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x9300000  usbdisk0:rootfs.squashfs;boot DRAM0: 'vmalloc=700M bmem=100M@924M initrd=0x9300000,161M'
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0xd3800000 - 0xff000000   ( 696 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xd3400000   ( 308 MB)
[    0.000000]     pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
[    0.000000]     modules : 0xbf000000 - 0xbfe00000   (  14 MB)
[    0.000000]       .text : 0xc0008000 - 0xc0827a7c   (8319 kB)
[    0.000000]       .init : 0xc0828000 - 0xc0876000   ( 312 kB)
[    0.000000]       .data : 0xc0876000 - 0xc08b9268   ( 269 kB)
[    0.000000]        .bss : 0xc08bc000 - 0xc08eb1e0   ( 189 kB)
奇迹发生了!此时由于lowmem大小是308M,rootfs的尺寸上限变成了161M!

实测超大rootfs:rootfs.squashfs.129M
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x9300000  usbdisk0:rootfs.squashfs.129M;boot DRAM0: 'vmalloc=700M bmem=100M@924M initrd=0x9300000,161M'
fail,原因:内核打印如下,看来如果rootfs超过了默认的ramdisk大小,必须要显式指定ramdisk了
RAMDISK: image too big! (125826KiB/8192KiB),

load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x9300000  usbdisk0:rootfs.squashfs.129M;boot DRAM0: 'ramdisk_size=133120 vmalloc=700M bmem=100M@924M initrd=0x9300000,161M'
fail:
squashfs: SQUASHFS error: unable to read id index table
分析:bolt的load命令,把上限设定成了0x2000000,也就是只加载了36M,soga!
Loader:raw Filesys:fat Dev:usbdisk0 File:rootfs.squashfs.129M Options:(null)
Loading: ...........
 33554432 bytes read
Entry address is 0x9300000

设定load命令的-max参数为256M:
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x9300000 -max=0x10000000  usbdisk0:rootfs.squashfs.129M;boot DRAM0: 'ramdisk_size=133120 vmalloc=400M bmem=100M@924M initrd=0x9300000,161M'
ok!

实测超大rootfs:rootfs.squashfs.170M
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x9300000 -max=0x10000000  usbdisk0:rootfs.squashfs.170M;boot DRAM0: 'ramdisk_size=183120 vmalloc=400M bmem=100M@924M initrd=0x9300000,170M'
ok!并且能够在rootfs中成功执行reboot

把SSBL的运行地址向后挪了0x10000000(256M):
Total memory used by BOLT: 0x16FFC000 - 0x19200000 (35667968)
FSBL info area:            0x16FFC000 - 0x16FFC048 (72)
Page table base:           0x17000000
Text (code) segment:       0x170080F0 - 0x1703B000 (208656)
Initialized Data:          0x1703B000 - 0x170834D0 (296144)
BSS Area:                  0x170834D0 - 0x1708FE60 (51600)
Local Heap:                0x17100000 - 0x19100000 (33554432)
Stack Area:                0x19100000 - 0x19200000 (1048576)
注意:vmalloc调整了:
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x1000000 -max=0x10000000  usbdisk0:rootfs.squashfs.129M;boot DRAM0: 'ramdisk_size=133120 vmalloc=400M bmem=100M@924M initrd=0x1000000,161M'
fail!kernel直接无法启动,why?
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x1000000 -max=0x10000000  usbdisk0:rootfs.squashfs;boot DRAM0: 'vmalloc=200M bmem=100M@924M initrd=0x1000000,10M'
ok
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x1000000 -max=0x10000000  usbdisk0:rootfs.squashfs.129M;boot DRAM0: 'vmalloc=200M bmem=100M@924M initrd=0x1000000,160M'
fail
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x1000000 -max=0x10000000  usbdisk0:rootfs.squashfs.91M;boot DRAM0: 'vmalloc=200M bmem=0M  initrd=0x1000000,91M'
fail!

为验证是否和bolt内存调整有关,换回原bolt:
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x1000000 -max=0x10000000  usbdisk0:rootfs.squashfs.91M;boot DRAM0: 'ramdisk_size=93184 vmalloc=200M bmem=100M@924M  initrd=0x1000000,91M'
fail!竟然也失败?内核无法启动,打印停在如下,why?????
Starting program at 0x8000 (DTB @ 0x7649000)
32 bit PSCI boot...
此处打印是bolt打印,说明kernel有可能还没开始执行,而是bolt的某数据被破坏导致的!


load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x1000000 -max=0x10000000  usbdisk0:rootfs.squashfs.53M;boot DRAM0: 'ramdisk_size=80000 vmalloc=200M bmem=100M@924M  initrd=0x1000000,53M'
ok
分析:kernel启动时有如下打印:
32 bit PSCI boot...
PSCI: DTB @ 0000000007649000, Linux entry @ 0000000000008000
PWR_UP-CPU1 OK
BOOT32
ADDR-CPU1  00000000064025b0 @ RDB: 20452008

我们假设0x64025b0(100M+)是DRAM地址,那么我们先让rootfs在这个边界内,99M-16M=83M
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x1000000 -max=0x10000000  usbdisk0:rootfs.squashfs.82M;boot DRAM0: 'ramdisk_size=90000 vmalloc=200M bmem=100M@924M  initrd=0x1000000,82M'
ok!
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x1000000 -max=0x10000000  usbdisk0:rootfs.squashfs.85M;boot DRAM0: 'ramdisk_size=90000 vmalloc=200M bmem=100M@924M  initrd=0x1000000,85M'
ok
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x1000000 -max=0x10000000  usbdisk0:rootfs.squashfs.86M;boot DRAM0: 'ramdisk_size=90000 vmalloc=200M bmem=100M@924M  initrd=0x1000000,86M'
ok
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x1000000 -max=0x10000000  usbdisk0:rootfs.squashfs.88M;boot DRAM0: 'ramdisk_size=90000 vmalloc=200M bmem=100M@924M  initrd=0x1000000,88M'
ok 分析:16M+88M=104M > 100M,说明和 “ADDR-CPU1  00000000064025b0”并没有关系。
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x1000000 -max=0x10000000  usbdisk0:rootfs.squashfs.89M;boot DRAM0: 'ramdisk_size=90000 vmalloc=200M bmem=100M@924M  initrd=0x1000000,89M'
fail!
到底为啥呢?rootfs大小为何远远达不到bolt的起始地址?并且,bolt内存前移256M的版本,rootfs极限和原bolt一样,why?
并且,濒临极限的rootfs(88M),即使能挂载成功,reboot无法成功,必现,why?经验证和vmalloc过小没关系,将vmalloc改成400M也不行


为了排查是否和squashfs有关,我们使用rootfs.ext4.94M,看是否能够挂载:
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x1000000 -max=0x10000000  usbdisk0:rootfs.ext4.94M;boot DRAM0: 'ramdisk_size=100000 vmalloc=300M bmem=100M@924M  initrd=0x1000000,95M'
fail,表现一样。从内核根本无法启动看,不像是和fs类型有关系。

继续实验:
采用rootfs.squashfs.6M,将rootfs的加载地址设置的比较高,以覆盖16M+85M左右的地址,我们设在98M(0x6200000)
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x6200000 -max=0x10000000  usbdisk0:rootfs.squashfs.6M;boot DRAM0: 'ramdisk_size=10000 vmalloc=200M bmem=100M@924M  initrd=0x1000000,6M'
fail!
为了排除是否和-max=0x10000000有关,我们将-max设为6M:
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x6200000 -max=0x600000 usbdisk0:rootfs.squashfs.6M;boot DRAM0: 'ramdisk_size=10000 vmalloc=200M bmem=100M@924M  initrd=0x6200000,6M'
fail!
为了验证是否和地址16M+85M有关,我们将rootfs设置为这个之上,假设为105M(105M + 6M = 111M,没有触及bolt内存)
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x6900000 -max=0x600000 usbdisk0:rootfs.squashfs.6M;boot DRAM0: 'ramdisk_size=10000 vmalloc=200M bmem=100M@924M  initrd=0x6900000,6M'
ok!如此,更加印证了16M+85M左右的地址处有毛腻!

经再次排查bolt的内存,发现PSCI_BASE的地址是0x6400000,整好100M!问题终于找到了。
将PSCI的地址、bolt的地址都前移256M之后,启动超大rootfs成功!
load -raw -addr=0x100000 usbdisk0:vmlinuz-7260a0;load -raw -addr=0x1000000 -max=0x10000000  usbdisk0:rootfs.squashfs.170M;boot DRAM0: 'ramdisk_size=183120 vmalloc=400M bmem=100M@924M initrd=0x1000000,170M'




再继续深入分析:
为何建议在bootargs中vmalloc与bmem要配合使用?并且应使用nexus运行时推荐的vmalloc+bmem?这样做的目的是避免bmem落在ZONE_NORMAL区!因为lowmem与ZONE_NORMAL是线性映射,如过bmem落在了ZONE_NORMAL中,势必会破坏这段线性映射关系,导致内核运行异常!在nexus的doc中也解释了这个问题。


总结:
1,kernel所需内存并不是vmlinuz-7260a0的文件大小,而是解压缩之后的文件大小,加上bss段等的大小,应参考kernel运行时打印的内存布局;
2,经测试,将rootfs紧紧放在kernel的bss段值后也是不行的,可能的原因是kernel stack、或者zImage的自解压自搬运需要缓存,实测试情况:
若将vmlinuz放到0x100000的位置,那么需至少将rootfs放到0xC00000的位置,哪怕0xB00000也会挂载失败;
为保险其见,我们可再预留出更多空间,将rootfs起始地址设为0x1000000,也就是说前16M都留给kernel用。
3,当rootfs大小超过内核默认的ramdisk大小(一般是8M)时,bootargs中必须指定ramdisk_size(单位是KB),ramdisk_size指定了内核启动之后/dev/ram*的大小,然而rootfs并没有存在/dev/ram0中,一个验证方法是用dd将/dev/ram0写满zero,并没有影响系统运行;
4,initrd的起始地址并不需要页对齐,当然对齐最好;
5,initrd=xxx,yyy 其中yyy可以是0x200000这样的十六进制数,也可以是以M为单位的十进制树,如“10M”,为保持一致性,建议统一才用16进制表示;
6,initrd=xxx,yyy 其中如果yyy的值远大于rootfs的实际大小,并不会导致内存浪费;
7,initrd=xxx,yyy yyy的值并不可以任意大,其最小值是rootfs的大小,最大值应不超过lowmem的边界上限;而lowmem作为一段非常重要的内存资源,全被rootfs占满是非常不明智的,例如会导致slab资源紧张;
8,bootargs中的vmalloc与bmem,建议使用nexus初始化时推荐的值,这样一来避免内存浪费,二来避免bmem与ZONE_NORMAL发生重叠导致内核运行异常;
9,建议将rootfs的内存地址限定在 (0x1000000, bolt)之间,如果rootfs过大导致不得不放到bolt内存之后,那么你必须非常清楚你现在到底在做什么,要综合考虑rootfs、vmalloc、bmem的设定;
10,调整bolt的运行内存地址也是一个增加rootfs上限的方法,但这种方法不在本文的讨论范围内,而且,无论如何都应考虑lowmem的限制。




你可能感兴趣的:(内存管理,Linux)