`

initrd的作用

 
阅读更多

initrd 是一个 ram disk 的 image. 一般是压缩过的.它存在的主要目的是在内核启动时加载它,安装其中的驱动.
总的来说分这几步
a.内核启动时加载 initrd img, mount 为 / 
b.依 /linuxrc 的指令执行, 一般有扫描系统硬件,从 当前文件系统中找到驱动安装之.
c.挂载系统中真正的 /

细说就是:
开机 bios 代电自检, 依 bios 指定的启动盘(如 hd1), 找到 头 416 字节引导程序,执行之(顺便说如果是lilo引导linux的话, 在#lilo 时就写入了这416字节,但仅这416字节是不够用来引导 linux 的,因此叫它 stage1 还有一个 stage2 就是我们看到的选系统的 lilo 菜单部分), 然后出现 选系统的菜单 选了 linux 后, lilo 依 liloconf 中指定的位置找到 内核 启动之,之后 initrd 内亮登场:
1.内核依 指定的 initrd 文件加载它, 解压之到 /etc/ram0 [内存] 中(一般initrd 采用 bz bz2 算法,内核是知道如何处理的)
2. mount ram0 作为 / 文件系统(可能是内核支持的ext2),这样做的目的是为了读取 initrd 中的内容.
3.initrd 文件系统一般有一个 /linuxrc 的文件,一般是一个 sh 脚本, kernel 执行之
--- 以下的步骤可能是脚本中指令,这个我没有仔细再研究过
4. 扫描系统,发现新硬件,在 initrd 文件系统中找到相应驱动安装之.
5. 加载真正的 / 文件系统, 而将原有的 / 系统 (initrd 解压后对应的) 如下处理:
a.如果真正的 / 文件系统下有 /initrd 这个目录,则由原来的/ mount 到此处
b.没有则umount 掉(此时如果有进程还在用initrd 中的文件,会报错)
6.找到 /etc/init 执行之,依 /etc/inittab 初始化系统 
到此initrd 使令结束

initrd 是编译内核时可选的功能,但为什么还要搞出一个 initrd 来,把所有驱动编译进内核不就行了?
我考虑是这样的,如何是发行版的内核,它要适应不同的硬件,如果把所有硬件驱动编译到内核是不现实的,因此只有一个适当大小的内核[只有适当的一些驱动如 ext2等], 它在启动时会得用 initrd 来实现对内核未支持的驱动的加载.这样,一个内核+不同的intird 可以适当大量的硬件

比如,你的 / 文件系统是 ext3 的,但内核未必支持 ext3 ,这样就可能通过 initrd 的方式加载了 ext3
的驱动,然后再mount 你的 / 就OK了. 设想如果此时没有 initrd (内核又不支持ext3),一定遇到
kernel panic.

inintrd 单独拿出来压缩成一个文件和内核放一起,而不是 你真正 / 文件系统中的一个 目录,可能是由于 前者结构上更紧凑和不容易被用户更改,何况遇到 需要在 initrd 中加载文件系统驱动时,后者是无能为力的.(而 initrd 一般采用 ext2 ,kernel 是支持的)

------------------------------------------

initrd能做的事情很多,initrd就是一个微型的linux系统,就象前面说的,它可以解决驱动的问题,经过了grub引导内核,再未执行init进程前就开始读取initrd
所以可以在initrd中加载系统所需要的特殊驱动。以供init继续引导系统
另外在liveCD中也是非常重要的,负责检查出将光盘挂载哪里,进行压缩文件系统的解压初始化,加载特殊模块,然后通过pivot_root chroot 将系统挂载到正常的根分区,开始init引导。
一般自己编译后的内核是不需要initrd的,但是发行版则可能需要它。
可以通过下面的命令挂载上你的initrd,其中linuxrc就是initrd的启动文件
看看它都有什么内容就知道你的initrd都做了什么。
cat initrd.img | gunzip > /tmp/myinitrdfs
mkdir /mnt/tmp
mount -o loop -t ext2 /tmp/myinitrdfs /mnt/tmp

Mandrakelinux 10.1O的initrd.img中的linuxrc:
#!/bin/nash

echo "Loading jbd.ko module"
insmod /lib/jbd.ko
echo "Loading ext3.ko module"
insmod /lib/ext3.ko
echo Mounting /proc filesystem
mount -t proc /proc /proc
echo Mounting sysfs
mount -t sysfs none /sys
echo Creating device files
mountdev size=1M,mode=0755
echo starting udev
udevstart
echo -n /sbin/hotplug > /proc/sys/kernel/hotplug
echo Creating root device
mkrootdev /dev/root
echo Mounting root filesystem
mount -o defaults --ro -t ext3 /dev/root /sysroot
echo 0x0100 > /proc/sys/kernel/real-root-dev
pivot_root /sysroot /sysroot/initrd
umount /initrd/sys
umount /initrd/proc
echo Initrd finished
可见插入了两个模块
echo "Loading jbd.ko module"
insmod /lib/jbd.ko
echo "Loading ext3.ko module"
insmod /lib/ext3.ko
如果正在使用ext3文件系统,没有这个initrd,就无法正常引导根系统了。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics