Linux 的 initrd (linuxrc,init)

來源:互聯網
上載者:User
Linux 的 initrd (linuxrc,init)

摘自linux oracle百度空間  

Linux 的 initrd 技術是一個非常普遍使用的機制,linux2.6 核心的 initrd 的檔案格式由原來的檔案系統鏡像檔案轉變成了 cpio 格式,變化不僅反映在檔案格式上, linux 核心對這兩種格式的 initrd 的處理有著截然的不同。本文首先介紹了什麼是 initrd 技術,然後分別介紹了 Linux2.4 核心和 2.6 核心的 initrd 的處理流程。最後通過對 Linux2.6 核心的 initrd 處理部分代碼的分析,使讀者可以對
initrd 技術有一個全面的認識。為了更好的閱讀本文,要求讀者對 Linux 的 VFS 以及 initrd 有一個初步的瞭解。

 

1.什麼是 Initrd

initrd 的英文含義是 boot loader initialized RAM disk,就是由 boot loader 初始化的記憶體盤。在 linux核心啟動前, boot loader 會將儲存介質中的 initrd 檔案載入到記憶體,核心啟動時會在訪問真正的根檔案系統前先訪問該記憶體中的 initrd 檔案系統。在 boot loader 配置了 initrd 的情況下,核心啟動被分成了兩個階段,第一階段先執行 initrd 檔案系統中的"某個檔案",完成載入驅動模組等任務,第二階段才會執行真正的根檔案系統中的
/sbin/init 進程。這裡提到的"某個檔案",Linux2.6 核心會同以前版本核心的不同,所以這裡暫時使用了"某個檔案"這個稱呼,後面會詳細講到。第一階段啟動的目的是為第二階段的啟動掃清一切障愛,最主要的是 載入根檔案系統儲存介質的驅動模組。我們知道根檔案系統可以儲存在包括IDE、SCSI、USB在內的多種介質上,如果將這些裝置的驅動都編譯進核心,可 以想象核心會多麼龐大、臃腫。

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。


2.Linux2.4核心對 Initrd 的處理流程

為了使讀者清晰的瞭解Linux2.6核心initrd機制的變化,在重點介紹Linux2.6核心initrd之前,先對linux2.4核心的 initrd進行一個簡單的介紹。Linux2.4核心的initrd的格式是檔案系統鏡像檔案,本文將其稱為image-initrd,以區別後面介紹 的linux2.6核心的cpio格式的initrd。 linux2.4核心對initrd的處理流程如下:

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。 linux2.4 核心的 initrd 的執行是作為核心啟動的一個中間階段,也就是說 initrd 的 /linuxrc 執行以後,核心會繼續執行初始化代碼,我們後面會看到這是 linux2.4 核心同 2.6 核心的 initrd 處理流程的一個顯著區別。





3.Linux2.6 核心對 Initrd 的處理流程

linux2.6 核心支援兩種格式的 initrd,一種是前面第 3 部分介紹的 linux2.4 核心那種傳統格式的檔案系統鏡像-image-initrd,它的製作方法同 Linux2.4 核心的 initrd 一樣,其核心檔案就是 /linuxrc。另外一種格式的 initrd 是 cpio 格式的,這種格式的 initrd 從 linux2.5 起開始引入,使用 cpio 工具產生,其核心檔案不再是 /linuxrc,而是 /init,本文將這種
initrd 稱為 cpio-initrd。儘管 linux2.6 核心對 cpio-initrd和 image-initrd 這兩種格式的 initrd 均支援,但對其處理流程有著顯著的區別,下面分別介紹 linux2.6 核心對這兩種 initrd 的處理流程。

cpio-initrd 的處理流程

1. boot loader 把核心以及 initrd 檔案載入到記憶體的特定位置。

2. 核心判斷initrd的檔案格式,如果是cpio格式。

3. 將initrd的內容釋放到rootfs中。

4. 執行initrd中的/init檔案,執行到這一點,核心的工作全部結束,完全交給/init檔案處理。

