initrd的製作和解壓

initrd 的英文含義是 boot loader initialized RAM disk,就是由 boot loader 初始化的內存盤。在 linux內核啓動前,boot loader 會將存儲介質中的 initrd 文件加載到內存,內核啓動時會在訪問真正的根文件系統前先訪問該內存中的 initrd 文件系統。在 boot loader 配置了 initrd 的情況下,內核啓動被分成了兩個階段,第一階段先執行 initrd 文件系統中的"init or linuxrc",完成加載驅動模塊等任務,第二階段纔會執行真正的根文件系統中的 /sbin/init, Linux2.6既支持cpio-initrd,也支持image-initrd,但是cpio-initrd有着更大的優勢,在使用中我們應該優先 考慮使用cpio格式的initrd.

Initrd 的主要用途

linux 發行版必須適應各種不同的硬件架構,將所有的驅動編譯進內核是不現實的,initrd 技術是解決該問題的關鍵技術。Linux 發行版在內核中只編譯了基本的硬件驅動,在安裝過程中通過檢測系統硬件,生成包含安裝系統硬件驅動的 initrd,是一種即可行又靈活的解決方案。

 1.解壓 initrd
 # file initrd.`uname –r`.img (察看格式,不同的linux操作系統,這個文件格式也有不同,這個文件格式可能是cpio 也可能是ext2)
 如果是cpio格式 :

# mkdir /mnt/tmp # cd /mnt/tmp # cpio -idmv </tmp/initrd.`uname -r`.img

2 壓縮initrd

2.1 mkinitrd #cd /lib/modules/`uname -r` #mkinitrd /tmp/initrd.`uname -r`.img   `uname -r` #cd /tmp #mv initrd.`uname –r`.img initrd.`uname –r`.img.gz(initrd使用gzip壓縮,如果不改名字的話,後面無法解壓縮) #gunzip initrd.`uname -r`.img.gz

2.2 cpio

#假設當前目錄位於準備好的initrd文件系統的根目錄下

第一種方式,老的-c選項,用的是ascii碼備份方式. bash# find . | cpio -c -o > ../initrd.img bash# gzip ../initrd.img

第二種方式,新的.已經測試可用的方式.

#cd /root/busybox-1.15.3/rootfs9260 #find . | cpio -H newc -o > ../initrd_cpio.img #cd ../ #cp initrd_cpio.img initrd_cpio_bk.img -f #gzip initrd_cpio.img -f #/home/u-boot-1.1.5/tools/mkimage -A arm -T ramdisk -C none -O linux -a 0x600000 -e 0x600000 -d initrd_cpio.img.gz /home/ramdisk.uboot #ls /home/ramdisk.uboot -al 上面cpio命令的 -H 選項指定打包文件的具體格式,要生成initramfs,只能用newc 格式,如果使用其他格式,

內核會打出這樣的出錯信息:Unpacking initramfs...<0> kernel panic - not syncing: no cpio magic

或者出現:Unpacking initramfs...<0>Kernel panic - not syncing: bad gzip magic numbers 如果採用了-c舊的ascii碼備份方式,則內核會按照ramdisk的方式加載根文件系統。

如果你在編譯內核時選上了RAM block device support (在device drivers -> block devices裏),

也可以啓動成功,但這就失去了cpio-initrd的意義了!。

再就是注意cpio-initrd的初始進程是 “/init”,ramdisk方式初始進程是"/linuxrc"

另外如果採用cramfs格式的根文件系統,也需在編譯內核時選上RAM block device support


2.3  gen_init_cpio
獲取 gen_init_cpio,工具 ,gen_init_cpio是編譯內核時得到的,
在內核源代碼的 usr 目錄下,我們可以通過 以下步驟獲取它,進入內核源代碼 執行 :
# make menuconfig
# make usr/
這樣即編譯好gen_init_cpio,
gen_initramfs_list.sh 在內核源代碼的 script 目錄下,
將這兩個 文件 copy 到 /tmp 目錄下,/tmp/initrd 爲 解壓好的 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文件 然後 進行系統安裝。

3. 如何在 initrd 中添加新的驅動,以 ahci.ko 爲例

3.1 gen_init_cpio # cp initrd-‘uname –r‘.img /tmp/initrd;cd /tmp/initrd #cpio –ivdum < initrd-‘uname –r’.img; # mv initrd-‘uname –r’.img ../ #cd /tmp/initrd #vim init加上一行 insmod /lib/ahci.ko #cp ahci.ko lib/ #cd  /tmp # gen_initramfs_list.sh initrd/ > filelist # gen_init_cpio filelist >initrd.img # gzip initrd.img # mv initrd.img initrd-‘uname –r’.img

至此,新的initrd文件initrd-‘uname –r’.img中就包含了ahci的驅動程序了 ,這種方式是最簡單有效的。

 3.2 mkinitrd
(1) Add “alias scsi_hostadapter ahci” at /etc/modprobe.conf
(2) copy ahci.ko to “/lib/module/$(kernel-version)”/kernel/drivers/scsi”
(3) mkinitrd initrd.img ‘uname -r’
至此,新的initrd文件initrd-‘uname –r’.img中就包含了ahci的驅動程序了 .

#釋放cpio格式的initrd:        mv initrd.img imitrd.img.gz        gunzip initrd.img.gz        cpio -i --make-directories < initrd.img

#釋放centos6.2系統的initramfs.img

1."gunzip initrd.img-2.6.27-7-generic.gz",得到一個未壓縮的initrd.img-2.6.27-7-generic 2. cpio -iv < initrd.img-2.6.27-7-generic",提取成功

#製作cpio格式的initrd(新2012年使用過的)

#cd /root/busybox-1.15.3/rootfs9260
#find . | cpio -H newc -o > ../initrd_cpio.img

#製作cpio格式的initrd(2009年製作的LFS的方式):
dd if=/dev/zero of=/tmp/rootfs bs=1k count=35000
losetup /dev/loop0 /tmp/rootfs
mkfs.ext2 –F –i 2000 /tmp/rootfs
mkdir /tmp/loop
mount –o loop /tmp/rootfs /tmp/loop
#然後將剛纔建立的基本系統拷貝到/tmp/loop
cp /lfs/* /tmp/loop –arfp
find . | cpio –o –H newc | gzip –c > /tmp/initrd.img

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章