Initramfs应用问题记录

因为想把升级应用和内核做到一个Image中,所以打算采用Initramfs。

先准备root文件系统,比如到/home/qianjiang/tmp/initramfs目录下。

通过kernel menuconfig打开CONFIG_BLK_DEV_INITRD,
并且设置CONFIG_INITRAMFS_SOURCE="/home/qianjiang/tmp/initramfs/",

通过调试理解如下:
内核编译时,通过CONFIG_INITRAMFS_SOURCE指定的目录生成cpio文件(所以也可以直接指定cpio文件而不是指定目录)。
内核在初始化启动的时候会先注册一个rootfs的文件系统,然后通过rootfs_initcall来生成其中的内容。
A. 当CONFIG_BLK_DEV_INITRD未选中时,rootfs_initcall调用noinitramfs.c中的default_rootfs()来生成。
B. 如果选中时:
rootfs_initcall调用initramfs.c中的populate_rootfs()函数来填充。
static int __init populate_rootfs(void)
{
        char *err = unpack_to_rootfs(__initramfs_start, __initramfs_end - __initramfs_start, 0);
         if (initrd_start) {  
                  err = unpack_to_rootfs((char *)initrd_start, initrd_end ...
                  fd = sys_open("/initrd.p_w_picpath", O_WRONLY|O_CREAT, 0700);
                  if (fd >= 0) {
                           sys_write(fd, (char *)initrd_start, initrd_end - initrd_start);
                  }
         }
         ......
}

[__initramfs_start,__initramfs_end]指定了一个cpio包的位置,
A.1 如果设置了CONFIG_INITRAMFS_SOURCE,即我们目录对应的cpio数据包。
B.1 如果未设置,对应一个默认的cpio数据包,由内核编译时生成,和default_rootfs()生成的内容类似。

没有设置的情况,需要通过比如cmdline指定[initrd_start, initrd_end],该数据段被写入文件,/initrd.p_w_picpath(见上面的函数)。

接下来调用prepare_namespace(),调用initrd_load(),然后rd_load_p_w_picpath()对initrd.p_w_picpath进行解压(可以是gz, cramfs等)。


然后mount_root()把设备挂载到/root下面。


注意:系统在启动的时候,完成了cpio到rootfs的填充后,会检查是否存在/init,如果该文件不存在,则调用prepare_namespace()来挂载文件系统。

上述内容参考了:
http://liaowb1234.blog.163.com/blog/static/771555472010025114231594/
另外一个好的链接参考http://en.gentoo-wiki.com/wiki/Initramfs
确实写得很详细。


在/init脚本的书写时出了些问题
. Kernel panic - not syncing: Attempted to kill init!
/init 脚本写得有问题
---------------------------
#!/bin/busybox sh
/bin/echo hello
---------------------------
改成如下:
---------------------------
#!/bin/busybox
---------------------------
竟然好了,而且直接进入shell。
查看/proc/1/cmdline
发现是/bin/busybox init

?还有些疑惑