linux下的initrd镜像文件初探

来源:互联网 发布:软件正版化管理制度 编辑:程序博客网 时间:2024/06/16 00:21

我们在安装新内核的时候,通常都会编辑lilo.conf 和grub.conf
文件。里面有一段“initrd=/boot/initrd-***.img”(其中的***表示内核的版本号)的我们都很少会注意到,有时候还会发现这
一行不要也可以正常开机。那这个initrd***.img究竟是用来干什么的呢?
其实initrd***.img是一个镜像文件,类似ramdisk,把一段程序打包到img里,然后在开机的时候在内存里开辟一段区域,一般是
2m,释
放到那里运行,都是一些初始化的程序,比如sisc_mod、ext3、sd_mod等模块和insmod、nash等命令。不同内核,初始化的img可
以相同,也可以不同,如果没有,可以在grub.conf里加上no initrd,它就跳过initrd的检测和执行了,以前好像就没有,后来才有的。
它的作用是在没有mount
/分区以前,系统要执行一些操作,比如挂载scsi驱动,它就把initrd释放到内存里,作一个虚拟的/,然后执行其根目录下的一个脚本
“linuxrc”,运行insmod和nash命令挂装模块。为什么有的时候我们在lilo或grub的配置文件中不加入该行都可以正常开机呢?这是因
为我们一般的PC机都没有使用scsi硬盘等需要先加载其驱动的设备,所以就算没有initrd***.img也可以正常开机。但是如果我们要在服务器上
为其编译新内核那就一定不要忘记也为其新建一个initrd文件呀!
[color="#ff3f00"]好,下面来看看如何查看initrd***.img里面的内容和如何为你的新内核创建一个新的initrd.img文件。
[color="#a300a3"]查看initrd.img:
initrd***.img虽然后缀是“img”,但其实它是一个gz格式的文件,我们可以先把它解压,然后载挂装到目录下:
1、cp initrd.img initrd.gz
2、guzip initrd.gz
3、mount -o loop initrd /mnt/floppy
进入/mnt/floppy目录,我们就可以看到initrd***.img文件的庐山真面目了。
[color="#a300a3"]制作initrd文件
当我们编译了一个新的内核,也不要忘了为我们的scsi设备做一个新的initrd镜像:
语法:
mkinitrd 文件名 内核的目录名
示例:
mkinitrd initrd-2.4.19.img 2.4.19
initrd-2.4.19.img文件是自己任意取的,但最好对应自己的内核版本号。
2.4.19是在/lib/modules中的目录名,对应内核的版本。
当然,我们也可以在挂装了initrd***.img文件后直接添加模块到/lib目录中,然后修改linuxrc脚本让其开机进行挂装。但必须具备一定的shell脚本的能力才行。
IBM参考文档:

http://www-128.ibm.com/developerworks/cn/linux/l-k26initrd/index.html


Linux 下的 initrd 映像文件初探

Wu Zhangjin 创作于 2015/06/18
 评论 / 分享

by falcon of TinyLab.org2008/04/19

1 简介

如果自己制作过嵌入式 Linux 文件系统,那么应该比较了解 initrd 映像文件是个什么东西了?initrd 即 initial RAM disk,在内核解压之后,在真正的 root filesystem 被启动之前,它被加载到内存中,做一些系统初始化的操作,比如加载内核模块,挂载新的 Root 文件系统等。

initrd 本身是一个文件,内核启动时可以把它展开成一个文件系统。

在 2.6 版本的内核以前,initrd 基于一种特殊的 Loop设备,在展开成一个文件系统前需要通过一种 Loop 设备挂载起来,因为涉及到挂载操作,所以会涉及到一些操作权限。不过在 2.6 版本内核之后出现了 initramfs,它和 initrd 实现同样的功能,但是它基于一种 cpio 档,无须挂载就可以展开成一个文件系统,因此省去了各种相关的权限,在自动化方面更方便了。

initrd 的一个特别有趣的应用是Live CD,比如 Knoppix,它通过 initrd 启动一个初始化的文件系统,然后再通过一个 Cloop 设备挂载一个特别的压缩文件,展开为一个新的 Root 文件系统,这样一个 700M 左右的光盘就能够装下几个 G 的东西,包含大部分的软件和相应的内核模块,进而支持各种各样的功能。

2 initrd/initramfs 制作

下面简单介绍一下这两种初始化文件系统(initrd 和 initramfs)的制作过程。

先准备一个测试的目录。

  1. $ cd /tmp
  2. $ mkdir initrd
  3. $ mkdir initrd/loop initrd/cpio

2.1 initrd (via a loop device)

首先通过 dd 命令产生一个指定大小的文件。先来计算一下大小,比如要产生一个 1M 大小的文件,那么可以设置该文件的数据块大小为 1024kbyte,然后弄上 1024 块。

  1. $ dd if=/dev/zero of=ramdisk bs=1024 count=1024
  2. $ ls -lh ramdisk
  3. -rw-r--r-- 1 falcon falcon 1.0M 2008-04-19 14:59 ramdisk
  4. $ file ramdisk
  5. ramdisk: data

