以前一直没有研究过initrd部分,只是知道linux内核启动后会首先由引导装载器读取initrd映像来启动ramdisk.它的作用是鸡和蛋问题的解决方案,即首先安装一个内存盘作为临时的root,然后加载其上的磁盘/网络磁盘驱动程序,从而找到真正的硬盘设备/网络文件系统,再挂载它为真正的root,从而进入整个linux world。但这里面到底干了些什么,以及怎么实现的没有仔细研究,也认为比较简单,直到有一天,第一次升级我的home box,linux2.4内核到linux2.6内核,在启动过程中kernel panic -- 傻眼了。当时由于工作的缘故没有深究下去,但那时第一次遇到这个问题。最有由于自己想搭建一个linux平台,迫不得已只好开始仔细研究这个东西了。当然最后收获还是颇丰,把过程简单记录一下,希望对其它人有帮助。
我一直使用redhat的系统,包括最近的FC。所以我主要以RH/FC的启动过程为例进行说明。其他系统略有不同,但基本原理是一样的。
initrd放在RH/FC系统的/boot目录中,在grub,conf中指定。如:
initrd放在RH/FC系统的/boot目录中,在grub,conf中指定。如:
initrd /initrd-2.6.23.1-42.fc8.img注意这里的/是指grub的root,那是grub的root命令所指磁盘的boot目录下。
这个映像文件在2.6.1.x内核以前的版本中是一个被压缩的loop设备文件,但在2.6.1.x以后的内核支持它可以是一个被压缩的cpio包了。如果是cpio包可以:
mkdir initrd && mv /boot/initrd-2.6.23.1-42.fc8.img initrd && cd initrd
gunzip -c < initrd-2.6.23.1-42.fc8.img | cpio -imd #注意它将ramdisk内容解压到inird当前目录bin sbin如果是loop设备,必须通过mount命令加载它才能访问:
mkdir /mnt/initrd
gunzip -c < initrd-2.6.23.1-42.fc8.img > initrd.loop
mount -o loop,rw initrd.loop /mnt/initrd
在initrd目录中就是系统启动时临时root的内容。目录下有一个init文件,该文件最为重要,它就是内核启动后执行的第一个脚本。实际上内核启动后寻找的就是/init ; /sbin/init ;/bin/init,找到任何一个就执行它。整个的初始化从它开始。它的内容如下(FC8):
#!/bin/nash
mount -t proc /proc /proc
setquiet
echo Mounting proc filesystem
ec