最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

分析initrd.img文件

来源:动视网 责编:小OO 时间:2025-10-01 17:31:49
文档

分析initrd.img文件

原始URL:http://www.linuxfly.org/post/94.htm项目中,常会对系统进行驱动的升级或添加新硬件,此时,常会用到mkinitrd命令。而该命令其实是一个脚本,通过一系列的流程来生成系统启动需要的initrd.img文件。通过分析该文件,我们可以更清楚的知道系统启动时候加载驱动的顺序(用于调整HBA卡识别的设备符号),以及修正或加入一些自定义的配置。一、什么是initrd initrd的英文含义是bootloaderinitializedRAMdisk,就是由boo
推荐度:
导读原始URL:http://www.linuxfly.org/post/94.htm项目中,常会对系统进行驱动的升级或添加新硬件,此时,常会用到mkinitrd命令。而该命令其实是一个脚本,通过一系列的流程来生成系统启动需要的initrd.img文件。通过分析该文件,我们可以更清楚的知道系统启动时候加载驱动的顺序(用于调整HBA卡识别的设备符号),以及修正或加入一些自定义的配置。一、什么是initrd initrd的英文含义是bootloaderinitializedRAMdisk,就是由boo
原始URL: http://www.linuxfly.org/post/94.htm

项目中,常会对系统进行驱动的升级或添加新硬件,此时,常会用到mkinitrd命令。而该命令其实是一个脚本,通过一系列的流程来生成系统启动需要的initrd.img文件。通过分析该文件,我们可以更清楚的知道系统启动时候加载驱动的顺序(用于调整HBA卡识别的设备符号),以及修正或加入一些自定义的配置。

一、什么是initrd

 initrd 的英文含义是 boot loader initialized RAM disk,就是由 boot loader 初始化的内存盘。initrd的最初的目的是为了把kernel的启动分成两个阶段:在kernel中保留最少最基本的启动代码,然后把对各种各样硬件设备的支持以模块的方式放在initrd中,这样就在启动过程中可以从initrd所mount的根文件系统中装载需要的模块。这样的一个好处就是在保持kernel不变的情况下,通过修改initrd中的内容就可以灵活的支持不同的硬件。在启动完成的最后阶段,根文件系统可以重新mount到其他设备上。

二、是否必须

 initrd文件不是必须的,但对于像红旗这样,需要具有适应在不同的硬件环境下使用的要求,那使用initrd会更方便。

 我们常在编译核心的使用,使用make menuconfig,其中对某些而外的驱动,是可以选择以模块编译,还是<*>直接编译到核心里面。例如ext3文件系统驱动,如果核心需要放在该文件系统上,可以有两个方法:

引用

1、把其全都编译到内核中,则只需要一个内核文件系统即可启动;

2、把其编译为模块,然后通过initrd虚拟的内存系统加载;

 也就是说由于initrd会在内存虚拟一个文件系统,然后可以根据不同的硬件加载不同的驱动,而不需要重新编译整个核心。所以,大部分的发行版都会通过这种方式对驱动进行加载。

三、版本

 根据核心版本的不同,initrd文件有两种格式:image和cpio。2.4核心只使用image格式,而2.6核心可同时支持两种格式。它们不单格式不一样,而且运作的机制和流程也完全不同,甚至制作方法也不一样。

 下面,我就以红旗DC 4.1和红旗DC 5.0某机器上的initrd进行说明。 

四、2.4核心用initrd

1、格式

 2.4核心只能使用image格式,其一般是通过loop设备及gzip压缩生成(mkinitrd命令)。

2、解压

 以红旗DC 4.1使用的核心版本为例:

引用

[root@samba test]# ls

initrd-2.4.21-9.30AX.img

[root@samba test]# file initrd-2.4.21-9.30AX.img

initrd-2.4.21-9.30AX.img: gzip compressed data, from Unix, max compression

可以看到,它是一个gzip压缩文件,需要先解压:

引用

[root@samba test]# mv initrd-2.4.21-9.30AX.img initrd-2.4.21-9.30AX.img.gz

[root@samba test]# gunzip initrd-2.4.21-9.30AX.img.gz

[root@samba test]# file initrd-2.4.21-9.30AX.img

initrd-2.4.21-9.30AX.img: Linux rev 1.0 ext2 filesystem data

然后挂载:

引用

[root@samba test]# mkdir /mnt/disk

