initramfs
详细的initramfs的资料可以参考如下:
- 黃敬群先生的blog:深入理解 Linux 2.6 的 initramfs 機制: http://blog.linux.org.tw/~jserv/archives/001954.html
- initramfs, a new model for initial RAM: http://www.linuxdevices.com/articles/AT4017834659.html
制作initramfs/initrd镜像
原文:http://www.cnblogs.com/wwang/archive/2010/10/27/1862222.html
initramfs
下面是一些使用initramfs的简单帮助
-
查看initramfs的内容
mkdir initrdtmp && cd initrdtmp \ && zcat /boot/initrd.img-2.6.24-16 initrd.img-2.6.24-16.gz|cpio -i --make-directories
- 创建initramfs
命令:mkinitramfs, update-initramfs
mkinitramfs
mkinitramfs -o /boot/initrd.img 2.6.24-16
Note: 2.6.24-16是需要创建initramfs的kernel版本号,如果是给当前kernel制作initramfs,可以用uname -r查看当前的版本号。提供kernel版本号的主要目的是为了在initramfs中添加指定kernel的驱动模块。mkinitramfs会把/lib/modules/${kernel_version}/ 目录下的一些启动会用到的模块添加到initramfs中。
update-initramfs
# 更新当前kernel的initramfs update-initramfs -u
在添加模块时,initramfs tools只会添加一些必要模块,用户可以通过在/etc/initramfs-tools/modules文件中加入模块名称来指定必须添加的模块。
initrd
目前还是有不少Linux发行版采用initrd(即RAM disk的方式)来实现引导,所以了解一下mkinitrd这个命令也很有必要。
mkinitrd类似于mkinitramfs,是用于生成initrd的一个工具。最基本的用法参考下面:
mkinitrd /boot/initrd.img $(uname -r)
如果需要指定哪些module在启动时必须load,需要加上--preload=module或者 --with=module这样的选项。这两者的区别在于--preload指定的module会在/etc/modprobe.d/* 里声明的任何SCSI模块之前被加载,--with指定的module会在/etc/modprobe.d/* 里声明的任何SCSI模块之后被加载。
另外还有一个选项需要被注意,即--builtin=module。在manual里这个选项的解释是:Act as if module is built into the kernel being used. mkinitrd will not look for this module, and will not emit an error if it does not exist. This option may be used multiple times.
根据上面的解释,可以看出builtin选项另外还有一个取巧的用处。以我所用的平台Acer Aspire One为例, 我在用mkinitrd制作RAM disk镜像是出现一个错误“No module ohci-hcd found ...”,遇到这个情况,builtin选项就起作用了,用--builtin=ohci-hcd, mkinitrd就可以忽略ohci-hcd不存在这个事实了。
initrd有两种格式,initrd-image和initrd-cpio。
-
办法一:通过ramdisk来制作的方法比较简单(以ext2文件系统为例):
mkfs.ext2 /dev/ram0 mount /dev/ram0 /mnt/rd cp _what_you_like_ /mnt/rd # 把需要的文件复制过去 dd if=/dev/ram0 of=/tmp/initrd gzip -9 /tmp/initrd
这个过程也最能够解释initrd的本质,对于Linux来说,Ramdisk的一个块设备,而initrd是这个块设备上所有内容的“克隆”(由命令dd来完成)而生成的文件。核心中加载initrd相关的代码则用于完成将相反的过程,即将这一个文件恢复到Ramdisk中去。
-
办法二:通过loop设备来制作initrd的过程(losetup,mkfs.ext2):
dd if=/dev/zero of=/tmp/initrd bs=1024 count=4096 # 制作一个4M的空白文件 losetup /dev/loop0 /tmp/initrd # 映射到loop设备上; mkfs.ext2 /dev/loop0 # 创建文件系统; mount /dev/loop0 /mnt/rd cp _what_you_like_ /mnt/rd # 复制需要的文件; umount /mnt/rd losetup -d /dev/loop0 gzip -9 /tmp/initrd
-
办法三:mount -o loop
dd if=/dev/zero of=../initrd.img bs=512k count=5 mkfs.ext2 -F -m0 ../initrd.img mount -t ext2 -o loop ../initrd.img /mnt cp -r * /mnt umount /mnt gzip -9 ../initrd.img
-
办法四(新式INITRD:cpio-initrd的制作)
find . | cpio -c -o > ../initrd.img gzip ../initrd.img
-
cpio-initrd
# 假设当前目录位于准备好的initrd文件系统的根目录下 find . | cpio -c -o > ../initrd.img gzip ../initrd.img # gen_init_cpio是编译内核时得到的,在内核源代码的 usr 目录下,我们可以通过以下步骤获取它,进入内核源代码 执行: make menuconfig make usr/ # gen_initramfs_list.sh 在内核源代码的 script 目录下,将这两个文件copy 到/tmp 目录下, # /tmp/initrd为解压好的initrd目录,执行以下命令制作initrd : gen_initramfs_list.sh initrd/ > filelist gen_init_cpio filelist >initrd.img gzip initrd.img mv initrd.img initrd-`uname –r`.img # 只有用这个方式压缩的initrd ,在Linux系统重启的时候才能一正确的文件格式 boot 起来,也可以用 # 这种方式修改安装光盘的initrd文件 然后进行系统安装。