使用者空間的初始化initial

2021-06-20 09:44:27 字數 2801 閱讀 8446

取自:

阿拉神農

linux

image

android

儲存disk工作

上篇我們知道,kernel初始化後將啟動init程序,那麼這個程序將幹些什麼呢?除此之外,kernel還需要做些什麼事情呢?(想想檔案系統、根儲存裝置是在什麼時候初始化的呢?)

先從檔案系統初始化說起。以前一直不明白,有了kernel為何還需要乙個檔案系統?經過反覆琢磨,明白乙個道理,kernel載入到記憶體後,kernel執行起來是沒有問題的,但是如果沒有root fs,就好像pc上沒有硬碟.....。另外,linux中很多虛擬檔案系統(proc,sys,dev等)都是掛靠在rootfs中的,所以rootfs在linux中更加關鍵(必要條件簡直就是)。(kernel中的fs是另外乙個龐大的部分)

一 根檔案系統

1 fhs:file system hierachy standard:linux上檔案系統布局的標準,例如 usr目錄大概是幹嗎的,tmp目錄大概是幹嘛的。有空可以瞧瞧....其實使用linux os多了,自然就理解了。

2 常用的資料夾布局:其實就是es上普遍的檔案目錄:

二 post boot

這裡講的是execve init之前的事情,因為原始碼中:

三 init

init程序很重要,不過android上的init程序的工作流程比較簡單。這裡介紹非android上的init。一般它讀取的配置檔案是/etc/inittab中(ubuntu上似乎沒有這個檔案了,以後得找個fcore的系統看看)。

另外,這裡還有乙個叫run level的概念。見圖1.

圖1 run level

run level說白了就是將系統執行狀態分成幾個級別,例如shutdown的時候init需要執行一些操作,reboot的時候需要執行一些操作。

這裡關於init的東西就不介紹了,很多關於linux系統配置的知識都有涉及。(確實比android的init要複雜多了)

四 initial ram disk

lk在早期初始化的過程中,需要mount乙個fs,目前有新舊兩種方法:

這兩個東西非常常見,咱們要好好研究下。

4.1 initrd

這個功能需要配置kernel的編譯選項。

arm支援將前面的initrd和vmlinux打包到乙個image中。實際上只有arm架構支援。(核心編譯的時候要選擇這一項)。講了這麼多,那麼到底怎麼用呢?

bootloader把initrd的位址告訴核心。核心啟動時候把這個image解壓並掛載

另外一種辦法,編譯的時候將initrd和kernel放到乙個image中,這種方法只有arm架構支援。使用這種辦法話,建議用initramfs。注意,android中使用的就是乙個kernel+initramfs的單一image。也就是第二種辦法

(這裡有很多細節問題,以後我們分析原始碼再來搞懂它)

bl啟動核心的時候,需要給lk傳遞引數,即告訴lk這個initrd在什麼位置...很簡單不是?

kl如何使用這個initrd呢?

那麼如何製作這個initrd呢?

其實就是乙個gzip打包的資料夾....

(這部分**在do_mounts.c中的prepare_namespace函式中)

4.2 initramfs

(詳細說明:參考kernel/documentations/filesystems/ramfs-rootfs-initramfs.txt)

kernel預設支援這個initramfs,所以編譯的時候,會整乙個default的initramfs放到核心中。initramfs是乙個cpio的打包檔案。我特意查了下cpio的info。一般用法就是:讀取乙個目錄下所有檔案的資訊及其所有檔案的內容(可能是直接read資料到乙個buffer中),然後把這些資訊寫到乙個檔案中。說白了,可能就是乙個序列化的工具。然後lk用同樣的方法就可以反序列化,恢復原來目錄中的內容了。

前面說,lk編譯的時候缺省會有乙個簡單的initramfs目錄結構。這個結構由kernel/scripts/gen_initramfs_list.sh指令碼生成。這個指令碼很簡單:

dir /dev 0755 0 0

nod /dev/console/ 0600 0 0 c 5 1

dir /root 0700 0 0

執行的時候,前面加上mk...就生成乙個目錄了,然後用cpio打包,生成iniramfs,最後由lk解包並掛載

(具體內容,參考ramfs-rootfs-initramfs.txt)

如何製作自己的initramfs呢?

cpio:-o表示output,-v表示列印一些verbose資訊,-i表示input,-d表示建立整個資料夾結構。沒有-d的話,會出問題。

不過有了kernel編譯的支援,我們不用自己呼叫cpio了,在編譯選項中有乙個initramfs_source,把它指向目標資料夾,編譯的時候自然會生成這個initramfs了。

linux啟動的一些問題。

再三解釋一下,為什麼需要init ram disk。fs一般安裝在儲存介質上,而讀取這些儲存介質需要驅動。核心啟動的時候如果把這些驅動都載入的話,會非常麻煩,即使你把驅動靜態編譯到核心中,也不是乙個完美的解決辦法。所以。先整乙個簡單的,基於記憶體的fs,這樣初始化工作都可以順利進行。最後,等驅動都載入完後,再把實際儲存上的fs掛載上來。這裡要明白一點,沒有乙個fs的話,lk是沒法正常工作的。

五 u-boot

全名為das u-boot,是乙個使用非常廣泛的bootloader。以後會專門撰文介紹ub。這裡簡單說兩個點:

(最難的部分在於各個裝置的初始化了,需要結合開發板的datasheet來做)

其中,關於sdram.pdf,**已經移到了:

核心空間vmalloc的空間初始化

我們最近在除錯32位產品的時候遇到了這樣的問題 使用ddr虛擬disk做硬碟,來啟動系統 因為32位產品可以訪問的最大位址空間僅為4g,因此核心空間的位址也顯的比較緊張 我們虛擬的disk的實現是,使用一大塊連續的物理記憶體做disk,並將這塊物理記憶體通過vm map ram將物理線性位址對映到v...

初始化git的初始化使用者資訊

舉例驗證 官方幫助資訊 初始化使用者資訊,當人為提交add或commit編輯時,git伺服器會記錄提交人及郵箱,方便記錄資訊和給提交人傳送郵件。etc gitconfig此配置下設定git提交使用者資訊,每次提交時git會從此配置檔案中獲取使用者和郵箱,但是此配置缺點是不管那個子使用者都是以此使用者...

初始化 指定初始化

id alloc 物件的誕生過程,主要是從作業系統獲得一塊足夠大的記憶體,以存放該類的全部例項變數,並將其指定為存放記憶體物件的實力變數的位置。alloc方法同時將這塊記憶體全部設定為0。結果是 bool變數初始化為no,所有的int型別變數為0,float變數為0.0,所有的指標為nil.obje...