linux中的rootfs/initrd/ramfs/initramfs

weixin_33912246發表於2016-07-29

什麼是ramfs?
ramfs是空間規模動態變化的RAM檔案系統。它非常簡單,是用來實現Linux快取機制(快取page cache and dentry cache)的檔案系統
通常情況下,Linux的所有檔案在記憶體中都有快取。需要讀取的資料頁從支撐儲存裝置(block device)中讀取後,快取於記憶體。在支撐儲存裝置中的資料頁執行marked as clean操作。當虛擬檔案系統需要支撐儲存裝置中的資料頁記憶體時,可以釋放。基於同樣的機制,支撐儲存裝置的寫入操作(寫入檔案然後寫回支撐儲存裝置,marked as clean)後,也可以釋放佔用的資料頁記憶體。對於檔案目錄佔用的快取(dentry: directory entry),也存在同樣的機制。
但是,ramfs中不需要支撐儲存裝置(沒有支撐快取,但是有快取)。也就是說,寫入ramfs的檔案可以正常的分配page cache and dentry cache,但是不能寫入支撐儲存裝置。這些page cache and dentry cache不能被VM釋放、回收。
由於ramfs可以基於現有的Linux的檔案系統結構,用於實現ramfs的程式碼很小。一般而言,支撐儲存裝置的快取被安裝為一個檔案系統。所以,ramfs不能通過menuconfig選擇,是必然進入核心的。
在ramfs的下面可以一直寫入資料,直到寫滿記憶體為止。由於VM(Vitual Memory)認為檔案應該被寫回支撐儲存裝置,而不是交換空間(swap space),所以VM不能釋放ramfs分配的記憶體。從而,只有root使用者(or trusted user)才能進行ramfs寫操作。
-------------------------------------------------------------------------------
什麼是ram disk?
"ram disk"是一種實現檔案系統的支撐儲存(塊裝置)的、過時的機制(2.6不用了),就是在RAM上面開闢的綜合塊裝置(synthetic block device)。ram disk的大小是固定的,安裝的檔案系統大小(不是ramfs)也是固定的。ram disk的使用需要從這個假的塊裝置到page cache之間拷貝記憶體,生成和銷燬dentry,而且需要檔案系統的驅動格式化和解釋上面的資料,所以ram disk的機制不再使用。
與ramfs相比,ram disk浪費了記憶體,也浪費了記憶體匯流排的頻寬。同時,ram disk還為CPU加重了不必要的負擔,汙染了CPU的cache(儘管有避免汙染的方法,但是非常耗費資源)。ramfs機制非常自然,因為檔案訪問可以通過page cache and dentry cache。ram disk被棄用的另外一個原因是環回裝置(loopback)引入。環回裝置提供了一種更加靈活、方便的從檔案而不是從記憶體塊中建立綜合塊裝置的方法。
-------------------------------------------------------------------------------
什麼是tmpfs?
tmpfs是ramfs的衍生物,用來限制快取大小、向swap空間寫入資料。它是用來儲存VM所有檔案的檔案系統。tmpfs中快取的內容全部是臨時的。一旦解除安裝,所有的內容都會遺失。它把所有的快取置於核心,它的規模隨著檔案的規模同步變化。但是它規模有大小限制,可以修改。它可以把當前不再需要的頁寫入到swap空間。
-------------------------------------------------------------------------------
什麼是rootfs?
rootfs是ramfs的特殊例項,在2.6的核心中必然存在。rootfs不能被解除安裝(與其新增特殊程式碼用來維護空的連結串列,不如把rootfs節點始終加入,因此便於kernel維護:簡單、精煉。rootfs是ramfs的一個空例項,佔用空間極小)。大部分其他的檔案系統安裝於rootfs之上
-------------------------------------------------------------------------------
什麼是initramfs?
2.6的Linux核心包含有gzip壓縮的cpio格式的文件,可以在核心引導的時候解壓縮為rootfs。在解壓縮後,kernel將檢查rootfs中是否包含init檔案。如果init檔案存在,核心就會執行這個檔案,並且賦予PID=1的程式號。這個init程式將整個系統引導起來,包括定位並且安裝真正的root裝置。如果在cpio文件解壓縮後的rootfs中沒有init程式(init檔案),核心執行舊的程式碼,定位並且安裝root分割槽,執行/sbin/init程式。
-------------------------------------------------------------------------------
initramfs與initrd的區別
1. initrd是一個單獨的檔案;initramfs和Linux核心連結在一起(/usr目錄下的程式負責生成initramfs文件)。
2. initrd是一個壓縮的檔案系統映像(可以是ext2等,需要核心的驅動);initramfs是類似tar的cpio壓縮文件。核心中的cpio解壓縮程式碼很小,而且init資料在boot後可以丟棄。
3. initrd執行的程式(initd,不是init)進行部分setup後返回核心;initramfs執行的init程式不返回核心(如果/init需要向核心傳遞控制權,可以再次安裝在/目錄下一個新的root裝置並且啟動一個新的init程式)。
4. 切換到另一個root裝置時,initrd執行pivot_root後,解除安裝ramdisk;initramfs是rootfs,既不能pivot_root,也不能解除安裝。
initramfs會刪掉rootfs的所有內容(find -xdev / -exec rm '{}' ';'),再次安裝root到rootfs(cd /newmount; mount --move . /; chroot .),把stdin/sdout/stderr掛在新的/dev/console上,重新執行init。由於這是一個相當困難的實現過程(包括在使用一個命令之前把它刪除),所以klibc工具包引入一個幫助程式/utils/run_init.c來執行上述過程。其他大部分工具包(包括busybox)把這個命令稱為"switch_root"。
-------------------------------------------------------------------------------