image-initrd的處理流程

1. boot loader把核心以及initrd檔案載入到記憶體的特定位置。

2. 核心判斷initrd的檔案格式,如果不是cpio格式,將其作為image-initrd處理。

3. 核心將initrd的內容儲存在rootfs下的/initrd.image檔案中。

4. 核心將/initrd.image的內容讀入/dev/ram0裝置中,也就是讀入了一個記憶體盤中。

5. 接著核心以可讀寫的方式把/dev/ram0裝置掛載為原始的根檔案系統。

6. .如果/dev/ram0被指定為真正的根檔案系統,那麼核心跳至最後一步正常啟動。

7. 執行initrd上的/linuxrc檔案,linuxrc通常是一個指令檔,負責載入核心訪問根檔案系統必須的驅動, 以及載入根檔案系統。

8. /linuxrc執行完畢,常規根檔案系統被掛載

9. 如果常規根檔案系統存在/initrd目錄,那麼/dev/ram0將從/移動到/initrd。否則如果/initrd目錄不存在, /dev/ram0將被卸載。

10. 在常規根檔案系統上進行正常啟動過程 ,執行/sbin/init。

通過上面的流程介紹可知,Linux2.6核心對image-initrd的處理流程同linux2.4核心相比並沒有顯著的變化, cpio-initrd的處理流程相比於image-initrd的處理流程卻有很大的區別,流程非常簡單,在後面的原始碼分析中,讀者更能體會到處理的 簡捷。

4.cpio-initrd同image-initrd的區別與優勢

沒有找到正式的關於cpio-initrd同image-initrd對比的文獻,根據筆者的使用體驗以及核心代碼的分析,總結出如下三方面的區別,這些區別也正是cpio-initrd的優勢所在:

cpio-initrd的製作方法更加簡單

cpio-initrd的製作非常簡單,通過兩個命令就可以完成整個製作過程

#假設目前的目錄位於準備好的initrd檔案系統的根目錄下bash# find . | cpio -c -o > ../initrd.imgbash# gzip ../initrd.img


而傳統initrd的製作過程比較繁瑣,需要如下六個步驟

#假設目前的目錄位於準備好的initrd檔案系統的根目錄下bash# dd if=/dev/zero of=../initrd.img bs=512k count=5bash# mkfs.ext2 -F -m0 ../initrd.imgbash# mount -t ext2 -o loop ../initrd.img   /mntbash# cp -r   * /mntbash# umount /mntbash# gzip -9 ../initrd.img


本文不對上面命令的含義作細節的解釋,因為本文主要介紹的是linux核心對initrd的處理,對上面命令不理解的讀者可以參考相關文檔。

cpio-initrd的核心處理流程更加簡化

通過上面initrd處理流程的介紹,cpio-initrd的處理流程顯得格外簡單,通過對比可知cpio-initrd的處理流程在如下兩個方面得到了簡化:

1. cpio-initrd並沒有使用額外的ramdisk,而是將其內容輸入到rootfs中,其實rootfs本身也是一個基於記憶體的檔案系統。這樣就省掉了ramdisk的掛載、卸載等步驟。

2. cpio-initrd啟動完/init進程,核心的任務就結束了,剩下的工作完全交給/init處理;而對於image-initrd,核心在執行完 /linuxrc進程後,還要進行一些收尾工作,並且要負責執行真正的根檔案系統的/sbin/init。通過圖1可以更加清晰的看出處理流程的區別:


圖1核心對cpio-initrd和image-initrd處理流程

cpio-initrd的職責更加重要

1所示,cpio-initrd不再象image-initrd那樣作為linux核心啟動的一個中間步驟,而是作為核心啟動的終點,核心將控 制權交給cpio-initrd的/init檔案後,核心的任務就結束了,所以在/init檔案中,我們可以做更多的工作,而不比擔心同核心後續處理的銜 接問題。當然目前linux發行版的cpio-initrd的/init檔案的內容還沒有本質的改變,但是相信initrd職責的增加一定是一個趨勢。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.