Chinaunix首页 | 论坛 | 博客
  • 博客访问: 451948
  • 博文数量: 72
  • 博客积分: 3186
  • 博客等级: 中校
  • 技术积分: 1039
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-07 16:53
文章分类

全部博文(72)

文章存档

2012年(1)

2011年(5)

2010年(10)

2009年(56)

我的朋友

分类: 嵌入式

2009-11-10 14:45:25

说明:本篇是对 http://www.ibm.com/developerworks/cn/linux/l-initrd.html 这篇文章的一点笔记,以及参考一些网络资料。如有疑问,请参考原文。


一. 什么是initrd?

initrd 即 initrd ramdisk, 是指一个临时文件系统(或临时根文件系统)。
我们首先来理清几个问题。
1. 所谓根文件系统,就是指我们Linux里用 / 表示的那个,其它的分区都要挂在 / 下的某个路径下,所以用 / 表示的那个就是根文件系统了。注意initrd是文件系统用还是根文件系统用,这有本质的区别。

2. 根文件系统里的目录结构。这里以我们的pc机上文件系统为例,列出一些常见的目录。
/bin /boot /dev /etc /home /lib /media /mnt /opt /proc /root /sbin
/tmp /usr
在做嵌入式的文件系统的时候,可以根据需要来选取就行了。

3. initrd 的作用
initrd中包含了各种可执行程序和驱动程序,它可以用来挂载实际的根文件系统,然后再将initrd卸载,释放内存。许多嵌入式Linux系统中,initrd就是最终的根文件系统(此时就不能称其为“临时”文件系统了)。

4. “临时”
很多时候都说initrd是临时的,例如在我们pc机上,initrd的生存周期很短,只是到真实文件系统的一个桥梁。但在某些嵌入式设备中,initrd就是永久的根文件系统。

二. 查看initrd的内容(在pc机上)

# mkdir temp ; cd temp
# cp /boot/initrd-2.6.14.2.img initrd-2.6.14.2.img.gz  //注意这里先给它加了个.gz后缀
# gunzip initrd-2.6.14.2.img.gz
# cpio -i --make-directories < initrd-2.6.14.2.img

三. 制作initrd


#!/bin/bash

# Housekeeping...
rm -f /tmp/ramdisk.img
rm -f /tmp/ramdisk.img.gz

# Ramdisk Constants
RDSIZE=4000
BLKSIZE=1024

# Create an empty ramdisk image 为了创建 initrd,我们最开始创建了一个空文件,这使用了 /dev/zero(一个由零组成的码流)作为输入,并将其写入到 ramdisk.img 文件中。所生成的文件大小是 4MB(4000 个 1K 大小的块)
dd if=/dev/zero of=/tmp/ramdisk.img bs=$BLKSIZE count=$RDSIZE

# Make it an ext2 mountable file system  使用 mke2fs 命令在这个空文件上创建了一个 ext2(即 second extended)文件系统。这里可以换成其他文件系统,如romfs, cramfs...
/sbin/mke2fs -F -m 0 -b $BLKSIZE /tmp/ramdisk.img $RDSIZE

# Mount it so that we can populate  现在这个文件变成了一个 ext2 格式的文件系统,我们使用 loop 设备将这个文件挂载到 /mnt/initrd 上了
mount /tmp/ramdisk.img /mnt/initrd -t ext2 -o loop=/dev/loop0

# Populate the filesystem (subdirectories)  创建构成根文件系统所需要的子目录:/bin、/sys、/dev 和 /proc。这里只列出了所需要的目录(例如没有库),但是其中包含了很多功能。
mkdir /mnt/initrd/bin
mkdir /mnt/initrd/sys
mkdir /mnt/initrd/dev
mkdir /mnt/initrd/proc

# Grab busybox and create the symbolic links  为了可以使用根文件系统,我们使用了 BusyBox。这个工具是一个单一映像,其中包含了很多在 Linux 系统上通常可以找到的工具(例如 ash、awk、sed、insmod 等)。BusyBox 的优点是它将很多工具打包成一个文件,同时还可以共享它们的通用元素,这样可以极大地减少映像文件的大小。这对于嵌入式系统来说非常理想。将 BusyBox 映像从自己的源目录中拷贝到自己根目录下的 /bin 目录中...然后创建了很多符号链接,它们都指向 BusyBox 工具。BusyBox 会判断所调用的是哪个工具,并执行这个工具的功能。我们在这个目录中创建了几个链接来支持 init 脚本(每个命令都是一个指向 BusyBox 的链接。)
pushd /mnt/initrd/bin
cp /usr/local/src/busybox-1.1.1/busybox .
ln -s busybox ash
ln -s busybox mount
ln -s busybox echo
ln -s busybox ls
ln -s busybox cat
ln -s busybox ps
ln -s busybox dmesg
ln -s busybox sysctl
popd

# Grab the necessary dev files  创建几个特殊的设备文件。我从自己当前的 /dev 子目录中直接拷贝了这些文件,这使用了 -a 选项(归档)来保留它们的属性。
cp -a /dev/console /mnt/initrd/dev
cp -a /dev/ramdisk /mnt/initrd/dev
cp -a /dev/ram0 /mnt/initrd/dev
cp -a /dev/null /mnt/initrd/dev
cp -a /dev/tty1 /mnt/initrd/dev
cp -a /dev/tty2 /mnt/initrd/dev

# Equate sbin with bin  
pushd /mnt/initrd
ln -s bin sbin
popd

# Create the init file  生成 linuxrc 文件。在内核挂载 RAM 磁盘之后,它会查找 init 文件来执行。如果没有找到 init 文件,内核就会调用 linuxrc 文件作为自己的启动脚本。我们在这个文件中实现对环境的基本设置,例如挂载 /proc 文件系统。除了 /proc 之外,我还挂载了 /sys 文件系统,并向终端打印一条消息
cat >> /mnt/initrd/linuxrc << EOF
#!/bin/ash
echo
echo "Simple initrd is active"
echo
mount -t proc /proc /proc
mount -t sysfs none /sys
# 调用了 ash(一个 Bourne Shell 的克隆),这样就可以与根文件系统进行交互了。linuxrc 文件然后使用 chmod 命令修改成可执行的。
/bin/ash --login                
EOF

# 使用 chmod 命令修改成可执行的
chmod +x /mnt/initrd/linuxrc

# Finish up...  根文件系统就完成了。我们将其卸载掉,然后使用 gzip 对其进行压缩。所生成的文件(ramdisk.img.gz)被拷贝到 /boot 子目录中,这样就可以通过 GNU GRUB 对其进行加载了
umount /mnt/initrd
gzip -9 /tmp/ramdisk.img
cp /tmp/ramdisk.img.gz /boot/ramdisk.img.gz





-仅记录而已
阅读(1260) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~