 
- UID
- 1029342
- 性别
- 男
|

1. 启动时initrd的位置:
Linux启动时,initrd可以在内存中,也可以在 Flash或其它可用的设备上(软盘?对ARM显得不适用了哈 );
2. initrd文件格式:
romfs/Minix/ext2/gzip
相关的函数: drivers/block/rd.c: identify_ramdisk_image
3. 加载位置和条件
init/main.c: prepare_namespace
从这里可以看出,需要的参数为:initrd_start 和 initrd_end。
4. ARM如何传递initrd参数
核心可以选择是否从外部(bootLoader)获取参数。
从外部获取的情况:
arch/arm/kernel/setup.c: 从 TAG参数中获取(tags简单来说内存中一段具有一定格式的标签数据和参数,核心和Loader所共知的一种格式,由loader来构造,由核心来读取);通过Loader或核心配置的命令行参数中应包含 root=/dev/ram的参数;
不从外部获取的情况:
可以在 fix_up 中来设置,就像上面代码中提到的一样:
[引用]
aster2_fixup(struct machine_desc *desc, struct param_struct *unused,
char **cmdline, struct meminfo *mi)
{
ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
setup_ramdisk(1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE);
setup_initrd(0x04200000, 4 * 1024 * 1024);
}
[/引用]
这段代码的效果有几个:
(1)第一行:设置根文件系统为 ramdisk(相当于root=/dev/ram0,这种情况下核心命令行参数可以不需要这一行)
(2) 第二行:加载ramdisk;
(3) 第三行:通过setup_initrd设置initrd的参数,即(虚拟的)起始和结束地址;
5. Loader 如何传递参数给核心?
上面提到的代码中还有一行:
[引用]
BOOT_PARAMS(0x04000100)
[/引用]
这是一个很重要的地址,核心将从这个地址开始分析 tag参数,在上一次另一篇的回复中简单提到过一下,再说明一下,这些标记可以传递的参数包括:物理内存信息(ATAG_MEM)、ramdisk信息(ATAG_RAMDISK已经不再使用),initrd信息(ATAG_INITRD2),序列号(ATAG_SERIAL),版本号(ATAG_REVISION),命令行参数(ATAG_CMDLINE)等。Loader可以部份或全部设定这些标记。(参见:arch/arm/kernel/setup.c)这里,必要的参数为内存信息。Loader的有效标签中应至少包括这项。
很明显,Loader知道物理内存的信息(地址/长度),那么如何传其它的参数呢?
刚下了u-boot,很早以前用过了,现在好像改进比较大,上面提到的tag差不多都支持上了,并且可以通过宏来控制部份支持。(lib_arm/armlinux.c)
从代码可以看出,传递 initrd 参数的条件是, image文件中包含 initrd文件,即通过 mkimage生成一个核心与initrd混合的image文件,然后用bootm,这个参数就有可能传给核心。
然后,再说这里强调的可能。如果核心代码中定义的参数地址BOOT_PARAMS(0x04000100)与u-boot中的参数地址不一致,显然可能性不成立。如我下的 u-boot 版本中,smdk2410生成的参数地址为:0x30000100(我找到的一个2.4.18-rmk7版本核心中2410的参数地址也是这个,而不是nucleus代码中的那个0x04000100哦
如果上面条件成立,但在 fix_up中用了一个不同的参数来设置 initrd,那么即使loader传了参数,也被核心给忽略了。
====
上面问题中,如果要能加载 initrd 到 ramdisk中(这句顺便点一下initrd 和 ramdisk的关系 ) ,那么 Loader应该将 initrd加载到 (虚)0x04200000位置;或者去掉 fix_up中的内容(我看原来代码中这几行都是注释掉了的),让Loader自已传参数给核心。 |
|