[root@samba test]# mount -o loop initrd-2.4.21-9.30AX.img /mnt/disk/

内容:

引用

[root@samba test]# cd /mnt/disk/

[root@samba disk]# ls -lR

.:

total 8

drwxr-xr-x    2 root     root         1024 Jan 10  2006 bin

drwxr-xr-x    2 root     root         1024 Jan 10  2006 dev

drwxr-xr-x    2 root     root         1024 Jan 10  2006 etc

drwxr-xr-x    2 root     root         1024 Jan 10  2006 lib

-rwxr-xr-x    1 root     root          436 Jan 10  2006 linuxrc  <== 一个nash脚本

drwxr-xr-x    2 root     root         1024 Jan 10  2006 loopfs

drwxr-xr-x    2 root     root         1024 Jan 10  2006 proc

lrwxrwxrwx    1 root     root            3 Jan 10  2006 sbin -> bin

drwxr-xr-x    2 root     root         1024 Jan 10  2006 sysroot

./bin:

total 151

-rwxr-xr-x    1 root     root       1224 Jan 10  2006 insmod  <== 插入模块

lrwxrwxrwx    1 root     root           10 Jan 10  2006 modprobe -> /sbin/nash

-rwxr-xr-x    1 root     root        29524 Jan 10  2006 nash  <== 一个小型解释器

./dev:  <== 一些必要的设备文件

total 0

crw-r--r--    1 root     root       5,   1 Jan 10  2006 console

crw-r--r--    1 root     root       1,   3 Jan 10  2006 null

brw-r--r--    1 root     root       1,   1 Jan 10  2006 ram

crw-r--r--    1 root     root       4,   0 Jan 10  2006 systty

crw-r--r--    1 root     root       4,   1 Jan 10  2006 tty1

crw-r--r--    1 root     root       4,   2 Jan 10  2006 tty2

crw-r--r--    1 root     root       4,   3 Jan 10  2006 tty3

crw-r--r--    1 root     root       4,   4 Jan 10  2006 tty4

./etc:

total 0

./lib:   <== 启动时加载的模块

total 173

-rwxr--r--    1 root     root       108320 May 27  2004 ext3.o

-rwxr--r--    1 root     root        65888 May 27  2004 jbd.o

./loopfs:

total 0

./proc:

total 0

./sysroot:

total 0

3、执行脚本

上面可以看到,我们要了解的就是linuxrc执行文件:

引用

[root@samba disk]# cat linuxrc

#!/bin/nash

echo "Loading jbd.o module"

insmod /lib/jbd.o

echo "Loading ext3.o module"

insmod /lib/ext3.o

echo Mounting /proc filesystem

mount -t proc /proc /proc

echo Creating block devices

mkdevices /dev

echo Creating root device

mkrootdev /dev/root

echo 0x0100 > /proc/sys/kernel/real-root-dev

echo Mounting root filesystem

mount -o defaults --ro -t ext3 /dev/root /sysroot

pivot_root /sysroot /sysroot/initrd

umount /initrd/proc

很清楚,内容就是在挂载对应的驱动和目录。看上去的命令和普通的linux命令是一样的。

4、执行流程

引用

1)boot loader把内核以及/dev/initrd的内容加载到内存,/dev/initrd是由boot loader初始化的设备,存储着initrd。

2)在内核初始化过程中,内核把 /dev/initrd 设备的内容解压缩并拷贝到 /dev/ram0 设备上。

3)内核以可读写的方式把 /dev/ram0 设备挂载为原始的根文件系统。

4)如果 /dev/ram0 被指定为真正的根文件系统,那么内核跳至最后一步正常启动。

5)执行 initrd 上的 /linuxrc 文件,linuxrc 通常是一个脚本文件,负责加载内核访问根文件系统必须的驱动, 以及加载根文件系统。

6)/linuxrc 执行完毕,真正的根文件系统被挂载。

7)如果真正的根文件系统存在 /initrd 目录,那么 /dev/ram0 将从 / 移动到 /initrd。否则如果 /initrd 目录不存在, /dev/ram0 将被卸载。

8)在真正的根文件系统上进行正常启动过程,执行 /sbin/init。

linux2.4 内核的 initrd 的执行是作为内核启动的一个中间阶段,也就是说 initrd 的 /linuxrc 执行以后,内核会继续执行初始化代码。而我们可以把自己要添加的驱动执行脚本加到linuxrc,并把驱动放到/lib目录,例如:qla2300等。

