Ads 468x60px

##EasyReadMore##

13 11月, 2017

ramfs、tmpfs、rootfs、ramdisk 介紹

「ramfs、tmpfs、rootfs、ramdisk」的圖片搜尋結果

第一部分:ramfs、tmpfs、rootfs、ramdisk

一、 什麼是ramfs?

1. linux緩存機制
VFS(虛擬文件系統)層屏蔽了各種真實文件系統的特性,提供給linux上層統一的接口。
通常,linux對所有文件的讀寫都會在內存在做高速緩存,當系統再次使用這些文件時,可以直接從內存中讀取,以提高系統的I/O性能。當高速緩存中的文件被修改或者有數據寫入高速緩存時,系統會在適當的時候將這些高速緩存中的數據回寫到對應的文件系統設備(如磁盤、flash等)中去,那麼這之後這些高速緩存的狀態就被標識為clean(可用),這樣就相當於告訴了系統:這些高速緩存中的數據文件系統設備上有備份,你可以拿去另作他用。但其中的數據會保持到VMS(Virtual Memory System)將這些高速緩存回收重新分配。
類似於頁緩存機制,目錄緩存機制也極大地加快了對目錄的訪問。

2. ramfs
ramfs是一種非常簡單的文件系統,它直接利用linux內核已有的高速緩存機制(所以其實現代碼很小,也由於這個原因,ramfs特性不能通過內核配置參數屏蔽,它是內核的天然屬性),使用系統的物理內存,做成一個大小可以動態變化的的基於內存的文件系統。
ramfs工作於虛擬文件系統層(VFS)層,不能被格式化,可以創建多個,默認情況下,ramfs最多能用到內存的一半,必要時也可以使用-o maxsize = 10000(單位是KB)來更改使用的最大內存量。
ramfs沒有對應的文件系統設備,文件被寫入ramfs和其他文件系統一樣都正常分配頁緩存和目錄緩存,但是卻不可能想其他有存儲設備的文件系統一樣將高速緩存中的文件回寫到存儲設備。這就意味著這些為ramfs中的文件和目錄分配的高速頁或者目錄緩存都不可能會被標記為clean(可用)狀態,所以系統就永遠不會釋放ramfs所佔用的內存。正因為可以在ramfs下面可以一直往裡寫數據,直到寫滿為止,所以這種操作只有root(or trusted user)用戶才可以進行ramfs寫操作。
為了解決ramfs的缺點(沒有回寫設備)導致的種種問題,所以衍生出了tmpfs文件系統。

二、 什麼是tmpfs?

image
tmpfs是ramfs的衍生物,在ramfs的基礎上增加了容量大小的限制和允許向交換
空間(swap) 寫入數據。由於增加了這兩個特性,所以普通用戶也可以使用tmpfs。
tmpfs是一種虛擬內存文件系統,它不同於傳統的用塊設備形式來實現的ramdisk,也不同於針對物理內存的ramfs。tmpfs既可以使用物理內存,也可以使用交換分區。在linux內核中,虛擬內存資源由物理內存和交換分區組成,這些資源由內核中的虛擬內存子系統來負責管理。tmpfs就是和虛擬內存子系統打交道的,它向虛擬內存子系統請求頁來存儲文件,同linux的其他請求頁的部分一樣,不知道分配給自己的頁是在內存中還是在交換分區中。也就是說tmpfs使用的是虛擬內存,而ramfs使用物理內存。另外tmpfs和ramfs一樣,不可以被格式化,同時大小也是不固定的,可以使用-o size =32m或者(1g)來修改。
另外,tmpfs可以將當前不需要使用的頁寫入到交換空間。同時由於其使用的虛擬內存,所以tmpfs一旦被卸載,其中的數據都會丟失。
如果需要使用tmpfs,在內核編譯的時候得選擇上:
Virtual memory filesystem support
ramfs只會在物理內存中被創建,而tmpfs可能在物理內存中創建,也可能在交換 分區中創建。對於想利用內存的高速IO來提高效能的應用,最好是使用ramfs。對於只是想存放臨時緩存的應用,最好使用tmpfs,以提高內存的使用率。

三、 什麼是rootfs?

image
rootfs是一個特定的ramfs(或tmpfs,如果tmpfs被啟用)的實例,它始終存在於linux2.6的系統中。在嵌入式系統中,並不像PC 有著大容量硬碟存在,需利用Ramdisk 模擬的方法執行系統。
Ramdisk 是利用既有的RAM 或Flash,模擬一段磁碟空間,放置Root File System 供程式執行用。

四、 什麼是ramdisk?

linux2.6版本之後都不在使用ramdisk了,2.4中還在使用。一般嵌入式系統當中通常沒有硬碟的存在,但是有作業系統就會需要檔案系統。 因此嵌入式系統會從記憶體裡面分出一塊區域,來做為檔案系統之用,可動態調整大小,這個區域就叫Ramdisk。

