首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ARM中ramdisk的使用

ARM中ramdisk的使用

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自已传参数给核心。
继承事业,薪火相传
返回列表