或許你要問:為什么要拆解和定制initrd.img?我無法給你一個明確的答案。
可能的答案有:
--出于天生的好奇,我想知道它里面究竟裝有什么東西?
--對于擁有較新款設備的人,重新編譯內核后,可能系統用新內核無法啟動了?
--用一些軟件網絡安裝linux操作系統時(如用SystemImager),新安裝的機器無法啟動(我就遇到這個問題)
--其它原因添加中......
從拆解到定制自己的"initrd.img" ----Kevin Zeng
或許你要問:為什么要拆解和定制initrd.img?我無法給你一個明確的答案。
可能的答案有:
--出于天生的好奇,我想知道它里面究竟裝有什么東西?
--對于擁有較新款設備的人,重新編譯內核后,可能系統用新內核無法啟動了?
--用一些軟件網絡安裝linux操作系統時(如用SystemImager),新安裝的機器無法啟動(我就遇到這個問題)
--添加中......
--------------------------------------------------
我是個新手,深知初學者的不宜,所以盡量寫一些基本的東西。有些東西寫得可能不夠精煉,還望諒解。
所有文中的東西都是在實際中遇到過和自己的理解,寫到這里和大家分享與交流!
如果對本文有任何意見和要進行討論,請mailto: kevin[dot]zsc[at]gmail.com
--------------------------------------------------
1. 什么是initrd.img,它有什么用?
initrd.img是Linux啟動過程中很重要的一個文件,如果你編譯內核時將一部分功能編譯為可加載模塊。如果系統的一些設備的驅動編譯為可加載模,那么啟動時如果沒有指定INITRD=/path_to_initrd.img,那么系統啟動或者會失敗,或者啟動后會有設備無法使用(像網卡或者其它設備)。
比如我的Dell Precision 470 計算機的Adaptec HostRaid 39320B SCSI控制卡驅動就編為可加載模塊,如果沒指定initrd.img或者指定的initrd.img中并沒有包含正確的驅動模塊(有些硬件很多系列的驅動都是一個名稱,像Adaptec 的一系列Ultra320卡用的驅動模塊名稱都是aic79xx.o,但當前很多2.4版本內核模塊中并不支持較新的39320B驅動),則系統啟動時會掛起,并報告"kernel panic: VFS: Unable to mount root fs on 08:06"的錯誤。
2. 拆解initrd.img
很慶幸initrd.img可以進行拆解,或許這正是設計者高明所在。initrd.img不像通常的以.img為擴展名的ramdisk cramfs文件。它是經過用gzip -9進行壓縮過的ramdisk文件。所以,如果直接用#mount initrd.img /temppath -o loop不能mount上,會報告你指定一個文件類型。 所以我拆解它的過程要先將其進行解壓縮,然后再mount。下面是我的操作過程,可能有些命令用加些參數的方式更簡捷,當我知道后會進行更新。
#cd 假設已經到你的initrd.img文件所在目錄(最好先將其備份一個)
#mv initrd.img initrd.gz <--在我的RHEL AS3 U3 /bsh下,不做這一步的話,用gunzip解壓時會報告擴展名不對
#gunzip initrd.gz /tmp/initrd <--解壓后會生成一個不帶擴展名的initrd文件
#mkdir /mnt/tmp
#mv /tmp/initrd /tmp/initrd.img <--將解壓出的initrd文件加個.img的擴展名,在我的RHEL AS3 U3 下不做這一步,mount時會出錯
#mount /tmp/initrd.img /mnt/tmp -o loop <--mount成功后,/mnt/tmp目錄中將能看到initrd.img中的所有文件及目錄
#cp -a /mnt/tmp/* /tmp/initrd.new <--拷貝一份方便編輯
#umount /mnt/tmp
#cd /tmp/initrd.new
切換到/tmp/initrd.new目錄后,你可以按需要進行編輯。比如更新一些設備驅動模塊,或者對其中的一些啟動過程中會執行的shell script進行修改。
所有想要的修改完成后,進行打包生成新的initrd.img文件。方法如下:
#mkcramfs /tmp/initrd.new /tmp/newinitrd
#gzip -9 /tmp/newinitrd /tmp/newinitrd.gz
#mv /tmp/newinitrd.gz /tmp/initrd.img
上面的目錄可以根據需要進行更改。如果在gnome下,有些解壓縮、改名、復制可以直接用右鍵彈出菜單完成。
3. 定制自已的initrd.img
我修改initrd.img的起因還是歸于用的那臺Dell precision 470 及要用OSCAR4.1組建一個linux cluster(正在進行中,尚未完成)。OSCAR4.1包中所用的SystemImager3.2.2-1帶的用于網絡引導客戶機的BOEL-kernel-2.4.25和initrd.img不支持Dell precision 470的Adaptec39320B HostRaid Control Card。此外,在上面裝RedHat 9.0后進行內核重編譯時,可能因為mkinitrd或者9.0內核版本的原因,生成的img文件無法使用。在此以我實際遇到的問題,主要講講更新initrd.img中的硬件驅動模塊的方法,拋磚引玉。
模塊跟kernel的版本相關,直接的用其它支持你硬件但kernel版本不同的模塊進行替換通常不會成功,所以最好到kernel.org上下載所需要的kernel版本的源程序包。我解決我上面的問題的文法就是下載了Linux-2.4.25.tar.gz源程序,并解壓到/usr/src目錄,之后到adaptec.com網站下載到支持39320B HostRaid的適合linux-2.4版的驅動源程序,并解壓替換2.4.25內核源程序中的驅動程序源代碼。之后對內核進行重新編譯(在本文不詳述具體方法,網上有很多相關資料,或許有時間我會寫一篇),用make menuconfig時最好直接選上隨著原來kernel & initrd.img在一起的config文件。如果不出錯,執行make modules_install后就生成了需要的模塊(通常在目錄/lib/modules/kernel-version)。 之后我用新的/lib/modules/kernel-version/lib/下的modules目錄及其文件替換掉舊的initrd.img中的modules目錄(當然先得拆解之,方法見第2部分)。
當然initrd.img可修改的部分還有很多,但在此只以自已實際做過的部分進行說明。
如果你有好的方法修改initrd.img的案例,不妨發給我(kevin[dot]zsc[at]gmail.com),我將不斷完善本文。