對於用戶來說,可以把ramdisk與通常的硬盤分區同等對待來使用。ramdisk不適合作為長期保存文件的介質,掉電後ramdisk的內容會消失。
為了能夠使用ramdisk 你的內核必須要支持ramdisk,即:在編譯內核時,要選中RAM disk support這一選項,會在配置文件中定義CONFIG_BLK_DEV_RAM。同時為了讓內核有能力在內核加載階段就能裝入ramdisk,並運行其中的內容,要選中initial RAM disk(initrd) support 選項,會在配置文件中定義CONFIG_BLK_DEV_INITRD。
ramdisk的大小是固定的,安裝在其上的文件系統大小也是固定的。ramdisk在使用的時候,這個假的塊設備和高速緩存(頁緩存和目錄緩存)之間有數據的拷貝,而且它還需要文件系統的驅動來格式化和解釋這些數據。所以,使用ramdisk不僅浪費了內存,還加重了cpu的負擔,同時也無污染了cache,而且其所有的文件和目錄都要通過頁和目錄緩存進行訪問,這些工作ramfs都要執行的,那麼ramdisk就可以完全不需要。這是廢棄ramdisk的理由之一。

ramdisk 要被放棄的另一個原因是,loopback (註1)設備的引入。

loopback 設備提供了更加 靈活、方便的建立人工區塊設備的方法,該方法把用檔案的來實現設備,而不再是大量的的內存來創建一個合成塊設備。

可以看到 grub 把 image-full-quark.ext3

image

透過 loopback 方式掛載到 /

image

第二部分:initrd、initramfs

一、 initrd出現的背景

在早期的linux系統中,一般只有硬盤或者軟盤被用來作為linux根文件系統的存儲設備,因此也就很容易把這些設備的驅動程序集成到內核中。但是現在的嵌入式系統中可能將根文件系統保存到各種存儲設備上,包括scsi、sata,u-disk等等。因此把這些設備的驅動代碼全部編譯到內核中顯然就不是很方便。
在內核模塊自動加載機制udev中,我們看到利用udevd可以實現內核模塊的自動加載,因此我們希望如果存儲根文件系統的存儲設備的驅動程序也能夠實現自動加載,那就好了。但是這裡有一個矛盾,udevd是一個可執行文件,在根文件系統被掛載前,是不可能執行udevd的,但是如果udevd沒有啟動,那就無法自動加載存儲根文件系統設備的驅動程序,同時也無法在/dev目錄下建立相應的設備節點。
為了解決這一矛盾,於是出現了基於ramdisk的initrd( bootloader initialized RAM disk )。下圖為 grub 的內容

image

Initrd是一個被壓縮過的小型根目錄,這個目錄中包含了啟動階段中必須的驅動模塊,可執行文件和啟動腳本,也包括上面提到的udevd(實現udev機制的demon)。當系統啟動的時候,bootloader會把initrd文件讀到內存中,然後把initrd文件在內存中的起始地址和大小傳遞給內核。內核在啟動初始化過程中會解壓縮initrd文件,然後將解壓後的initrd掛載為根目錄,然後執行根目錄中的/init腳本(cpio格式的initrd為/init,而image格式的initrd<也稱老式塊設備的initrd或傳統的文件鏡像格式的initrd>為/initrc),

image

image

您就可以在這個腳本中運行initrd文件系統中的udevd,讓它來自動加載realfs(真實文件系統)存放設備的驅動程序以及在/dev目錄下建立必要的設備節點。

image

在udevd自動加載磁盤驅動程序之後,就可以mount真正的根目錄,並切換到這個根目錄中來。
這裡只是個簡單的描述,後面慢慢分析吧。

建立 root filesystem image 空間的三種方式
------------------------------
root filesystem 就是我們在登入 linux 後,所看到的檔案系統。
我們平時使用的工具,就放在其中。
如果我們光只是啟動了 Linux,卻沒有 root filesystem,那什麼事都無法做。
就好像電腦中安裝了Win95/98,卻不小心把 C:\Windows 給刪除了一樣。

在介紹initrd的製作之前,先瞭解下面的幾個命令作用:
dd:用指定大小的塊拷貝一個文件,並在拷貝的同時進行指定的轉換。
1. if=文件名:輸入文件名,缺省為標準輸入。即指定源文件。< if=input file >
注意/dev/zero設備,這個設備是可以源源不斷地提供0的設備,用來初始化
2. of=文件名:輸出文件名,缺省為標準輸出。即指定目的文件。< of=output file >
3.bs=bytes:同時設置讀入/輸出的塊大小為bytes個字節。
4. count=blocks:僅拷貝blocks個塊,塊大小等於ibs指定的字節數。
還有其他更詳細的參數用法參考:dd命令-詳解

