2008-04-19
如果自己制作过嵌入式Linux文件系统,那么应该比较了解initrd映像文件是个什么东西了?initrd即initial RAM disk,在内核解压之后,在真正的root filesystem被启动之前,它被加载到内存中,做一些系统初始化的操作,比如加载内核模块,挂载新的root文件系统等[1,2]。
initrd本身是一个文件,内核启动时可以把它展开成一个文件系统。
在2.6版本的内核以前,initrd基于一种特殊的loop设备[4],在展开成一个文件系统前需要通过一种loop设备挂载起来,因为涉及到挂载操作,所以会涉及到一些操作权限。不过在2.6版本内核之后出现了initramfs,它和initrd实现同样的功能,但是它基于一种cpio档,无须挂载就可以展开成一个文件系统,因此省去了各种相关的权限,在自动化方面更方便了[2,3]。
initrd的一个特别有趣的应用是Live CD,比如Knoppix[6],它通过initrd启动一个初始化的文件系统,然后再通过一个Cloop设备[5]挂载一个特别的压缩文件,展开为一个新的Root文件系统,这样一个700M左右的光盘就能够装下几个G的东西,包含大部分的软件和相应的内核模块,进而支持各种各样的功能。
下面简单介绍一下这两种初始化文件系统(initrd和initramfs)的制作过程。
先准备一个测试的目录。
$ cd /tmp |
1. initrd (via a loop device)
首先通过dd命令产生一个指定大小的文件。先来计算一下大小,比如要产生一个1M大小的文件,那么可以设置该文件的数据块大小为1024kbyte,然后弄上1024块。
$ dd if=/dev/zero of=ramdisk bs=1024 count=1024 |
得到这样一个文件以后就可以把这个文件系统格式化为ext3或者是ext2的文件系统。
$ mkfs.ext2 ramdisk |
如果想往这个文件系统里头添加内容(比如用busybox[7]自动的创建一些内容,或者参照Linux的根文件系统,从头开始手动制作一个)那么就需要先通过loop设备挂载一下。
不过挂载时需要root用户才行,所以如果你没有root用户的权限,做这个工作就不方便了,从这里就可以看出之后要介绍的initramfs的好处了。
$ mount ramdisk /mnt/ -o loop |
挂载以后只有一个lost+found目录,如果要做成一个完整的initrd,还得做一些工作,创建相应的目录和文件。这个工作可以参考这里[8,9]。
制作完文件系统以后就可以进行“打包”操作,制作成一个可以使用的initrd文件。
//确保各项操作已经写入磁盘 |
如果想要这个initrd映像文件能够正常工作,那么得确保文件系统里头的基本工具都有了,并且确保内核已经编译了相关的支持,比如loop设备的内核支持:
Device Drivers > Block Devices > Loopback Device Support. |
以及其他的选项,比如ext2文件系统支持等,就可以考虑测试ramdisk.gz能不能用了,在grub下面可以考虑使用initrd /path/to/ramdisk.gz来测试它,而在lilo下则通过initrd变量来指定initrd = /path/to/ramdisk.gz。关于具体的细节,还是参考资料[3,8,9]吧。
2. initramfs (via a cpio archive)
这种方式仅仅需要把一个符合linux标准的root文件系统所在目录中的文件加到一个cpio档里头,然后“打包”即可。
首先,参考资料[8,9]创建一个文件系统。
$ cd /tmp/initrd/cpio |
之后是把这个目录下的内容加到一个cpio档里头。
$ find . | cpio -c -o > ../ramdisk |
"打包"(压缩)一下。
$ sync |
到这里,这个ramdisk.gz在2.6的内核之后也应该可以类似上面的一样使用了,不过别忘记了加上相应的内核选项,比如(initramfs)初始化文件系统支持。
下面来看看如何对ubuntu 8.04中的initrd文件“解包”吧。
查看当前内核使用的initrd。
$ ls /boot/initrd.img-`uname -r` |
“解压”该文件。
$ mkdir /tmp/initrd/current |
现在展开cpio档,并查看里头的内容。
$ cpio -i < ./initrd.img-2.6.24-12-generic |
这样你就可以看看Linux中的initrd文件里头的庐山真面目了。如果有兴趣,可以考虑往里头加点自己的东西,然后通过上面介绍的方法,把它重新“打包”成initrd文件,并让linux系统把你"hack"的initrd文件加载起来。
take one's time and play with it, you will find a lot of fun :-)
参考资料
[1] man boot-scripts (或 man 7 boot)
[2] initrd
[3] Linux initial RAM disk (initrd) overview
[4] Loop device
http://en.wikipedia.org/wiki/Loop_device
[5] Cloop
[6] Knoppix
[7] busybox
[8] Build a mini filesystem in linux from scratch
http://oss.lzu.edu.cn/blog/blog.php?/do_showone/tid_1211.html
[9] Build a mini filesystem in linux with BusyBox
http://oss.lzu.edu.cn/blog/blog.php?/do_showone/tid_1212.html