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