linux initrd 制作及使用
使用Ramdisk作为根文件系统,也就是INITRD
一, Ramdisk
Ram Disk 就是将内存中的一块区域作为物理磁盘来使用的一种技术。
使用时内核配置:两个选项:第一个设定Ramdisk个数,默认16个;第二个是设定Ramdisk的大小,设定16M
Device Drivers --->
[*] Block devices --->
<*> RAM block device support
(16) Default number of RAM disks
(16384) Default RAM disk size (kbytes)
另外:设置RAM disk 支持
General setup --->
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
二, initrd
initrd全称是 initial RAM disk ,它提供一种让核心可以简单使用Ramdisk的能力,简单的说,这些能力包括:
格式化一个 Ramdisk;
加载文件系统内容到Ramdisk;
将Ramdisk作为根文件系统;
而Linux启动阶段的Ramdisk相当于一个未格式化的硬盘分区,核心可以直接将initrd的内容释放到一个未初始化的Ramdisk里,这个过程与Ghost恢复一个分区的过程十分相似。于是,相应的内容被加载到相应的Ramdisk中,同时,这个Ramdisk也被格式化成某种由initrd格式所表达的分区格式。
initrd支持的格式
· Romfs文件系统;
· Ext2文件系统;
· cramfs文件系统;
· minix文件系统;
三, Gzip支持
如果核心选择了Gzip支持(通常这是默认的,在init/do_mounts_rd.c中定义的BUILD_CRAMDISK宏)还可以使用Gzip压缩的initrd。相关的代码可以在核心源码 drivers/block/rd.c:identify_ramdisk_image 中找到。
四, 制作initrd
initrd有两种格式,initrd-image和initrd-cpio。
办法一
通过ramdisk来制作的方法比较简单(以ext2文件系统为例):
redice # mkfs.ext2 /dev/ram0
redice # mount /dev/ram0 /mnt/rd
redice # cp _what_you_like_ /mnt/rd # 把需要的文件复制过去
redice # dd if=/dev/ram0 of=/tmp/initrd
redice # gzip -9 /tmp/initrd
这个过程也最能够解释initrd的本质,对于Linux来说,Ramdisk的一个块设备,而initrd是这个块设备上所有内容的“克隆”(由
命令dd来完成)而生成的文件。核心中加载initrd相关的代码则用于完成将相反的过程,即将这一个文件恢复到Ramdisk中去。
办法二
通过loop设备来制作initrd的过程:
redice # dd if=/dev/zero of=/tmp/initrd bs=1024 count=4096 # 制作一个4M的空白文件
redice # losetup /dev/loop0 /tmp/initrd # 映射到loop设备上;
redice # mkfs.ext2 /dev/loop0 # 创建文件系统;
redice # mount /dev/loop0 /mnt/rd
redice # cp _what_you_like_ /mnt/rd # 复制需要的文件;
redice # umount /mnt/rd
redice # losetup -d /dev/loop0
redice # gzip -9 /tmp/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
办法四(新式INITRD:cpio-initrd的制作)
# find . | cpio -c -o > ../initrd.img
# gzip ../initrd.img
解压initrd
gunzip initrd.img.gz
即使您的 initrd 映像文件不是以 .gz 结尾,它也可能是一个压缩文件,
可以给这个文件添加上 .gz后缀,然后再使用 gunzip 对其进行解压。
cpio 归档文件
# mkdir temp ; cd temp
# cp /boot/initrd-2.6.14.2.img initrd-2.6.14.2.img.gz
# gunzip initrd-2.6.14.2.img.gz
#cpio -ivmd < initrd-2.6.14.2.img
五, 启动:
Redboot启动。
下载initrd
0x01000000-0x01258831
下载zImage
0x00100000-0x002f82f7
启动命令
exec -r 0x1000000 -s 0x258831 -c "root=/dev/ram rw console=ttymxc0,115200"
六, 结果:
办法三制作,也就是initrd-image可以成功启动:
Kernel command line: root=/dev/ram rw console=ttymxc0,115200
checking if image is initramfs...it isn't (no cpio magic); looks like an initrd
Freeing initrd memory: 2402K
RAMDISK: Compressed image found at block 0
RAMDISK: ran out of compressed data
out of input data
VFS: Mounted root (ext2 filesystem).
Freeing init memory: 140K
Mounting /proc and /sys
Starting the hotplug events dispatcher udevd
Synthesizing initial hotplug events
Setting the hostname to aigo_R&D
Mounting filesystems
initrd-cpio无法启动:
Kernel command line: root=/dev/ram rw console=ttymxc0,115200
checking if image is initramfs...it isn't (out of input data); looks like an initrd
Freeing initrd memory: 2376K
RAMDISK: Compressed image found at block 0
RAMDISK: ran out of compressed data
out of input data
List of all partitions:
1f00 2048 mtdblock0 (driver?)
1f01 4096 mtdblock1 (driver?)
1f02 2048 mtdblock2 (driver?)
1f03 16384 mtdblock3 (driver?)
1f04 8192 mtdblock4 (driver?)
1f05 4096 mtdblock5 (driver?)
1f06 786432 mtdblock6 (driver?)
1f07 3371008 mtdblock7 (driver?)
No filesystem could mount root, tried: ext2 cramfs vfat msdos
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0)
参考资料:
Linux文档中关于ramdisk的介绍,核心目录里 Documentation/ramdisk.txt;
Linux文档中关于initrd的介绍,核心目录 Documentation/initrd.txt;
Linux文档中关于tmpfs的介绍,核心目录 Documentation/filesystems/tmpfs.txt;