linux 2.6内核initrd.img文件分析

linux 2.6内核initrd.img文件分析

如果对系统进行驱动的升级或添加新硬件,此时,常会用到mkinitrd命令。而该命令其实是一个脚本,通过一系列的流程来生成系统启动需要的initrd.img文件。通过分析该文件,我们可以更清楚的知道系统启动时候加载驱动的顺序,以及修正或加入一些自定义的配置。

一、什么是initrd

initrd 的英文含义是 boot loader initialized RAM disk,就是由 boot loader 初始化的内存盘。initrd的最初的目的是为了把kernel的启动分成两个阶段:在kernel中保留最少最基本的启动代码,然后把对各种各样硬件设备的支持以模块的方式放在initrd中,这样就在启动过程中可以从initrd中mount根文件系统中需要装载的模块。这样的一个好处就是在保持kernel不变的情况下,通过修改initrd中的内容就可以灵活的支持不同的硬件。在启动完成的最后阶段,根文件系统可以重新mount到其他设备上。

二、是否必须

initrd.img是Linux启动过程中很重要的一个文件,如果你编译内核时将一部分功能编译为可加载模块。如果系统的一些设备的驱动编译为可加载 模,那么启动时如果没有指定INITRD=/path_to_initrd.img,那么系统启动或者会失败,或者启动后会有设备无法使用(像网卡或者其 它设备)。如果没指定initrd.img或者指定的initrd.img中并没有包含正确的驱动模块,则系统启动时会挂起,并报告"kernel panic: VFS: Unable to mount root fs on 08:06"的错误。
initrd文件不是必须的,当需要具有适应在不同的硬件环境下使用的要求,那使用initrd会更方便。我们常在编译核心的使用,使用make menuconfig,其中对某些而外的驱动,是可以选择以模块编译,还是<*>直接编译到核心里面。例如ext3文件系统驱动,如果核心需要放在该文件系统上,可以有两个方法:
引用
1、把其全都编译到内核中,则只需要一个内核文件系统即可启动;
2、把其编译为模块,然后通过initrd虚拟的内存系统加载;

也就是说由于initrd会在内存虚拟一个文件系统,然后可以根据不同的硬件加载不同的驱动,而不需要重新编译整个核心。所以,大部分的发行版都会通过这种方式对驱动进行加载。

三、版本

根据核心版本的不同,initrd文件有两种格式:image和cpio。2.4核心只使用image格式,而2.6核心可同时支持两种格式。它们不单格式不一样,而且运作的机制和流程也完全不同,甚至制作方法也不一样。

四、2.6核心用initrd

