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