Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2147553
  • 博文数量: 333
  • 博客积分: 10161
  • 博客等级: 上将
  • 技术积分: 5238
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-19 08:59
文章分类

全部博文(333)

文章存档

2017年(10)

2014年(2)

2013年(57)

2012年(64)

2011年(76)

2010年(84)

2009年(3)

2008年(37)

分类: LINUX

2010-09-09 14:17:02

Linux下的Initrd映像文件初探

falcon 19 四月, 2008 07:58 Linux&Unix 静态链接网址 引用 (0)
by falcon
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
$ mkdir initrd
$ mkdir initrd/loop initrd/cpio



1. initrd (via a loop device)

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

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


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

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



    如果想往这个文件系统里头添加内容(比如用busybox[7]自动的创建一些内容,或者参照Linux的根文件系统,从头开始手动制作一个)那么就需要先通过loop设备挂载一下。
    不过挂载时需要root用户才行,所以如果你没有root用户的权限,做这个工作就不方便了,从这里就可以看出之后要介绍的initramfs的好处了。

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



    挂载以后只有一个lost+found目录,如果要做成一个完整的initrd,还得做一些工作,创建相应的目录和文件。这个工作可以参考这里[8,9]。
    制作完文件系统以后就可以进行“打包”操作,制作成一个可以使用的initrd文件。

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


   
    如果想要这个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
在这个目录下创建一个符合linux标准的root文件系统
$ .... do what you should to do ...



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

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


       
    "打包"(压缩)一下。

$ sync
$ cd ../
$ gzip -9 ramdisk
$ file ramdisk.gz
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。

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


   
    “解压”该文件。

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



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

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


   
    这样你就可以看看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

阅读(838) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~