initial RAM disk

  Linux初始 RAM磁碟(initrd)是在系統引導過程中掛載的一個臨時根檔案系統,用來支援兩階段的引導過程。initrd檔案中包含了各種可執行程式和驅動程式,它們可以用來掛載實際的根檔案系統,然後再將這個 initrd RAM 磁碟解除安裝,並釋放記憶體。在很多嵌入式Linux 系統中,initrd 就是最終的根檔案系統。

-------------------------------------------------------------------------------
Populating initramfs
2.6的核心預設情況下總是生成一個gzipped的cpio文件,並且和核心連結在一起。這個文件預設是空的,在X86環境下的大小是134位元組。
CONFIG_INITRAMFS_SOURCE配製引數指定initramfs文件的源,並且自動的嵌入到二進位制檔案中。這個引數可以指向一個gzipped的cpio文件,一個包含檔案的目錄,或者檔案描述的文字檔案。例如文字檔案:
   dir /dev 755 0 0
   nod /dev/console 644 0 0 c 5 1
   nod /dev/loop0 644 0 0 b 7 0
   dir /bin 755 1000 1000
   slink /bin/sh busybox 777 0 0
   file /bin/busybox initramfs/busybox 755 0 0
   dir /proc 755 0 0
   dir /sys 755 0 0
   dir /mnt 755 0 0
   file /init initramfs/init.sh 755 0 0
在核心編譯完成後,可以執行/usr/gen_init_cpio命令獲得cpio文件。配置檔案的一個優勢是不需要root許可權,也不需要在新的文件中生成裝置節點。在上述文件中的兩個file命令用來發現initramfs目錄下面的init.sh檔案和busybox檔案。核心不需要外部的cpio工具實現initramfs的cpio文件。如果在配置時指定了一個目錄而不是一個描述檔案,核心編譯時將從這個目錄生成一個描述檔案(作為/usr/gen_init_cpio.c的輸入)。核心編譯時cpio生成程式碼和核心渾然一體,boot時解壓縮程式也和核心渾然一體。
如果不使用配置檔案或者配置目錄,而使用定製的cpio文件時,需要外部的cpio工具。例如下面的命令可以從cpio映像檔案抽取包含的檔案、壓縮cpio映像檔案:
    cpio -i -d -H newc -F initramfs_data.cpio --no-absolute-filenames   
下面的shell指令碼可以生成一個定製的cpio.gz文件,可以用來代替配置檔案生成的cpio文件:
   #!/bin/sh
   if [ $# -ne 2 ]
   then
     echo "usage: mkinitramfs directory imagename.cpio.gz"
     exit 1
   fi
   if [ -d "$1" ]
   then
     echo "creating $2 from $1"
     (cd "$1"; find . | cpio -o -H newc | gzip) > "$2"
   else
     echo "First argument must be a directory"
     exit 1
   fi

相關文章