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 壓縮initrd2.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