得到这样一个文件以后就可以把这个文件系统格式化为 ext3 或者是 ext2 的文件系统。

  1. $ mkfs.ext2 ramdisk
  2. $ file ramdisk
  3. ramdisk: Linux rev 1.0 ext2 filesystem data

如果想往这个文件系统里头添加内容(比如用 busybox 自动的创建一些内容,或者参照 Linux 的根文件系统,从头开始手动制作一个)那么就需要先通过 Loop 设备挂载一下。

不过挂载时需要 Root 用户才行,所以如果你没有 Root 用户的权限,做这个工作就不方便了,从这里就可以看出之后要介绍的 initramfs 的好处了。

  1. $ mount ramdisk /mnt/ -o loop
  2. mount: only root can do that
  3. $ sudo mount ramdisk /mnt/ -o loop
  4. $ ls /mnt/
  5. lost+found
  6. $ mount | grep ramdisk
  7. /tmp/initrd/loop/ramdisk on /mnt type ext2 (rw,loop=/dev/loop0)

挂载以后只有一个 lost+found 目录,如果要做成一个完整的 initrd,还得做一些工作,创建相应的目录和文件,详细内容可参考该书:Optimizing Embedded Systems using Busybox。

制作完文件系统以后就可以进行“打包”操作,制作成一个可以使用的 initrd 文件。

  1. // 确保各项操作已经写入磁盘
  2. $ sync
  3. // 卸载已经挂载的ramdisk
  4. $ sudo umount /mnt
  5. // “打包”成initrd文件,如果是解压,那么使用gunzip命令,后面直接跟上要解压的文件即可
  6. $ gzip -9 ramdisk
  7. $ file ramdisk.gz
  8. ramdisk.gz: gzip compressed data, was "ramdisk", from Unix, last modified: Sat Apr 19 17:05:24 2008, max compression

如果想要这个 initrd 映像文件能够正常工作,那么得确保文件系统里头的基本工具都有了,并且确保内核已经编译了相关的支持,比如 Loop 设备的内核支持:

  1. Device Drivers > Block Devices > Loopback Device Support.

以及其他的选项,比如 ext2 文件系统支持等,就可以考虑测试 ramdisk.gz 能不能用了,在 grub 下面可以考虑使用 initrd /path/to/ramdisk.gz 来测试它,而在 lilo 下则通过 initrd 变量来指定initrd = /path/to/ramdisk.gz

2.2 initramfs (via a cpio archive)

这种方式仅仅需要把一个符合 Linux 标准的 Root 文件系统所在目录中的文件加到一个 cpio 档里头,然后“打包”即可。

首先,参考后续资料创建一个文件系统。

  1. $ cd /tmp/initrd/cpio
  2. // 在这个目录下创建一个符合 Linux标准的 Root 文件系统
  3. $ .... do what you should to do ...

之后是把这个目录下的内容加到一个 cpio 档里头。

  1. $ find . | cpio -c -o > ../ramdisk
  2. $ file ../ramdisk
  3. ../ramdisk: ASCII cpio archive (pre-SVR4 or odc)

“打包”(压缩)一下。

  1. $ sync
  2. $ cd ../
  3. $ gzip -9 ramdisk
  4. $ file ramdisk.gz
  5. ramdisk.gz: gzip compressed data, was "ramdisk", from Unix, last modified: Sat Apr 19 17:37:25 2008, max compression

到这里,这个 ramdisk.gz 在 2.6 的内核之后也应该可以类似上面的一样使用了,不过别忘记了加上相应的内核选项,比如(initramfs)初始化文件系统支持。

下面来看看如何对 ubuntu 8.04 中的 initrd 文件“解包”吧。

看当前内核使用的 initrd:

  1. $ ls /boot/initrd.img-`uname -r`
  2. /boot/initrd.img-2.6.24-12-generic
  3. $ file /boot/initrd.img-2.6.24-12-generic
  4. /boot/initrd.img-2.6.24-12-generic: gzip compressed data, from Unix, last modified: Thu Apr 3 18:35:25 2008

“解压”该文件:

  1. $ mkdir /tmp/initrd/current
  2. $ cp /boot/initrd.img-2.6.24-12-generic /tmp/initrd/current/
  3. $ cd /tmp/initrd/current/
  4. $ mv initrd.img-2.6.24-12-generic initrd.img-2.6.24-12-generic.gz
  5. $ gunzip initrd.img-2.6.24-12-generic.gz
  6. $ file initrd.img-2.6.24-12-generic
  7. initrd.img-2.6.24-12-generic: ASCII cpio archive (SVR4 with no CRC)

现在展开 cpio 档,并查看里头的内容。

  1. $ cpio -i < ./initrd.img-2.6.24-12-generic
  2. $ ls
  3. bin conf etc init initrd.img-2.6.24-12-generic lib modules sbin scripts usr var

这样就可以看看 Linux 中的 initrd 文件里头的庐山真面目了。如果有兴趣,可以考虑往里头加点自己的东西,然后通过上面介绍的方法,把它重新“打包”成 initrd 文件,并让 Linux 系统把你”hack”的 initrd 文件加载起来。

3 参考资料

  • man boot-scripts (或 man 7 boot)
  • initrd
  • Linux initial RAM disk (initrd) overview
  • Loop device
  • Cloop
  • Knoppix
  • busybox

0 0
原创粉丝点击