发布于:
2010年05月09日
Linux 启动一般分成两个部分,比如Linux安装在第一个硬盘的第一个分区,在grub的命令行,我们可以采用下面的几行命令启动:
grub>kernel (hd0,0)/vmlinuz root=/dev/sda1 ro quiet splash
grub>initrd (hd0,0)/initrd.img
grub>boot
上面的命令,除了制定kernel位置和root位置以及一些kernel 的参数以外,还指定了initrd的位置。
很长一段时间,我并不知道initrd是用来干什么的,也几乎没有在中文资料里面看好很好的解释。就这样不求甚解的过了很久,才在近段时间在wikipedia上看到了比较详细的解释。花了点时间翻译了原理性的部分,如下:
Initinal ramdisk或者“initrd”是Linux 启动阶段被 Linux 内核调用一个临时文件系统。Initrd 和 initramfs 是实现的两种机制,虽然两者都是用于真正 “根(root)”文件系统被挂载之前的进行准备工作,但在载入临时文件系统到内存的实现上细微的区别。
基本原理
大部分Linux 发行版携带者一颗通用的内核映像(kernel image),用来启动尽可能多的硬件。而这颗通用内核映像(kernel image)的大部分硬件驱动一般被编译为可加载模块(module),因为如果全部静态编译的话,内核(kernel)会变得巨大无比,不仅软盘启动无法实现,一般小内存的电脑无法承受这么大的内存占用。
这样,在mount 根(root)文件系统前,探测和加载必要的驱动模块(module)成了大问题。或者说,判断哪个是根(root)文件系统变得困难。(译者注:在识别跟文件系统之前,必须先识别硬件设备,而识别硬件设备–如硬盘–的驱动代码可能是存在根(root)文件系统内的可加载模块(module)。)
而更复杂的问题是,根(root)文件系统可能是软RAID卷,LVM,,NFS(无盘工作站),或者一个加密分区。这些情况下,在mount之前需要更多的特殊的驱动加载。
另外一个复杂情况是让内核支持系统休眠(hibernation),休眠会让系统挂起(suspend),将整个内存内容dump成一个映像(image)到swap分区或者常规文件存储,然后关机。下次启动的时候,这个映像(image)必须可读才能加载到内存。
为了防止内核(kernel)不得不硬编码处理这么多特殊情况,使用了一种在初始化启动阶段使用临时根(root)文件系统(也称早期用户空间)。这种临时根(root)文件系统可包含硬件探测,模块加载,设备识别直到mount到真正的根(root)文件系统。
实际使用
initrd映像(image)文件必须和内核映像(image)一起被存放于Linux 引导程序(bootloader)或者启动固件(boot firmware)可读的地方,比如:
- 系统的根(root)文件系统
- 启动光盘
- 本地启动分区,可以是ext2或者FAT等格式化的小分区
- TFTP服务器,使系统可以通过以太网启动
引导程序会加载内核(kernel)和initrd映像(image)文件到内存,然后启动内核(kernel),传递initrd映像(image)内存地址给内核(kernel)。在启动程序的最后阶段,内核(kernel)会通过读取initrd映像(image)的首部分数据尝试判断它的格式:
- 在initrd机制里面,initrd映像(image)是一个文件系统映像(可以是压缩的),这样就可以以特殊的块设备(block device) mount(/dev/ram)。但文件系统驱动必须被静态编译到内核。 很多Linux发行版使用压缩的ext2格式作为initrd映像(image)的格式。另外一些(包括Debian 3.1)使用cramfs, 因为cramfs映像(image)可以被直接mount 而无需额外的解压缩空间,让内存有限的系统更容易启动。一旦临时文件系统启动,内核(kernel)会执行/linuxrc 作为第一个进程。当这个进程退出,内核(kernel)会认为真正的根(root)文件系统已经被mount,然后执行”/sbin/init”来开始正常的用户空间进程。
- 在initramfs机制里面(Linux 2.6.13以后版本可用),initrd映像(image)是一个cpio包(可以是压缩的)。在启动过程中,cpio包被内核解包为一个tmpfs的特殊实力,成为一个临时根文件系统。initramfs机制的优点是不需要一个必须被静态编译到内核(kernel)的中间文件系统格式或者块设备(block device)。 在initramfs机制里,内核(kernel)执行/init 作为第一个进程,这个进程开始之后并不退出。
依赖静态编译在内核(kernel)的压缩算法不同,initrd/initramfs映像(image)的压缩格式可以是gzip,bzip2和LZMA.