1、什么是initrd




  • initrd 的英文含义是 boot loader initialized RAM disk,即由引导程序初始化的RAM磁盘。initrd是在实际根文件系统可用之前挂载到系统中的一个初始根文件系统。initrd与内核绑定在一起, 并作为内核引导过程的一部分进行加载。内核然后会将这个initrd文件作为其阶段引导过程的一部分来加载模块,这样才能在以后的引导过程中使用真正的文 件系统,并挂载实际的根文件系统。根文件系统可以存储在包括IDE、SCSI、USB在内的多种介质上,如果将这些设备的驱动都编译进内核,可以想象内核 会多么庞大、臃肿。所以可以把initrd看做是在启动过程中连接内核与根文件系统的一个桥梁。

其实initrd***.img是一个镜像文件,类似ramdisk,把一段程序打包到img里,然后在开机的时候在内存里开辟一段区域,一般是2m,释放到那里运行,都是一些初始化的程序,比如sisc_mod、 ext3、sd_mod等模块和insmod、nash等命令。不同内核,初始化的img可以相同,也可以不同,如果没有,可以在grub.conf里加 上no initrd

initrd 中包含了实现这个目标所需要的目录和可执行程序的最小集合,例如将内核模块加载到内核中所使用的 insmod工具。以及一些mount、mknod等命令,这些会在后面的nash部分讲到。Initrd 的用途主要有以下四种:*

1. linux 发行版的必备部件 linux 发行版必须适应各种不同的硬件架构,将所有的驱动编译进内核是不现实的,initrd 技术是解决该问题的关键技术。Linux 发行版在内核中只编译了基本的硬件驱动,在安装过程中通过检测系统硬件,生成包含安装系统硬件驱动的 initrd,无非是一种即可行又灵活的解决方案。

2. livecd 的必备部件 同 linux 发行版相比,livecd 可能会面对更加复杂的硬件环境,所以也必须使用 initrd。

3. 制作 Linux usb 启动盘必须使用 initrd usb 设备是启动比较慢的设备,从驱动加载到设备真正可用大概需要几秒钟时间。如果将 usb 驱动编译进内核,内核通常不能成功访问 usb 设备中的文件系统。因为在内核访问 usb 设备时, usb 设备通常没有初始化完毕。所以常规的做法是,在 initrd 中加载 usb 驱动,然后休眠几秒中,等待 usb设备初始化完毕后再挂载 usb 设备中的文件系统。

4. 嵌入式开发中常用做永久根文件系统。

5. 在 linuxrc 脚本中可以很方便地启用个性化 bootsplash。




2、剖析initrd




在linux2.4内核initrd的文件格式是文件系统镜像文件,即使用loop设备来构建的。loop设备是一个设备驱动程序,利用它可以将文件作为 一个块设备挂载到系统中,然后就可以查看这个文件系统中的内容了。到了linux2.6 内核的 initrd 的文件格式即支持原来的文件系统镜像文件,也支持 cpio 格式,而cpio就是用来取代原来的文件系统镜像文件格式。通过如下步骤可以查看到initrd文件里面的内容:

# mv initrd-2.6.18-8.2.img initrd-2.6.18-8.2.img.gz
# gunzip initrd-2.6.18-8.2.img.gz
# cpio -id < initrd-2.6.18-8.2.img
# ls -l
drwx------ 2 root root 4096 08-31 11:13 bin
drwx------ 3 root root 4096 08-31 11:13 dev
drwx------ 2 root root 4096 08-31 11:13 etc
-rwx------ 1 root root 1833 08-31 11:13 init
drwx------ 2 root root 4096 08-31 11:13 lib
drwx------ 2 root root 4096 08-31 11:13 proc
lrwxrwxrwx 1 root root    3 08-31 11:13 sbin -> bin
drwx------ 2 root root 4096 08-31 11:13 sys
drwx------ 2 root root 4096 08-31 11:13 sysroot

从上面的结果可以看出,initrd里面是一个很小的根文件系统,在 /bin 目录中有一组很少但却非常必要的应用程序,包括 nash、insmod等。init则是其引导的核心文件,在cpio格式的initrd里,该文件的名称只能是init。而在原来镜像文件格式的 initrd其核心文件可以是init和linuxrc。init通常是一个脚本文件,负责加载内核访问根文件系统必须的驱动,以及加载根文件系统。关于 nash的解释是,nash (not a shell)它不是一个SHELL,是一个设计的尽可能小的简单命令解释器。主要用于初始化RAM DISK时候解释里面的linuxrc或者init这些简单的脚本。nash目前常用的构建命令如下:



echo



将字符串输出到标准输出,只是功能上没有系统里面echo那么多。



find



显示指定路径下所匹配名称的文件,即只支持linux系统里find命令中的-name参数。



losetup



将文件帮定到回环设备/dev/loopdev上



mkdevices



指定创建的块设备文件存放路径,如:mkdevices /dev



mknod



创建设备文件



mkrootdev



创建根文件系统的设备节点,根据内核传递参数当中的“root=”来创建对应该设备的节点,节点的名称是/dev/root,它不仅能够根据root= /dev/xxx来生成对应的设备节点,还能够在碰到root=LABEL=/的情况下探测所有的硬盘分区,以便找到对应着卷标为/的分区。



pivot_root



转换根文件系统,以及挂载临时根文件系统。



raidautorun



自动检测所有的raid设备



showlabels



显示设备的LABEL以及UUID sw



itchroot



与pivot_root功能类似,用于转换根文件系统。但只能用于2.6或以后的核心。