分享

initrd加载过程备忘_GO AHEAD,DUANIUS!

 黄浦江中的一条鱼 2009-07-20

最近研究lkml上的fastboot patch,再次意识到自己对initrd一直很迷茫 ,就大概花了天时间看了看这方面的文档和代码,备忘总结下。

不想长篇大论 ,简单的说,主要有4种情况。1。无initrd 2。cpio initrd,于内核编在一起。 3。cpio initrd于内核分开编 4。 ramdisk initrd。

1。对于无initrd的情况,会先在initcall中调用default_rootfs(),随后在prepare_namespace()中调用 mount_root挂载真实的文件系统 ,最后在init_post()中通过kernel_execve执行根文件系统中的 /sbin/init。

2。对于后面3种,会调用initcall中的populate_rootfs() 函数来填充 rootfs。对于2,3的情况,是把initrd来填充rootfs,只不过,对2而言,原来的initrd和内核编在一起,在.init.ramfs段中,其中全局变量__initramfs_start和__initramfs_end分别指向这个数据段的起始地址和结束地址。如果.init.ramfs数据段大小不为0(initramfs_end - initramfs_start != 0),就说明这是initrd集成在内核数据段中。并且是cpio的initrd。而对于3,initrd是由bootloader加载到内存中的,这时 bootloader会把起始地址和结束地址传递给内核,内核中的全局initrd_start和initrd_end分别指向initrd的起始地址和 结束地址。对于4,则把 initrd 保存到 rootfs 的 /initrd.image 这个文件里。在后面,4会在prepare_namespace先挂载这个initrd,然后执行里面的linuxrc,然后再挂载真实的文件系统。后面 的步骤2,3会在init_post()中调用/init,一般的发行版本的Linux中,initrd中的/init脚本会启动udevd,加载必要的 设备驱动程序,然后挂载真正的根文件系统,最后再执行真正的根文件系统上的initrd,这样就这个启动过程就顺利的交接了。而对于4,则会调用根文件系 统上的/sbin/init(同1)。

所有的函数都在kernel_init中,从do_basic_setup()中的do_init_calls()到 prepare_namespace()(只有1,4要执行此函数)最后到init_post()。(有关临时根目录的挂载并未在本文中包含,请参阅参考 文献)总的来说,为了提高启动速度,应该尽量避免使用initrd,而如果非要使用initrd,则应该使用cpio initrd,因为ramdisk initrd不仅使用不方便,而且在内核中的处理过程也更加复杂,不推荐使用。

参考文献:
1 Linux内核Ramdisk(initrd)机制
http://www./modules/article/view.article.php?9/c2#heading2
2 initrd 流程分析
http://hi.baidu.com/mczyh/blog/item/86153139527ed422b8998f17.html
3 解析linux根文件系统的挂载过程
http://bbs./viewthread.php?tid=306225

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多