initrd提供了在boot loader下加載ram disk的方法。該ram disk可以被作為根檔案系統挂載進來,裡面的程式也可以運作。然後,新的根檔案系統可以從其他裝置挂載。之前的根(來自initrd)可以被轉移到一個目錄然後被解除安裝。
initrd主要設計用來使系統啟動于兩個條件,一個是核心來自于非常小的驅動器,一個是額外的子產品需要從initrd中加載。
本文給出initrd的概要描述,更具體的可以參考[1]。
操作
-------
當使用initrd,典型的系統啟動順序如下:
1. boot loader加載核心并初始化ram disk
2. 核心把initrd轉化成正常的ram disk并釋放initrd使用的記憶體
3. initrd作為root被挂載,賦予讀寫權限。
4. /linuxrc被執行(這可以是任何可執行檔案,如腳本,運作在uid 0,可以做任何初始化)。
5. linuxrc挂載真正的根檔案系統
6. linuxrc使用pivot_root系統調用把根檔案系統放在根目錄。
7. 正常的啟動序列(/sbin/init)在根檔案系統上執行。
8. initrd檔案系統被移去。
注意,改變根目錄不牽扯解除安裝他。
挂載在initrd的檔案系統仍然可以被通路。
啟動指令選項
------------------------
initrd添加了如下新的選項:
initrd=
(e.g. LOADLIN)
加載特定的檔案作為初始的ram disk。當使用lilo,你應該在/etc/lilo.conf中指定
ram disk鏡像檔案位置,使用INITRD變量。
noinitrd
initrd資料被保留卻不轉化成ram disk,正常的根檔案系統被加載。initrd的資料可以 從/dev/initrd中讀取。注意,在initrd中的資料可以是任意結構的,不一定要是檔案系統鏡像。該選項多用于調試。
注意:/dev/initrd是隻讀的,而且隻能被使用一次。隻要最後一個程序關閉它,所有的資料将會釋放掉,而/dev/initrd将不再被打開。
root=/dev/ram0 (without devfs)
root=/dev/rd/0 (with devfs)
initrd作為根檔案系統被挂載,随後正常的啟動順序中,ram disk仍然作為root。
安裝
------------
首先,用于initrd檔案系統的目錄在根檔案系統上被建立:
# mkdir /initrd
名字不是很重要。更多的可以參考pivot_root(2)的man。
在啟動過程中,如果根檔案系統被建立(如果你有軟碟啟動),那麼根檔案系統應該建立/initrd目錄。
如果initrd沒有被挂載,他裡面的内容仍然可以被通路,通過以下的方法(注意,這在使用devfs時不可用):
# mknod /dev/initrd b 1 250
# chmod 400 /dev/initrd
第二步,核心編譯的時候必須支援ram disk并啟動ram disk使能。所有從initrd中執行的程式必須被編譯到核心中。
第三步,你必須建立ram disk鏡像。這可以通過在塊裝置上建立檔案系統實作,把所需的檔案拷貝,然後把檔案拷貝到initrd檔案。根據最新的核心,至少三種裝置可以用:
l 軟碟(慢,卻随處可用)
l ram disk(快,需要實體記憶體)
l loopback device(最高檔)
我将介紹 loopback device方法:
保證loopback device被核心支援
建立一個空的檔案系統,擁有合适的大小:
# dd if=/dev/zero of=initrd bs=300k count=1
# mke2fs -F -m0 initrd
如果空間不多,你可以用minix fs而不是ext2
挂載檔案系統
# mount -t ext2 -o loop initrd /mnt
建立控制台裝置(如果用devfs,就沒必要)
# mkdir /mnt/dev
# mknod /mnt/dev/console c 5 1
拷貝initrd環境需要的所有檔案。不要忘掉最重要的檔案/linuxrc.
注意,/linuxrc必須有執行權限。
正确的initrd環境可以不用重新開機就可以通過指令行測試:
# chroot /mnt /linuxrc
解除安裝檔案系統
# umount /mnt
現在initrd被儲存在initrd檔案中。還可以壓縮他。
# gzip -9 initrd
為了試驗initrd,你可以建立一個急救盤,隻需建立/linuxrc到/bin/sh的符号連結。
你還可以試着把initrd更小。
最後,你要啟動核心并加載initrd.幾乎所有的boot loader都支援initrd.
雖然啟動程序相容老的機制,下面的啟動指令行還是得給出:
root=/dev/ram0 init=/linuxrc rw如果不使用devfs.或者
root=/dev/rd/0 init=/linuxrc rw
如果使用devfs.
使用 LOADLIN,隻要執行
LOADLIN initrd=
e.g. LOADLIN C:/LINUX/BZIMAGE initrd=C:/LINUX/INITRD.GZ root=/dev/ram0
init=/linuxrc rw
使用LILO,你添加選項INITRD=
到/etc/lilo.conf中,使用APPEDN指令即可。
image = /bzImage
initrd = /boot/initrd.gz
append = "root=/dev/ram0 init=/linuxrc rw"
然後運作 /sbin/lilo
對于其他的啟動程式,請參考相應的文檔。
現在你可以啟動并享受使用initrd的樂趣了
如何改變根裝置
------------------
當完成他的任務,linuxrc改變根裝置并啟動真正的根裝置。
整個過程包括如下幾步:
1. 挂載新的根檔案系統
2. 把他變成根檔案系統
3. 删除所有對舊(Initrd)檔案系統的通路
4. 解除安裝initrd檔案系統,重定位ram disk
挂載新的根檔案系統很容易:隻需把他挂載到目前根下。例如:
# mkdir /new-root
# mount -o ro /dev/hda1 /new-root
根的轉變伴随着pivot_root系統調用。pivot_root把目前的根轉移到新根下的一個目錄,并把新的根放到原來的地方。老根的目錄必須在調用pivot_root前退出。例如:
# cd /new-root
# mkdir initrd
# pivot_root . initrd
現在,linuxrc程序可以仍然通路老的根。所有的這些引用可以通過如下指令釋放:
# exec chroot . what-follows dev/console 2>&1
然後執行的就是新根下的,例如/sbin/init.
如果新的根檔案系統使用devfs,而/dev目錄還不可用,devfs必須被挂載進來,
在使用chroot之前,隻有這樣才有/dev/console裝置。
注意:privot_root執行的情況可能有所不同。為了保證相容性,注意以下幾點:調用pivot_root之前,調用程序的目前目錄應指向新的根檔案目錄使用.作為第一個參數,老根的相對路徑作為第二個參數。chroot程式必須在就老的和新的根下都可以使用。最後改變根到新的根下。在執行指令中使用dev/console的相對路徑。
注意,initrd可以被解除安裝,而ram disk使用的記憶體可以被釋放:
# umount /initrd
# blockdev --flushbufs /dev/ram0 # /dev/rd/0 if using devfs
initrd還可以使用NFS-mounted根,參考man pivot_root(8)。
注意:如果linuxrc或者其他程式從終端執行,老的改變根機制必須調用。
使用限制
-----------
引入initrd的主要動機是為了在系統安裝中可以子產品化配置核心。過程運作如下:
1. 一個小核心的系統從軟碟或其他媒體上啟動(支援ram disk,initrd,a.out, ext2fs),并加載initrd。
2. /linuxrc決定如何挂載真正的根檔案系統(裝置類型,裝置驅動,檔案系統),并分布媒體(CDROM,network,tape)。這些可以詢問使用者或者自動探測,或是混合使用。
3. /linuxrc加載必須的核心子產品
4. /linuxrc建立并組裝根檔案系統(還不一定能用)。
5. /linuxrc調用pivot_root改變根檔案系統,執行(chroot)安裝程式.
6. boot loader 安裝完畢
boot loader配置用于加載initrd,initrd中包含系統啟動的必須子產品。
現在系統可以啟動的,額外的安裝任務被執行。
initrd的主要任務是在正常的系統操作中複用配置資料,而不需重新編譯連結核心。
第二個限制是在linux運作在不同的硬體配置上的安裝問題。這種情況下,隻需産生一個小核心,分别配置。initrd中必須含有所有需要的子產品。然後,/linuxrc或其他一個檔案可能有所不同。
第三個限制更友善恢複磁盤,因為象根檔案系統分區的資訊在系統啟動的時候要用,而在啟動時刻是得不到的。
最後,CDROM釋出使他更友善安裝。
荒廢的根改變機制
----------------
下面的機制在pivot_root之前被使用。目前的核心仍然支援他,但是你不要依賴他。
他在linuxrc存在的情況下,把真正的根裝置作為根檔案系統。initrd檔案系統然後被
解除安裝,或者把他移動到/initrd目錄,如果這個目錄存在于新的根檔案系統。
為了使用這種機制,你不必設定啟動參數root,init,rw(如果設定了,這将影響到真正的
根檔案系統)。
本文轉自
http://blog.21ic.com/user1/1066/archives/2005/2331.html