现在的位置: 首页 > 综合 > 正文

RamDisk与Initrd

2014年10月11日 ⁄ 综合 ⁄ 共 4339字 ⁄ 字号 评论关闭

转载:http://wenku.baidu.com/view/391882c508a1284ac85043d4.html

1、什么是initrd以及为什么要用initrd

 

在早期的Linux系统中,一般就只有软盘或者硬盘被用来作为Linux的根文件系统,因此很容易把这些设备的驱动程序集成到内核中。但是现在根文件系统可能保存在各种存储设备上,包括SCSI,
SATA, U
盘等等,种类太多,这些多种多样的存储设备的驱动程序加起来就很大了,因此把这些设备驱动程序全部编译到内核中显得不太方便。我们看到利用udevd可以实现实现内核模块的自动加载,因此我们希望根文件系统的设备驱动程序也能够实现自动加载。但是这里有一个矛盾,udevd是一个可执行文件,在根文件系统被挂载前,是不可能执行udevd的,但是如果udevd没有启动,那就无法自动加载根文件系统设备的驱动程序,同时也无法在/dev目录下建立相应的设备节点。为了解决这个矛盾,于是出现了initrd(bootloader
initialized RAM disk)
initrd是一个被压缩过的小型根目录,这个目录中包含了启动阶段中必须的驱动模块(注意这里是模块--module)可执行文件和启动脚本,以及包括上面提到的udevd当系统启动的时候,booloader会把initrd文件读到内存中,然后把initrd的起始地址告诉内核。内核在运行过程中会解压initrd,然后把 initrd挂载为根目录,然后执行根目录中的/initrc脚本,您可以在这个脚本中运行initrd中的udevd,让它来自动加载设备驱动程序以及在/dev目录下建立必要的设备节点。udevd自动加载磁盘驱动程序之后,就可以mount真正的根目录,并切换到这个根目录中。

启动时用到initrd来mount根文件系统。其实ramdisk只是在ram上实现的块设备,initrd可以说是启动过程中用到的一种机制。

 

2Ramdiskinitrd区别

ramdisk 一种基于内存的虚拟文件系统,就好像你又有一个硬盘,你可以对它上面的文件添加修改删除等等操作。但是一掉电,就什么也没有了。无法保存。
initrd 是
boot loader initialized RAM disk,顾名思义,是在系统初始化引导时候用的ramdisk也就是由启动加载器(bootloader)所初始化的RamDisk设备,它的作用是完善内核的模块机制,让内核的初始化流程更具弹性;内核以及initrd,都由
bootloader在系统启动后被加载至内存的指定位置,主要功能为按需加载模块以及按需改变根文件系统。


3、Linux启动一定要用initrd么?

    如果把需要的功能全都编译到内核中(非模块方式),只需要一个内核文件即可。initrd能够减小启动内核的体积并增加灵活性,如果你的内核以模块方式支持某种文件系统(例如ext3, UFS),而启动阶段存储该文件系统的设备驱动模块放在该文件系统上,内核是无法读取文件系统的,从而只能通过initrd的虚拟文件系统来装载这些模块。这里有些人会问: 既然内核此时不能读取文件系统,那内核的文件是怎么装入内存中的呢? 答案很简单,Grub是file-system sensitive的,能够识别常见的文件系统。(即bootloader是可以识别文件系统的)

4、制作initrd

1Linux2.4内核对 Initrd 的处理流程

为了使读者清晰的了解Linux2.6内核initrd机制的变化,在重点介绍Linux2.6内核initrd之前,先对linux2.4内核的 initrd进行一个简单的介绍。Linux2.4内核的initrd的格式是文件系统镜像文件,本文将其称为image-initrd,以区别后面介绍linux2.6内核的cpio格式的initrd linux2.4内核对initrd的处理流程如下:

1. bootloader把内核以及/dev/initrd的内容加载到内存,/dev/initrd是由bootloader初始化的设备,存储着initrd

2. 在内核初始化过程中,内核把/dev/initrd 设备的内容解压缩并拷贝到/dev/ram0 设备上。

3. 内核以可读写的方式把 /dev/ram0 设备挂载为原始的根文件系统。

4. 如果 /dev/ram0 被指定为真正的根文件系统,那么内核跳至最后一步正常启动。

5. 执行 initrd 上的 /linuxrc 文件,linuxrc 通常是一个脚本文件,负责加载内核访问根文件系统必须的驱动,以及加载根文件系统。

6. /linuxrc 执行完毕,真正的根文件系统被挂载。

7. 如果真正的根文件系统存在/initrd 目录,那么 /dev/ram0 将从 / 移动到 /initrd。否则如果 /initrd 目录不存在, /dev/ram0 将被卸载。

