標籤:

Linux的啟動過程中,滿足什麼條件可以不用initramfs而直接掛載/?


用了Gentoo你就懂了。

我們的 Gentoo 全是一個3-6M大的內核,無initrd(initramfs)。

拆不拆/boot都一樣,沒區別,都可以不加initramfs。

除非有人非要搞plymouth啟動動畫這種美化的東西才會去生成一個initramfs。

為了正常啟動只要把硬碟驅動(不用懷疑,硬碟也有驅動……)、LVM(如果你用的話)、文件系統編譯進去就行了,(根據各版本內核默認配置不同,)可能會偶爾因為別的必須的東西沒編譯而導致內核恐慌。

當然很多人卡殼在第一步……

籠統的來說,不生成initramfs的情況下,啟動順序為:

1、grub引導vmlinuz,vmlinuz有root參數,例如root=/dev/sda7,或者root=UUID

2、vmlinuz讀取/etc中的modules文件,決定載入哪個模塊(這裡一般放置網路模塊等,例如vbox虛擬機驅動vboxdrv,我的網卡brcmsmac,b43等),模塊大概是放在/lib/modules*。此時要求vmlinuz編譯了可以讀取 / 的文件系統。

3、啟動。

順便說一下,gentoo上的mkinitrd系列工具是被標記為推薦不安裝的。

至於種卿卿同學的

順帶說一句,比如grub的menu.lst,/initramfs是從根開始的,而不是/boot/initramfs。希望能幫您重新理解Linux啟動流程。

………………表示弄了多年的linux,硬是木有看懂這句話。

夫差,難道你忘了grub0.97 的 root命令和grub2的 set root 命令……


順帶說一句,比如grub的menu.lst,/initramfs是從根開始的,而不是/boot/initramfs。希望能幫您重新理解Linux啟動流程。

-------------------------------------------

你可以看看grub的代碼。 grub實現引導的功能最多代碼實現其實是載入/boot,也就是載入內核。 主要原理是MBR(GRUB 實現的MBR部分, 是一段400多位元組的程序加主分區表)載入大約64KB大小/boot文件系統支持(大小不是很清楚,就是不屬於任何分區一小塊磁碟空間,大約在主分區開始前,在安裝GRUB引導器寫入,有時裝好的GRUB重新調整分區表沒影響到MBR 就會刪除這一塊空間內容,導致GRUB出錯提示stage xxx載入不了)

GRUB 載入menu.lst 或grub.conf後(這個路徑不能變的,不支持配置,除非你去改GRUB代碼),然後根據menu.lst 配置載入,grub-0.97 每個操作系統載入第一行都是root (xxx), 這一行, 其他就可能用到/boot/grub/裡面其他各種文件系統的支持了。 vmlinuz和initramfs了,放那裡都沒有關係,關鍵是grub支持的文件系統和磁碟,你可以放/boot/initramfs,也可以/boot/usr/bin/initramfs都可以 都沒有關係(我習慣是/boot 跟/不同分區)

------------------------------------------------

------------------------------------

vmlinuz讀取/etc中的modules文件,決定載入哪個模塊(這裡一般放置網路模塊等,例如vbox虛擬機驅動vboxdrv,我的網卡
brcmsmac,b43等),模塊大概是放在/lib/modules*。此時要求vmlinuz編譯了可以讀取 / 的文件系統。

--------------------------------------

這個並不是vmlinuz的功能,或者說不是直接功能。

vmlinuz功能就是初始化內核及載入啟動init進程, 內核模塊不是內核vmlinuz主動載入的,init進程啟動後,調用其他程序載入的

什麼內核模塊,網卡配置,通常都是/etc/init.d下面一堆腳本做的(腳本運行在/sbin/init準備好的shell環境中),運維人員應該經常跟這些打交道 。這些init腳本或叫應用層系統初始化及配置功能,事實標準應該是叫sysvinit,不過每個發行版實現起來都有差異。很多時間一段驅動的安裝失敗就是因不同版本的啟動腳本介面不一致,如redhat系和debian系就有較大差異。

現在gentoo的實現是openrc及systemd可選其中之一, ubuntu使用的叫upstar。systemd把過去腳本化串列的啟動功能改用elf二進位+配置文件來做了,因為可以並行啟動以及二進位的效率運行方式提高等,所以啟動速度提高了很多。開機一般4~5秒就完成grub-&>X了。關機一般是1~2秒(我的是固態硬碟),但是對於一些linux的老鳥來說,可能沒有以前shell腳本直觀簡單。

