Sep
30
项目中,常会对系统进行驱动的升级或添加新硬件,此时,常会用到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文件系统驱动,如果核心需要放在该文件系统上,可以有两个方法:
也就是说由于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使用的核心版本为例:
可以看到,它是一个gzip压缩文件,需要先解压:
然后挂载:
内容:
3、执行脚本
上面可以看到,我们要了解的就是linuxrc执行文件:
很清楚,内容就是在挂载对应的驱动和目录。看上去的命令和普通的linux命令是一样的。
4、执行流程
linux2.4 内核的 initrd 的执行是作为内核启动的一个中间阶段,也就是说 initrd 的 /linuxrc 执行以后,内核会继续执行初始化代码。而我们可以把自己要添加的驱动执行脚本加到linuxrc,并把驱动放到/lib目录,例如:qla2300等。
5、生成新initrd
由于默认的initrd不大,只有8M(有mkinitrd脚本决定):
所以,要加入的东西不要过多。保存的过程是:
最后,修改grub即可。
※如果是要新做一个initrd文件,可以这样:
一、什么是initrd
initrd 的英文含义是 boot loader initialized RAM disk,就是由 boot loader 初始化的内存盘。initrd的最初的目的是为了把kernel的启动分成两个阶段:在kernel中保留最少最基本的启动代码,然后把对各种各样硬件设备的支持以模块的方式放在initrd中,这样就在启动过程中可以从initrd所mount的根文件系统中装载需要的模块。这样的一个好处就是在保持kernel不变的情况下,通过修改initrd中的内容就可以灵活的支持不同的硬件。在启动完成的最后阶段,根文件系统可以重新mount到其他设备上。
二、是否必须
initrd文件不是必须的,但对于像红旗这样,需要具有适应在不同的硬件环境下使用的要求,那使用initrd会更方便。
我们常在编译核心的使用,使用make menuconfig,其中对某些而外的驱动,是可以选择
引用
1、把其全都编译到内核中,则只需要一个内核文件系统即可启动;
2、把其编译为模块,然后通过initrd虚拟的内存系统加载;
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
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]# 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]# 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 122464 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
[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 122464 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
#!/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。
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
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/
[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
[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
内文分页: [1] [2]
我这里是以常见的发行版形式描述的,这样好处理。