轉自:http://blog.csdn.net/weiganyi/article/details/11561859shell
在咱們的周圍,大量的嵌入式設備都是基於Linux系統來構建的,嵌入式Linux與主機Linux相比有着本身的一些特色,本文就嵌入式Linux系統的構成和啓動過程作一些總結。spa
1、嵌入式Linux系統構成操作系統
上圖是一個嵌入式Linux系統的典型結構,劃分紅了4個區:.net
一、Bootloader區存放的是Bootloader,它負責嵌入式系統最初的硬件初始化、驅動和內核加載。翻譯
二、參數區不是必須的,一般存放了一些系統參數,而且一般這個區是沒有文件系統,參數以原始數據的格式來存放。blog
三、內核鏡像區存放的Linux內核壓縮鏡像,它被解壓後運行於內存,做爲嵌入式設備的Linux操做系統。接口
四、文件系統區存放通過壓縮的文件系統,它會被Linux內核解壓並掛載,並做爲各類應用程序、文件的主要載體。進程
這4個區都以二進制數據的形式存放於嵌入式設備的Flash芯片上。內存
2、嵌入式Linux系統啓動過程get
嵌入式設備從上電那一刻到應用程序正常運行,其間經歷過一系列漫長的過程,下面對主要的步驟進行闡述:
一、嵌入式設備上電後,CPU開始運行,一般CPU會從某一個固定的物理地址開始運行,這個物理地址通常是Flash芯片的起始物理地址。Flash芯片的最初一段一般存放的是Bootloader,因而CPU就會開始運行Bootloader的代碼。
二、咱們知道CPU能夠讀寫Flash上的數據,可是不能直接執行Flash上的指令,CPU一般只能執行內存中的指令,那麼CPU剛開始運行時怎樣去執行Flash上的指令呢?這裏分兩種狀況,Flash芯片主要分爲兩種,一種是Nor Flash,另外一種是Nand Flash,Nor Flash具備能夠直接在Flash芯片上執行指令的特色。若是嵌入式設備採用的是Nor Flash,那就比較簡單了,CPU能夠直接運行在Nor Flash上的指令。若是採用的是Nand Flash呢,怎麼辦?目前主要有兩種方法,一種方法是Flash控制器可以把Nand Flash的前4k數據搬到4k的內部RAM中,並設置CPU從這個內部RAM的起始地址開始啓動執行。另外一種方法是Flash控制器可以把Nand Flash的前4k數據的地址映射到系統總線的某個地址上,並設定CPU從這個地址開始啓動執行。這兩種方法都是硬件來完成的。
三、Bootloader分爲兩個部分,第一部分是彙編代碼且不作壓縮,第二部分是C代碼且有壓縮的。Bootloader開始執行時,第一部分彙編代碼先負責初始化CPU、PLL、DDR、Cache等硬件,讓CPU和內存可以穩定運行,而後解壓第二部分的Image,並拷貝到到內存執行。第二部分C代碼完成串口、flash、網口等驅動的加載,並構建一個shell環境來接受用戶輸入。注意,在整個Bootloader運行其間CPU的MMU是沒有被初始化的,全部的地址訪問都是採用物理地址直接訪問的。
四、在完成Bootloader初始化後,根據代碼中設定的內核區物理地址,Bootloader會把內核區壓縮後的Linux鏡像拷貝到內存中並解壓。同時準備好內核的啓動參數,如:console=ttyS0,115200 root=31:2 mtdparts=ar7100-nor0:196608(boot),835236(kernel),-(rootfs),這裏主要是把Bootloader裏設置的MTD分區信息傳遞給內核,還有須要加載的根文件系統。最後跳轉到內核入口開始運行。
五、Linux內核代碼開始執行,會先進行內核各個子系統初始化,並完成對MMU的初始化。MMU是CPU中的一個單元,它跟操做系統一塊兒配合完成從虛擬地址到物理地址的轉換。若是CPU帶有MMU單元,則CPU執行單元發出的內存地址將被MMU截獲,從CPU到MMU的地址稱爲虛擬地址,而MMU將這個地址翻譯成另外一個地址發到CPU芯片的外部地址引腳上,這個地址稱爲物理地址。在這個過程當中Linux內核會維護頁表結構,它保存着內核和進程的虛擬地址到物理地址的映射,而MMU則經過Linux內核頁表去完成地址翻譯和保護工做。
六、接下來Linux內核會掛載根文件系統,要掛載的根文件系統是經過內核啓動參數來獲取的。這裏有一個問題,根文件系統一般表示爲一個Linux文件系統下的某個MTD設備,但在加載根文件系統前Linux尚未一個文件系統,那它怎樣經過訪問文件系統中的MTD設備來加載根文件系統呢?事實上,根文件系統的安裝分爲兩個階段,首先Linux內核會安裝一個特殊的RootFS文件系統,該文件系統僅提供一個做爲初始安裝點的空目錄,而後Linux內核再在空目錄上安裝一個真正的根目錄。Linux內核對Flash的訪問都是經過MTD子系統來進行的,它抽象了對於各類Flash設備的訪問,提供統一的接口。
七、Linux內核繼續初始化各類類型的驅動程序,完成以後會啓動第一個應用程序,它的進程ID爲1。這個應用程序能夠由內核啓動參數傳入,若是沒有則會默認執行/sbin/init。init進程會讀取配置文件/etc/inittab,根據配置文件的內容它會完成兩個工做,執行rcS和啓動Shell。至此,Linux系統已經啓動完成,給用戶提供了一個Shell的交互環境,後續的行爲就取決於用戶的輸入或者系統特定應用的加載。