5、生成新initrd

由于默认的initrd不大,只有8M(有mkinitrd脚本决定):

引用

[root@samba disk]# df -h /mnt/disk

Filesystem            Size  Used Avail Use% Mounted on

/root/test/initrd-2.4.21-9.30AX.img

                     7.6M  333K  6.9M   5% /mnt/disk

所以,要加入的东西不要过多。保存的过程是:

引用

[root@samba test]# umount /mnt/disk/

[root@samba test]# mv initrd-2.4.21-9.30AX.img initrd-2.4.21-9.30AX.new.img

[root@samba test]# gzip -9 initrd-2.4.21-9.30AX.new.img

[root@samba test]# mv initrd-2.4.21-9.30AX.new.img.gz initrd-2.4.21-9.30AX.new.img

[root@samba test]# cp initrd-2.4.21-9.30AX.new.img /boot/

最后,修改grub即可。

※如果是要新做一个initrd文件,可以这样:

引用

[root@samba test]# dd if=/dev/zero of=./new.img bs=1024k count=8

[root@samba test]# mkfs.ext2 -F -m0 new.img

[root@samba test]# mkdir /mnt/new

[root@samba test]# mount -o loop new.img /mnt/new/  <==创建一个新挂载点

[root@samba test]# cd /mnt/new/

[root@samba new]# cp -a /mnt/disk/* ./

然后加入自定义的驱动或脚本

[root@samba test]# umount /mnt/new/

[root@samba test]# gzip -9 new.img

[root@samba test]# mv new.img.gz new.img

五、2.6核心用initrd

1、格式

 2.6核心可以支持image格式,但更多的时候使用的是cpio格式。其核心文件不再是/linuxrc,而是/init。

2、解压

 以红旗DC 5.0使用的核心版本为例:

引用

[root@printserver test]# ls

initrd-2.6.9-11.19AX.img

[root@printserver test]# file initrd-2.6.9-11.19AX.img

initrd-2.6.9-11.19AX.img: gzip compressed data, from Unix, max compression

可以这样来识别格式:

引用

[root@printserver test]# gzip -dc initrd-2.6.9-11.19AX.img > new.img

[root@printserver test]# file new.img

new.img: ASCII cpio archive (SVR4 with no CRC)

创建一个新目录,然后解压出来:

引用

[root@printserver test]# mkdir new

[root@printserver test]# cd new/

[root@printserver new]# gzip -dc ../initrd-2.6.9-11.19AX.img | cpio -idvm

也可以这样运行命令:

引用

[root@printserver new1]# zcat ../initrd-2.6.9-11.19AX.img |cpio -idvm

内容:

引用

[root@printserver new]# ll -R

.:

total 36

drwxr-xr-x  2 root root 4096 Sep 30 16:55 bin

drwxr-xr-x  2 root root 4096 Sep 30 16:55 dev

drwxr-xr-x  3 root root 4096 Sep 30 16:55 etc

-rwxr-xr-x  1 root root  725 Jun 29 17:35 init  <== 一个nash脚本

drwxr-xr-x  2 root root 4096 Sep 30 16:55 lib

drwxr-xr-x  2 root root 4096 Jun 29 17:35 loopfs

drwxr-xr-x  2 root root 4096 Jun 29 17:35 proc

lrwxrwxrwx  1 root root    3 Sep 30 16:54 sbin -> bin

drwxr-xr-x  2 root root 4096 Jun 29 17:35 sys

drwxr-xr-x  2 root root 4096 Jun 29 17:35 sysroot

./bin:

total 592

lrwxrwxrwx  1 root root     10 Sep 30 16:55 hotplug -> /sbin/nash

-rwxr-xr-x  1 root root  12904 Jun 29 17:35 insmod  <== 插入模块

lrwxrwxrwx  1 root root     10 Sep 30 16:55 modprobe -> /sbin/nash

-rwxr-xr-x  1 root root  38184 Jun 29 17:35 nash  <== 一个小型解释器

-rwxr-xr-x  1 root root 541716 Jun 29 17:35 udev

lrwxrwxrwx  1 root root      4 Sep 30 16:54 udevstart -> udev

./dev:  <== 一些必要的设备文件

total 0

crw-r--r--  1 root root 5, 1 Jun 29 17:35 console

