天天看點

使用ramdisk初始化initrd

  

  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