1、格式
2.6核心可以支持image格式,但更多的时候使用的是cpio格式。其核心文件不再是/linuxrc,而是/init。
2、解压
以红旗6.0使用的核心版本为例:
[root@localhost test]# ls initrd-2.6.9-11.19AX.img [root@localhost test]# file initrd-2.6.9-11.19AX.img initrd-2.6.9-11.19AX.img: gzip compressed data, from Unix, max compression可以这样来识别格式:
[root@localhost test]# gzip -dc initrd-2.6.9-11.19AX.img > new.img [root@localhost test]# file new.img new.img: ASCII cpio archive (SVR4 with no CRC)创建一个新目录,然后解压出来:
[root@localhost test]# mkdir new
[root@localhost test]# cd new/ [root@localhost new]# gzip -dc ../initrd-2.6.9-11.19AX.img | cpio -idvm也可以这样运行命令:
[root@localhost new]# zcat ../initrd-2.6.9-11.19AX.img |cpio -idvm内容:
[root@localhost new]# ll -R .: total 36 drwxr-xr-x 2 root root 4096 Sep 30 16:55 bin drwxr-xr-x 2 root root 4096 Sep 30 16:55 dev drwxr-xr-x 3 root root 4096 Sep 30 16:55 etc -rwxr-xr-x 1 root root 725 Jun 29 17:35 init <== 一个nash脚本 drwxr-xr-x 2 root root 4096 Sep 30 16:55 lib drwxr-xr-x 2 root root 4096 Jun 29 17:35 loopfs drwxr-xr-x 2 root root 4096 Jun 29 17:35 proc lrwxrwxrwx 1 root root 3 Sep 30 16:54 sbin -> bin drwxr-xr-x 2 root root 4096 Jun 29 17:35 sys drwxr-xr-x 2 root root 4096 Jun 29 17:35 sysroot ./bin: total 592 lrwxrwxrwx 1 root root 10 Sep 30 16:55 hotplug -> /sbin/nash -rwxr-xr-x 1 root root 12904 Jun 29 17:35 insmod <== 插入模块 lrwxrwxrwx 1 root root 10 Sep 30 16:55 modprobe -> /sbin/nash -rwxr-xr-x 1 root root 38184 Jun 29 17:35 nash <== 一个小型解释器 -rwxr-xr-x 1 root root 541716 Jun 29 17:35 udev lrwxrwxrwx 1 root root 4 Sep 30 16:54 udevstart -> udev ./dev: <== 一些必要的设备文件 total 0 crw-r--r-- 1 root root 5, 1 Jun 29 17:35 console crw-r--r-- 1 root root 1, 3 Jun 29 17:35 null brw-r--r-- 1 root root 1, 1 Jun 29 17:35 ram crw-r--r-- 1 root root 4, 0 Jun 29 17:35 systty crw-r--r-- 1 root root 4, 1 Jun 29 17:35 tty1 crw-r--r-- 1 root root 4, 2 Jun 29 17:35 tty2 crw-r--r-- 1 root root 4, 3 Jun 29 17:35 tty3 crw-r--r-- 1 root root 4, 4 Jun 29 17:35 tty4 ./etc: total 4 drwxr-xr-x 2 root root 4096 Sep 30 16:55 udev ./etc/udev: <== udev配置文件 total 4 -rw-r--r-- 1 root root 1128 Jun 29 17:35 udev.conf ./lib: <== 启动时加载的模块 total 236 -rwxr--r-- 1 root root 139452 Aug 5 2005 ext3.ko -rwxr--r-- 1 root root 89648 Aug 5 2005 jbd.ko ./loopfs: total 0 ./proc: total 0 ./sys: total 0 ./sysroot: total 0

3、执行脚本

[root@localhost new]# cat init #!/bin/nash mount -t proc /proc /proc setquiet echo Mounted /proc filesystem echo Mounting sysfs mount -t sysfs none /sys echo Creating /dev mount -o mode=0755 -t tmpfs none /dev mknod /dev/console c 5 1 mknod /dev/null c 1 3 mknod /dev/zero c 1 5 mkdir /dev/pts mkdir /dev/shm echo Starting udev /sbin/udevstart echo -n "/sbin/hotplug" > /proc/sys/kernel/hotplug echo "Loading jbd.ko module" insmod /lib/jbd.ko echo "Loading ext3.ko module" insmod /lib/ext3.ko /sbin/udevstart echo Creating root device mkrootdev /dev/root umount /sys echo Mounting root filesystem mount -o defaults --ro -t ext3 /dev/root /sysroot mount -t tmpfs --bind /dev /sysroot/dev echo Switching to new root switchroot /sysroot umount /initrd/dev
4、执行流程
1)boot loader 把内核以及 initrd 文件加载到内存的特定位置。
2)内核判断initrd的文件格式,如果是cpio格式。
3)将initrd的内容释放到rootfs中。
4)执行initrd中的/init文件,执行到这一点,内核的工作全部结束,完全交给/init文件处理。

正式由于cpio格式带来的便利,我们要修改和增加自定义的脚本和驱动都变得简单很多,一般只需要对init脚本和/lib添加即可。
5、生成新initrd文件
[root@localhost new]# find ./ | cpio -c -o > ../initrd-2.6.9-11.19AX.new.img 1617 blocks [root@localhost new]# cd .. [root@localhost test]# gzip -9 initrd-2.6.9-11.19AX.new.img [root@localhost test]# mv initrd-2.6.9-11.19AX.new.img.gz initrd-2.6.9-11.19AX.new.img [root@localhost test]# cp initrd-2.6.9-11.19AX.new.img /boot/最后,修改grub即可。若在2.6核心上使用image的initrd文件,处理的流程只是在开始会增加一个判断的步骤,后续是和在2.4上执行的过程是一样的。
五、对比

可以看到,使用cpio格式的处理是非常方便和简洁的。但就是因为制作cpio,以及启动对cpio的处理更直接,目前新发行版的initrd都 以cpio格式为多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值