1.選擇一個設備空間

(a) ramdisk

建立 ramdisk 空間的方式,是用 dd 指令,填入指定大小的內容後, 就會在 ram 中保留該大小的空間;
而這個 ram 空間,就連接到 dd 指 令中,所指定的設備名稱,如 /dev/ram0。

$ dd if=/dev/zero of=/dev/ram0 bs=1k count=4096

上面這指令的意義是,從輸入設備 /dev/zero 中,以 bs 指定的大小(1k), 讀取資料,輸出到設備 /dev/ram0 中,
重覆輸出入 count 指定的次數(4096次),這表示 /dev/ram0 所連接的 ram 空間,會有 4096K 的空間可用。
/dev/zero 是一個特殊的設備,從這個設備中,讀取的內容,全部都是0。

接著格式化這塊 ram 空間

$ mkfs.ext2 /dev/ram0 4096

最後 mount 此空間 (我 mount 在 /mnt/ramdisk 目錄上),準備複製檔案:

$ mount -t ext2 /dev/ram0 /mnt/ramdisk


(b) loopback device: loopback image 檔

有些人是用舊機器跑 linux,ram 可能只有 16~32mb,用 ramdisk 就不太方便,這時可以利用 loopback 設備。
作法是將一個檔案,當作 loopback 設備 mount 起來。

$ dd if=/dev/zero of=/tmp/rootfs-file bs=1k count=4096

上面的指令,會在 /tmp 建立一個叫 rootfs-file 的檔案,大小 是 4096KB。
意義跟上面 ramdisk 一樣,只是一個把空間建立在 ram 中,另一個建立在 disk 中。

格式化:

$ mkfs.ext2 /tmp/rootfs-file 4096

把這個檔案 mount 上去:

$ mount -o loop -t ext2 /tmp/rootfs-file /mnt/ramdisk

mount:掛在命令.
mount [-t vfstype] [-o options] device dir
1.-t vfstype 指定文件系統的類型,通常不必指定。mount 會自動選擇正確的類型。
2.-o options 主要用來描述設備或檔案的掛接方式。常用的參數有:
loop:用來把一個文件當成硬盤分區掛接上系統
ro:採用只讀方式掛接設備
rw:採用讀寫方式掛接設備
iocharset:指定訪問文件系統所用字符集
3.詳細參數參考:mount命令詳解(網絡搜索)


(c) 硬碟

這個方法不太建議使用...
在硬碟上分一個 partition,格式化後 mount 上去,做為 root filesystem 的空間。
除非硬碟上剛好有一個 partition 沒在用,否則不需要這麼做。

建立一個儲存空間
$ dd if=/dev/zero of=DEVICE bs=1k count=???

格式化此空間
$ mkfs.ext2 DEVICE

mount 此空間
$ mount -t ext2 DEVICE /mnt/ramdisk


2.選擇要放入 root filesystem 的檔案

選擇要放入 root filesystem 的檔案,這個部份就看你自已的了。
有些是必要的, 有些是選擇性的,自已憑經驗看著辦。
在複製的檔案時,最好用 cp -dpR 來複製,這樣才可以完 整地將檔案屬性複製過去(特別是那些設備檔及符號連結檔)。
這些檔案複製好後,我們就完成 root filesystem 的內容了。

3.建立 root filesystem 的 image

接下來,我們要將這整個 root filesystem 的內容,變成一 個 image (檔案),並且加以壓縮。
最好先 umount :

$ umount /mnt/rootfs

接著將該空間的內容給 dump 出來,變成一個 image 檔, 並壓縮,我用一個動作完成:

$ dd if=DEVICE bs=1k count=??? | gzip -9 > /tmp/rootfs.gz

DEVICE 是你選擇的設備,在本文中,如 /dev/ram0, /tmp/rootfs-file;
??? 的大小,是你建立這空間時所指定的,本文中,都是用 4096。

之所以要再重新建立空間,是為了清除空間中的舊有資料,全部設為0,這樣在製作 image時,就可以壓得比較小。

MarkS Note: Rootfs 與 ramfs 和 initramfs的差別 - https://goo.gl/Eqzsvk

註1:
是一種偽裝置,這種裝置使得檔案可以如同塊裝置一般被存取。
在Linux中,裝置名按照相應裝置驅動程式的符號表項進行命名。這些裝置被叫做」loop「裝置,裝置節點通常命名為/dev/loop0, /dev/loop1之類。

ramfs、tmpfs、rootfs、ramdisk介绍 - CSDN博客 - https://goo.gl/Bp6y7A

Ramdisk & Root filesystem image @ Welkin小窩 :: 痞客邦 PIXNET :: - https://goo.gl/Ptqbr3

0 意見:

張貼留言

 
Blogger Templates