linux 下的 initrd ramdisk
在Linux操作系統(tǒng)中,有一項(xiàng)特殊的功能——初始化內(nèi)存盤INITRD(INITial Ram Disk)技術(shù),而且內(nèi)核支持壓縮的文件系統(tǒng)映像。有了這兩項(xiàng)功能,我們可以讓Linux系統(tǒng)從小的初始化內(nèi)存盤啟動(dòng),并把系統(tǒng)內(nèi)存的一部分作為根文件系統(tǒng)掛載。
Ramdisk就是將內(nèi)存的一部分分配為一個(gè)分區(qū)并作為硬盤來使用。對(duì)于系統(tǒng)運(yùn)行時(shí)不斷使用的程序,將它們放在Ramdisk中將加快計(jì)算機(jī)的操作,如大數(shù)據(jù)量的網(wǎng)絡(luò)服務(wù)器、無盤工作站等。為了能夠使用Ramdisk,我們?cè)诰幾g內(nèi)核時(shí)須將block device中的Ramdisk支持選上,它下面還有兩個(gè)選項(xiàng),一個(gè)是設(shè)定Ramdisk的大小,默認(rèn)是4096k;另一個(gè)是設(shè)定默認(rèn)個(gè)數(shù)。如果要使用initrd,還得選上的支持。它既可以直接編譯進(jìn)內(nèi)核,也可以編譯成模塊,在需要的時(shí)候加載。我們由于在啟動(dòng)時(shí)就用它,所以必須將它直接編譯進(jìn)內(nèi)核。
什么是Initrd
? ?initrd的英文含義是 boot loader initialized RAM disk,就是由boot loader初始化的內(nèi)存盤。在 linux內(nèi)核啟動(dòng)前, boot loader 會(huì)將存儲(chǔ)介質(zhì)中的 initrd 文件加載到內(nèi)存,內(nèi)核啟動(dòng)時(shí)會(huì)在訪問真正的根文件系統(tǒng)前先訪問該內(nèi)存中的 initrd 文件系統(tǒng)。
? ?在 boot loader 配置了 initrd 的情況下,內(nèi)核啟動(dòng)被分成了兩個(gè)階段,第一階段先執(zhí)行 initrd文件系統(tǒng)中的"某個(gè)文件",完成加載驅(qū)動(dòng)模塊等任務(wù),第二階段才會(huì)執(zhí)行真正的根文件系統(tǒng)中的 /sbin/init 進(jìn)程。
? ?這里提到的"某個(gè)文件",Linux2.6 內(nèi)核會(huì)同以前版本內(nèi)核的不同,所以這里暫時(shí)使用了"某個(gè)文件"這個(gè)稱呼,后面會(huì)詳細(xì)講到。
? ?第一階段啟動(dòng)的目的是為第二階段的啟動(dòng)掃清一切障礙,最主要的是加載根文件系統(tǒng)存儲(chǔ)介質(zhì)的驅(qū)動(dòng)模塊。為了在內(nèi)核啟動(dòng)之后能夠判斷哪些硬件驅(qū)動(dòng)需要加載,哪些不需要,文件系統(tǒng)有沒有問題等,最終使得根分區(qū)能順利加載。我們知道根文件系統(tǒng)可以存儲(chǔ)在包括IDE、SCSI、USB在內(nèi)的多種介質(zhì)上,如果將這些設(shè)備的驅(qū)動(dòng)都編譯進(jìn)內(nèi)核,可以想象內(nèi)核會(huì)多么龐大、臃腫。
Initrd的用途
? ?1.linux 發(fā)行版的必備部件
? ?linux 發(fā)行版必須適應(yīng)各種不同的硬件架構(gòu),將所有的驅(qū)動(dòng)編譯進(jìn)內(nèi)核是不現(xiàn)實(shí)的,initrd技術(shù)是解決該問題的關(guān)鍵技術(shù),Linux發(fā)行版在內(nèi)核中只編譯了基本的硬件驅(qū)動(dòng),在安裝過程中通過檢測(cè)系統(tǒng)硬件,生成包含安裝系統(tǒng)硬件驅(qū)動(dòng)的initrd,無非是一種即可行又靈活的解決方案。
? ?2.livecd 的必備部件
? ?同linux發(fā)行版相比livecd可能會(huì)面對(duì)更加復(fù)雜的硬件環(huán)境,所以也必須使用initrd。
? ?3.制作 Linux usb 啟動(dòng)盤必須使用 initrd
? ?usb 設(shè)備是啟動(dòng)比較慢的設(shè)備,從驅(qū)動(dòng)加載到設(shè)備真正可用大概需要幾秒鐘時(shí)間。如果將usb驅(qū)動(dòng)編譯進(jìn)內(nèi)核,內(nèi)核通常不能成功訪問usb設(shè)備中的文件系統(tǒng)。因?yàn)樵趦?nèi)核訪問usb設(shè)備時(shí),usb設(shè)備通常沒有初始化完畢。所以常規(guī)的做法是,在 initrd 中加載usb驅(qū)動(dòng),然后休眠幾秒中,等待usb設(shè)備初始化完畢后再掛載usb設(shè)備中的文件系統(tǒng)。
? ?4.在linuxrc腳本中可以很方便地啟用個(gè)性化bootsplash。
Linux2.6內(nèi)核對(duì)Initrd的處理流程
? ?linux2.6內(nèi)核支持兩種格式的initrd,一種是前面第3部分介紹的linux2.4內(nèi)核那種傳統(tǒng)格式的文件系統(tǒng)鏡像-image-initrd,它的制作方法同Linux2.4內(nèi)核的initrd一樣,其核心文件就是/linuxrc。另外一種格式的initrd 是cpio格式的,這種格式的initrd從 linux2.5 起開始引入,使用cpio工具生成,其核心文件不再是/linuxrc,而是/init,本文將這種initrd稱為cpio-initrd。
? ?盡管linux2.6內(nèi)核對(duì)cpio-initrd和image-initrd這兩種格式的initrd均支持,但對(duì)其處理流程有著顯著的區(qū)別,下面分別介紹linux2.6內(nèi)核對(duì)這兩種initrd的處理流程。
? ?cpio-initrd 的處理流程
? ?1.boot loader把內(nèi)核以及initrd文件加載到內(nèi)存的特定位置。
? ?2.內(nèi)核判斷initrd的文件格式,如果是cpio格式。
? ?3.將initrd的內(nèi)容釋放到rootfs中。
? ?4.執(zhí)行initrd中的/init文件,執(zhí)行到這一點(diǎn),內(nèi)核的工作全部結(jié)束,完全交給/init文件處理。
? ?image-initrd的處理流程
? ?1.boot loader把內(nèi)核以及initrd文件加載到內(nèi)存的特定位置。
? ?2.內(nèi)核判斷initrd的文件格式,如果不是cpio格式,將其作為image-initrd處理。
? ?3.內(nèi)核將initrd的內(nèi)容保存在rootfs下的/initrd.image文件中。
? ?4.內(nèi)核將/initrd.image的內(nèi)容讀入/dev/ram0設(shè)備中,也就是讀入了一個(gè)內(nèi)存盤中。
? ?5.接著內(nèi)核以可讀寫的方式把/dev/ram0設(shè)備掛載為原始的根文件系統(tǒng)。
? ?6..如果/dev/ram0被指定為真正的根文件系統(tǒng),那么內(nèi)核跳至最后一步正常啟動(dòng)。
? ?7.執(zhí)行initrd上的/linuxrc文件,linuxrc通常是一個(gè)腳本文件,負(fù)責(zé)加載內(nèi)核訪問根文件系統(tǒng)必須的驅(qū)動(dòng),以及加載根文件系統(tǒng)。
? ?8./linuxrc執(zhí)行完畢,常規(guī)根文件系統(tǒng)被掛載
? ?9.如果常規(guī)根文件系統(tǒng)存在/initrd目錄,那么/dev/ram0將從/移動(dòng)到/initrd。否則如果/initrd目錄不存在,/dev/ram0將被卸載。
? ?10.在常規(guī)根文件系統(tǒng)上進(jìn)行正常啟動(dòng)過程 ,執(zhí)行/sbin/init。
通過上面的流程介紹可知,Linux2.6內(nèi)核對(duì)image-initrd的處理流程同linux2.4內(nèi)核相比并沒有顯著的變化,cpio-initrd的處理流程相比于image-initrd的處理流程卻有很大的區(qū)別,流程非常簡(jiǎn)單。
nitial RAM disk
Linux初始RAM磁盤(initrd)是在系統(tǒng)引導(dǎo)過程中掛載的一個(gè)臨時(shí)根文件系統(tǒng),用來支持兩階段的引導(dǎo)過程。initrd文件中包含了各種可執(zhí)行程序和驅(qū)動(dòng)程序,它們可以用來掛載實(shí)際的根文件系統(tǒng),然后再將這個(gè) initrd RAM磁盤卸載,并釋放內(nèi)存。在很多嵌入式Linux系統(tǒng)中,initrd 就是最終的根文件系統(tǒng)。本文將探索 Linux 2.6 的初始 RAM磁盤,包括如何創(chuàng)建以及如何在Linux內(nèi)核中使用。
什么是初始 RAM 磁盤
初始RAM磁盤(initrd)是在實(shí)際根文件系統(tǒng)可用之前掛載到系統(tǒng)中的一個(gè)初始根文件系統(tǒng)。initrd與內(nèi)核綁定在一起,并作為內(nèi)核引導(dǎo)過程的一部分進(jìn)行加載。內(nèi)核然后會(huì)將這個(gè) initrd文件作為其兩階段引導(dǎo)過程的一部分來加載模塊,這樣才能稍后使用真正的文件系統(tǒng),并掛載實(shí)際的根文件系統(tǒng)。
initrd 中包含了實(shí)現(xiàn)這個(gè)目標(biāo)所需要的目錄和可執(zhí)行程序的最小集合,例如將內(nèi)核模塊加載到內(nèi)核中所使用的 insmod 工具。
在桌面或服務(wù)器Linux 系統(tǒng)中,initrd 是一個(gè)臨時(shí)的文件系統(tǒng)。其生存周期很短,只會(huì)用作到真實(shí)文件系統(tǒng)的一個(gè)橋梁。在沒有存儲(chǔ)設(shè)備的嵌入式系統(tǒng)中,initrd 是永久的根文件系統(tǒng)。本文將對(duì)這兩種情況進(jìn)行探索。
一開始我被ramdisk和initrd這兩個(gè)東西弄胡涂了,其實(shí)ramdisk只是在ram上實(shí)現(xiàn)的塊設(shè)備,initrd可以說是啟動(dòng)過程中用到的一種機(jī)制。就是在裝載linux之前,bootloader可以把一個(gè)比較小的根文件系統(tǒng)的映象裝載在內(nèi)存的某個(gè)指定位置,姑且把這段內(nèi)存稱為initrd,然后通過傳遞參數(shù)的方式告訴內(nèi)核initrd的起始地址和大小(也可以把這些參數(shù)編譯在內(nèi)核中),在啟動(dòng)階段就可以暫時(shí)的用initrd來mount根文件系統(tǒng)。initrd的最初的目的是為了把kernel的啟動(dòng)分成兩個(gè)階段:在kernel中保留最少最基本的啟動(dòng)代碼,然后把對(duì)各種各樣硬件設(shè)備的支持以模塊的方式放在initrd中,這樣就在啟動(dòng)過程中可以從initrd所mount的根文件系統(tǒng)中裝載需要的模塊。這樣的一個(gè)好處就是在保持kernel不變的情況下,通過修改initrd中的內(nèi)容就可以靈活的支持不同的硬件。在啟動(dòng)完成的最后階段,根文件系統(tǒng)可以重新mount到其他設(shè)備上,但是也可以不再重新mount(很多嵌入式系統(tǒng)就是這樣)。?initrd的具體實(shí)現(xiàn)過程是這樣的:bootloader把根文件系統(tǒng)映象裝載到內(nèi)存指定位置,把相關(guān)參數(shù)傳遞給內(nèi)核,內(nèi)核啟動(dòng)時(shí)把initrd中的內(nèi)容復(fù)制到ramdisk中(ram0),把initrd占用的內(nèi)存釋放掉,在ram0上mount根文件系統(tǒng)。從這個(gè)過程可以看出,內(nèi)核需要對(duì)同時(shí)對(duì)ramdisk和initrd的支持。
initrd的最初的目的是為了把kernel的啟動(dòng)分成兩個(gè)階段:在kernel中保留最少最基本的啟動(dòng)代碼,然后把對(duì)各種各樣硬件設(shè)備的支持以模塊的方式放在initrd中,這樣就在啟動(dòng)過程中可以從initrd所mount的根文件系統(tǒng)中裝載需要的模塊。這樣的一個(gè)好處就是在保持kernel不變的情況下,通過修改initrd中的內(nèi)容就可以靈活的支持不同的硬件。在啟動(dòng)完成的最后階段,根文件系統(tǒng)可以重新mount到其他設(shè)備上。?
標(biāo)準(zhǔn)的答案是:initrd是linux在系統(tǒng)引導(dǎo)過程中使用的一個(gè)臨時(shí)的根文件系統(tǒng),用來支持兩階段的引導(dǎo)過程。
再白話一點(diǎn),initrd就是一個(gè)帶有根文件系統(tǒng)的虛擬RAM盤,里面包含了根目錄‘/’,以及其他的目錄,比如:bin,dev,proc,sbin,sys等linux啟動(dòng)時(shí)必須的目錄,以及在bin目錄下加入了一下必須的可執(zhí)行命令。
PC或者服務(wù)器linux內(nèi)核使用這個(gè)initrd來掛載真正的根文件系統(tǒng),然后將此initrd從內(nèi)存中卸掉,這種情況下initrd其實(shí)就是一個(gè)過渡使用的東西。?當(dāng)然也可以不卸載這個(gè)initrd,直接將其作為根文件系統(tǒng)使用,這當(dāng)然是在沒有硬盤的情況下了,這種情況多用在沒有磁盤的超輕量級(jí)的嵌入式系統(tǒng)。?其實(shí)現(xiàn)在的大多數(shù)嵌入式系統(tǒng)也是有自己的磁盤的,所以,initrd在現(xiàn)在大多數(shù)的嵌入式系統(tǒng)中也作過渡使用。
Initrd的引導(dǎo)過程
????‘第二階段引導(dǎo)程序’,常用的是grub將內(nèi)核解壓縮并拷貝到內(nèi)存中,然后內(nèi)核接管了CPU開始執(zhí)行,然后內(nèi)核調(diào)用init()函數(shù),注意,此init函數(shù)并不是后來的init進(jìn)程!!!然后內(nèi)核調(diào)用函數(shù)initrd_load()來在內(nèi)存中加載initrd根文件系統(tǒng)。Initrd_load()函數(shù)又調(diào)用了一些其他的函數(shù)來為RAM磁盤分配空間,并計(jì)算CRC等操作。然后對(duì)RAM磁盤進(jìn)行解壓,并將其加載到內(nèi)存中。現(xiàn)在,內(nèi)存中就有了initrd的映象。
????然后內(nèi)核會(huì)調(diào)用mount_root()函數(shù)來創(chuàng)建真正的跟分區(qū)文件系統(tǒng),然后調(diào)用sys_mount()函數(shù)來加載真正的根文件系統(tǒng),然后chdir到這個(gè)真正的根文件系統(tǒng)中。
????最后,init函數(shù)調(diào)用run_init_process函數(shù),利用execve來啟動(dòng)init進(jìn)程,從而進(jìn)入init的運(yùn)行過程。
總結(jié)
以上是生活随笔為你收集整理的linux 下的 initrd ramdisk的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux 2.6内核配置说明(File
- 下一篇: Linux下1号进程的前世(kernel