boot loader裝入kernel, 然后kernel需要執行/sbin/init, 讀取
這個文件就必須先mount根文件系統, 早期是通過啟動時的root=
參數告訴內核根文件系統在哪個設備上, 隨著硬件和技術的發展,
現在根文件系統可能位于一個網絡存儲如NFS上, 可能由于RAID而
散布于多個設備上, 可能位于一個加密設備上需要提供用戶名和密碼,
這時root=參數就顯得不夠了. 為了應付這種局面, 先后出現兩種
機制來作為boot loader裝載kernel到真正的/sbin/init執行這個啟動
過程的橋梁: initrd和initramfs, 兩者有類似的地方, 比如都是
由內核執行其上的某個程序(initrd是/linuxrc, initramfs是/init),
由這個程序決定加載什么驅動以及如何裝載根文件系統. 下面一點
筆記總結initrd的缺點和initramfs的優點.
initrd:
ram disk是一個基于ram的塊設備,因此它占據了一塊固定的內存,
而且事先要使用特定的工具比如mke2fs格式化,還需要一個文件系統
驅動來讀寫其上的文件。
如果這個disk上的空間沒有用完,這些未用的內存就浪費掉了,并且
這個disk的空間固定導致容量有限,要想裝入更多的文件就需要重新
格式化。
由于Linux的塊設備緩沖特性, ram disk上的數據被拷貝到page cache
(對于文件數據)和dentry cache(對于目錄項), 這個也導致內存浪費.
initramfs:
最初的想法是Linus提出的: 把cache當作文件系統裝載. 他在一個叫
ramfs的cache實現上加了一層很薄的封裝, 其它內核開發人員編寫了
一個改進版tmpfs, 這個文件系統上的數據可以寫出到交換分區, 而且
可以設定一個tmpfs裝載點的最大尺寸以免耗盡內存. initramfs就是
tmpfs的一個應用.
優點:
(1)tmpfs隨著其中數據的增減自動增減容量.
(2)在tmpfs和page cache/dentry cache之間沒有重復數據.
(3)tmpfs重復利用了Linux caching的代碼, 因此幾乎沒有增加內核
尺寸, 而caching的代碼已經經過良好測試, 所以tmpfs的代碼質量
也有保證.
(4)不需要額外的文件系統驅動.
另外, initrd機制被設計為舊的"root="機制的前端, 而非其替代物,
它假設真正的根設備是一個塊設備, 而且也假設了自己不是真正的根設備,
這樣不便將NFS等作為根文件系統, 最后/linuxrc不是以PID=1執行的, 因為
1這個進程ID是給/sbin/init保留的. initrd機制找到真正的根設備后將
其設備號寫入/proc/sys/kernel/real-root-dev, 然后控制
轉移到內核由
其裝載根文件系統并啟動/sbin/init.
initramfs則去掉了上述假設, 而且/init以PID=1執行, 由init裝載根文件
系統并用exec轉到真正的/sbin/init, 這樣也導致一個更為干凈漂亮的設計.