什麼是initrd
initrd 的英文含義是 boot loader initialized RAM disk,就是由 boot loader 初始化的內存盤。
在 linux內核啟動前, boot loader 會將存儲介質中的 initrd 文件加載到內存,內核啟動時會在訪問真正的根文件系統前先訪問該內存中的 initrd 文件系統。
在 boot loader 配置了 initrd 的情況下,內核啟動被分成了兩個階段,第一階段先執行 initrd 文件系統中的"某個文件",完成加載驅動模塊等任務,第二階段才會執行真正的根文件系統中的 /sbin/init 進程。
這裡提到的"某個文件",Linux2.6 內核會同以前版本內核的不同,所以這裡暫時使用了"某個文件"這個稱呼,後面會詳細講到。
第一階段啟動的目的是為第二階段的啟動掃清一切障愛,最主要的是 加載根文件系統存儲介質的驅動模塊。
initrd產生原因
要想明白initrd產生的原因,帶要從linux啟動說起。其實裝入本地linux系統時可以不用initrd,只要在kernel參數中加入root參數就可以了。
在boot loader如grub等裝入kernel後, kernel需要執行系統中的/sbin/init, 讀取這個文件就必須先mount根文件系統。 早期是通過啟動時的root=參數告訴內核根文件系統在哪個設備上。
隨著硬件和技術的發展,現在根文件系統可能位於一個網絡存儲如NFS上, 可能由於RAID而散布於多個設備上, 可能位於一個加密設備上需要提供用戶名和密碼,這時root=參數就顯得不夠了。
為了應付這種局面, 先後出現兩種機制來作為boot loader裝載kernel到真正的/sbin/init執行這個啟動過程的橋梁:initrd和initramfs。
兩者有類似的地方,比如都是由內核執行其上的某個程序(initrd是/linuxrc, initramfs是/init),由這個程序決定加載什麼驅動以及如何裝載根文件系統。
例如,把linux裝入U盤中時,就要用到initrd。這裡不是指把系統做成initrd直接加載成內存式linux,而是像本地硬盤上那樣是非鏡像型的linux系統。
為什麼必須要用initrd?我們可以從啟動過程來看。首先,由如GRUB的引導加載器加載內核,這時可以識別U盤,如果你是從U盤啟動的,那麼U盤為hd0。這一切都是GRUB可以識別U盤的存在。
當內核加載後情況就不一樣了,內核之中一般是沒有U盤驅動的,那它就 找不到U盤,更不用說U盤中的系統了。所以就要用initrd來加載U盤驅動,並執行系統中的/sbin/init。
initrd 的用途
1. linux 發行版的必備部件
linux 發行版必須適應各種不同的硬件架構,將所有的驅動編譯進內核是不現實的,initrd 技術是解決該問題的關鍵技術。Linux 發行版在內核中只編譯了基本的硬件驅動,在安裝過程中通過檢測系統硬件,生成包含安裝系統硬件驅動的 initrd,無非是一種即可行又靈活的解決方案。
2. livecd 的必備部件
同 linux 發行版相比,livecd 可能會面對更加復雜的硬件環境,所以也必須使用 initrd。
3. 制作 Linux usb 啟動盤必須使用 initrd
usb 設備是啟動比較慢的設備,從驅動加載到設備真正可用大概需要幾秒鐘時間。如果將 usb 驅動編譯進內核,內核通常不能成功訪問 usb 設備中的文件系統。因為在內核訪問 usb 設備時, usb 設備通常沒有初始化完畢。所以常規的做法是,在 initrd 中加載 usb 驅動,然後休眠幾秒中,等待 usb設備初始化完畢後再掛載 usb 設備中的文件系統。
4. 在 linuxrc 腳本中可以很方便地啟用個性化 bootsplash。