自從自己成功編譯內核後,就再也沒有用過initramfs了,生成這個也挺複雜(懶得動手). initramfs並不是什麼必須東西。 眾多發行版喜歡帶這個因為這個靈活。如果內核有磁碟和文件系統了,直接載入啟動init進程,其他就不行initramfs了。

initramfs就是一段精簡的linux系統,剛性目的就是靈活載入init。 如果不要initramfs, 想想一個發行版的內核如可要支持各式各樣的硬碟(以前ATA, SATA, SCSI, USB),還有數十種文件系統,然後可能還要支持NFS(網路協議,地址配置),這樣的內核會彭漲得很大, 一些載入器如lilo對加的內核大小是有限制的。所以不能把內核做得很大,就有initramfs。就是GRUB預載入一個小型文件系統到內存,裡面包含init進程和shell腳本,需要的內核模塊,還可以有一些花哨的東西像bootsplash, 有興趣的同學可以找找教程解壓initramfs出來看看。


對鍾(懶得打字)的答案提出少量異議。

1. 對於不拆 boot 的人來說,grub 的確該做 initrd boot/initramfs 來載入。當然一些發行版在根目錄下對 /boot 中的內核和 initramfs 進行了軟鏈接,這是另外的事情了。至少 grub-mkconfig 永遠是那麼認認真真地按 /boot 在哪裡處理的。

2 Linux Kernel 其實一點都不怕找不到 /,因為有 root=/dev/xxx 參數丟著呢,grub2-mkconfig 照樣會自動寫好。grub 0.97 大坑我不知道,但是至少內核命令行你還是可以那麼傳。

剩下的保持一致,即對於複雜的文件系統(如 LVM 和 Squashfs Live)環境需要使用 initramfs 推一把。ext 系列用戶實際上真的不用管這個…


這是先有雞還是先有蛋的問題。需要掛載根目錄,就需要知道文件系統程序、驅動程序在哪兒並運行起來;但這些文件是擱在根目錄下的。這就是悖論。

initramfs就是解決這個悖論的,把驅動和所需的程序打包。然後在內存中建立偽根、並啟動init完成啟動自舉。

所以要替換initramfs的條件,就得替換它所完成的功能。

順帶說一句,比如grub的menu.lst,/initramfs是從根開始的,而不是/boot/initramfs。希望能幫您重新理解Linux啟動流程。


如果內核能夠正確識別和載入你的rootfs所在設備的驅動、正確掛載你的rootfs的文件系統,從而能夠順利讀取rootfs的文件,那就不需要多此一舉載入initramfs。

在嵌入式linux領域,內核都是針對特定硬體進行的編譯,自然在內核中可以加入這些設備驅動和文件系統。比如rootfs位於NAND,而NAND Flash使用了UBIFS文件系統,只要我們在kernel中加入NAND驅動、UBIFS相關驅動,啟動時通過bootargs向kernel傳遞正確的rootfs位置和驅動信息,kernel自身就可以順利找到rootfs並掛載正確,從而繼續下面的init工作。

而在PC端,通常一個內核需要適應各種差異巨大的硬體,如果要在內核中包含能兼容所有不同廠商、不同處理器、不同啟動介質、不同文件系統的基本驅動,內核會變得非常複雜、兼容性擴展性不好,體積還很大。這時候,就可以考慮把比如所有x86 pc相似相同的公共性驅動放在kernel中,而把差異性的驅動放在initramfs里。同時initramfs里還會有更多初始啟動時的腳本,幫助系統更好的完成kernel啟動後的下一階段工作。


個人理解可能不對。

我覺得initramfs的主要目的是為了補充設備驅動。你不可能把所有的設備驅動都編譯到內核里,那樣內核體積就太大了。在無數個驅動程序中,你的機器需要用到的也就那麼幾個到十幾個,然而驅動程序卻有上千個。目前的做法是把不常用的驅動都放在initramfs裡面,內核啟動之後先從initramfs里啟動一下小的系統,並掛載所需的硬體驅動,這樣可以保證網卡、RAID卡、硬碟、SSD、嵌入式設備的nandflash等可以使用。而真正的文 件系統很有可能是做在上述硬體里的。

總結答案就是,如果你已經把硬碟(或者說是你存儲文 件系統的存儲設備)驅動以及文件系統驅動(例子ext.ko等)編譯進了內核,那你就不需要initramfs了。


推薦閱讀:

ELF文件裡面section的虛擬地址是如何在鏈接(link)時確定的?
Linux 平台下閱讀 Linux 內核源碼好用的工具有哪些?

TAG:Linux | Linux內核 |