8. 在真正的根文件系统上进行正常启动过程,执行 /sbin/init linux2.4 内核的 initrd 的执行是作为内核启动的一个中间阶段,也就是说 initrd  /linuxrc 执行以后,内核会继续执行初始化代码,我们后面会看到这是 linux2.4 内核同 2.6 内核的 initrd 处理流程的一个显著区别。

2Linux2.6 内核对 Initrd 的处理流程

linux2.6 内核支持两种格式的 initrd,一种是前面第 3 部分介绍的 linux2.4 内核那种传统格式的文件系统镜像-image-initrd,它的制作方法同 Linux2.4 内核的 initrd 一样,其核心文件就是 /linuxrc。另外一种格式的 initrd  cpio 格式的,这种格式的initrd从linux
2.5
 起开始引入,使用 cpio 工具生成,其核心文件不再是/linuxrc,而是 /init,本文将这种 initrd 称为 cpio-initrd。尽管 linux2.6 内核对 cpio-initrd image-initrd 这两种格式的 initrd 均支持,但对其处理流程有着显著的区别,下面分别介绍 linux2.6 内核对这两种 initrd 的处理流程。

cpio-initrd 的处理流程

1 boot loader 把内核以及 initrd 文件加载到内存的特定位置。

2内核判断initrd的文件格式,如果是cpio格式。

3initrd的内容释放到rootfs中。(解压)

4执行initrd中的/init文件,执行到这一点,内核的工作全部结束,完全交给/init文件处理。

image-initrd的处理流程

1 boot loader把内核以及initrd文件加载到内存的特定位置。

2内核判断initrd的文件格式,如果不是cpio格式,将其作为image-initrd处理。

3内核将initrd的内容保存在rootfs下的/initrd.image文件中。

4内核将/initrd.image的内容读入/dev/ram0设备中,也就是读入了一个内存盘中。

5接着内核以可读写的方式把/dev/ram0设备挂载为原始的根文件系统。

6 .如果/dev/ram0被指定为真正的根文件系统,那么内核跳至最后一步正常启动。

7执行initrd上的/linuxrc文件,linuxrc通常是一个脚本文件,负责加载内核访问根文件系统必须的驱动,以及加载根文件系统。

8 /linuxrc执行完毕,常规根文件系统被挂载

9如果常规根文件系统存在/initrd目录,那么/dev/ram0将从/移动到/initrd。否则如果/initrd目录不存在, /dev/ram0将被卸载。

10在常规根文件系统上进行正常启动过程,执行/sbin/init

通过上面的流程介绍可知,Linux2.6内核对image-initrd的处理流程同linux2.4内核相比并没有显著的变化, cpio-initrd的处理流程相比于image-initrd的处理流程却有很大的区别,流程非常简单,在后面的源代码分析中,读者更能体会到处理的简捷。

4cpio-initrdimage-initrd的区别与优势

没有找到正式的关于cpio-initrdimage-initrd对比的文献,根据笔者的使用体验以及内核代码的分析,总结出如下三方面的区别,这些区别也正是cpio-initrd的优势所在:

cpio-initrd的制作方法更加简单

cpio-initrd的制作非常简单,通过两个命令就可以完成整个制作过程

    

#假设当前目录位于准备好的initrd文件系统的根目录下
 bash# find . | cpio -c -o > ../initrd.img
 bash# gzip ../initrd.img

 

 

 

具体过程:busybox中添加配置文件并生成initrd镜像

 

这时,我们处在/root/busybox-1.16.0/_install 目录下。

# mkdir proc sys etc dev (创建四个空目录,linux内核需要)

# cd dev

# mknod console c 5 1 (创建一个控制台字符设备文件)

# mknod null c 1 3 (创建一个0设备文件)

# cd ..

# cd etc

# vim fstab (输入如下图内容)


# mkdir init.d

# vim init.d/rcS (输入如下内容)

# chmod +x init.d/rcS (rcS文件加上可执行权限)

# vim inittab (输入如下内容)


 

# cd ..

# pwd (打印当前目录)

/root/busybox-1.16.0/_install

此时表明我们处在busybox安装文件的根目录下

# rm linuxrc (删除linuxrc链接文件)

然后新创建一个指向busybox文件的链接文件,如下图所示:



我们输入如下图所示命令来创建initrd镜像.



# cd ..

# cp initrd.gz /boot

 

而传统initrd的制作过程比较繁琐,需要如下六个步骤

    

#假设当前目录位于准备好的initrd文件系统的根目录下
 bash# dd if=/dev/zero of=../initrd.img bs=512k count=5
 bash# mkfs.ext2 -F -m0 ../initrd.img
 bash# mount -t ext2 -o loop ../initrd.img   /mnt
 bash# cp -r   * /mnt
 bash# umount /mnt
 bash# gzip -9 ../initrd.img

抱歉!评论已关闭.