crw-r--r--  1 root root 1, 3 Jun 29 17:35 null

brw-r--r--  1 root root 1, 1 Jun 29 17:35 ram

crw-r--r--  1 root root 4, 0 Jun 29 17:35 systty

crw-r--r--  1 root root 4, 1 Jun 29 17:35 tty1

crw-r--r--  1 root root 4, 2 Jun 29 17:35 tty2

crw-r--r--  1 root root 4, 3 Jun 29 17:35 tty3

crw-r--r--  1 root root 4, 4 Jun 29 17:35 tty4

./etc:

total 4

drwxr-xr-x  2 root root 4096 Sep 30 16:55 udev

./etc/udev:  <== udev配置文件

total 4

-rw-r--r--  1 root root 1128 Jun 29 17:35 udev.conf

./lib:  <== 启动时加载的模块

total 236

-rwxr--r--  1 root root 139452 Aug  5  2005 ext3.ko

-rwxr--r--  1 root root  8 Aug  5  2005 jbd.ko

./loopfs:

total 0

./proc:

total 0

./sys:

total 0

./sysroot:

total 0

3、执行脚本

引用

[root@printserver new]# cat init

#!/bin/nash

mount -t proc /proc /proc

setquiet

echo Mounted /proc filesystem

echo Mounting sysfs

mount -t sysfs none /sys

echo Creating /dev

mount -o mode=0755 -t tmpfs none /dev

mknod /dev/console c 5 1

mknod /dev/null c 1 3

mknod /dev/zero c 1 5

mkdir /dev/pts

mkdir /dev/shm

echo Starting udev

/sbin/udevstart

echo -n "/sbin/hotplug" > /proc/sys/kernel/hotplug

echo "Loading jbd.ko module"

insmod /lib/jbd.ko

echo "Loading ext3.ko module"

insmod /lib/ext3.ko

/sbin/udevstart

echo Creating root device

mkrootdev /dev/root

umount /sys

echo Mounting root filesystem

mount -o defaults --ro -t ext3 /dev/root /sysroot

mount -t tmpfs --bind /dev /sysroot/dev

echo Switching to new root

switchroot /sysroot

umount /initrd/dev

很明显,与2.4核心最大的差别在于用init代替了linuxrc,并且加入了udev方式。

4、执行流程

由于采用cpio格式后,不需要再创建一个临时的设备用于挂载img文件,所以执行的流程也简单很多:

引用

1)boot loader 把内核以及 initrd 文件加载到内存的特定位置。

2)内核判断initrd的文件格式,如果是cpio格式。

3)将initrd的内容释放到rootfs中。

4)执行initrd中的/init文件,执行到这一点,内核的工作全部结束,完全交给/init文件处理。

正式由于cpio格式带来的便利,我们要修改和增加自定义的脚本和驱动都变得简单很多,一般只需要对init脚本和/lib添加即可。

5、生成新initrd文件

引用

[root@printserver new]# find ./ | cpio -c -o > ../initrd-2.6.9-11.19AX.new.img

1617 blocks

[root@printserver new]# cd ..

[root@printserver test]# gzip -9 initrd-2.6.9-11.19AX.new.img

[root@printserver test]# mv initrd-2.6.9-11.19AX.new.img.gz initrd-2.6.9-11.19AX.new.img

[root@printserver test]# cp initrd-2.6.9-11.19AX.new.img /boot/

最后,修改grub即可。

若在2.6核心上使用image的initrd文件,处理的流程只是在开始会增加一个判断的步骤,后续是和在2.4上执行的过程是一样的。

六、对比

可以看到,使用cpio格式的处理是非常方便和简洁的,很难对比两种格式处理有什么不同,可以说几乎是一样的。但就是因为制作cpio,以及启动对cpio的处理更直接,目前新发行版的initrd都以cpio格式为多。

文档

分析initrd.img文件

原始URL:http://www.linuxfly.org/post/94.htm项目中,常会对系统进行驱动的升级或添加新硬件,此时,常会用到mkinitrd命令。而该命令其实是一个脚本,通过一系列的流程来生成系统启动需要的initrd.img文件。通过分析该文件,我们可以更清楚的知道系统启动时候加载驱动的顺序(用于调整HBA卡识别的设备符号),以及修正或加入一些自定义的配置。一、什么是initrd initrd的英文含义是bootloaderinitializedRAMdisk,就是由boo
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top