ARM Linux從Bootloader、kernel到filesystem啓動流程

轉自:http://www.veryarm.com/1491.htmlhtml

 

ARM Linux啓動流程大體爲:bootloader ---->kernel---->root filesystem。bootloader 是一上電就拿到cpu 的控制權的,而bootloader實現了硬件的初始化。bootloader儼然就成了Power on 以後」第一個吃螃蟹」的代碼。linux

談到這就得想到硬件機制是如何知足這個功能的了。CPU內部通常都集成小容量的SRAM (又叫stapping stone,墊腳石),當系統一上電,NAND controler 就自動地將Nand flash 裏的前內容複製到墊腳石裏,而PC 指針一上電就指向墊腳石的起始地址0x00000000。這樣這一部分的代碼就能夠獲得執行。因此,這一部分的代碼就是 bootloader 部分,那一上電bootloader 不就能夠獲得運行了麼?事實確實如此,在嵌入式Linux的軟件系統中,nandflash前面一部分代碼每每就是bootloader ,而後就是kernel, 再接着就是根文件系統。bootstrap

說了這麼多,好像都沒說到啓動流程啊,彆着急,咱慢慢談,所謂磨刀不誤砍柴工嘛。app

要說啓動流程,若是隻是簡單的介紹從哪到哪,誰幹了啥啥,獲得的結果可能只是只知其然不知其因此然。我的以爲隨着CPU的PC指針走,循着代碼的足跡才能把整個流程理清楚,當找到了代碼的執行過程,再分析一下代碼,天然知道了哪一個部分完成了哪些事,更重要的是爲代碼的移植打下了堅實的基礎。天然這個過程是痛苦和枯燥的,甚至是看代碼看了幾天也沒弄明白,不過這也是一種鍛鍊。函數

bootloder 

前面說了,bootloader一上電就拿到了cpu 的使用權,它固然得幹一些初始化的工做啊,好比關閉看門狗、設置cpu 的運行模式、設置堆棧等等比較急迫的事情。固然還要對主板的一些其餘硬件進行簡單的初始化,好比外部DDR內存、網卡、顯示屏、nand flash等等的初始化工做,最後還要負責把Linux內核加載到內存中。正所謂責任和權力是並存的嘛,你獲得了權益,固然就得付出。當bootloader 完成它的使命以後就會把cpu 的使用權交給下一部分代碼:kernel 。工具

kernel

在討論kernel 是如何啓動以前,先了解kernel 的組成結構以及是如何得來的。下面這張圖是內核編譯即將結束時顯示的信息:spa

11f36c7a535f07454fa15220c9e2cf87

 

下面的這張圖說明了上面的編譯過程,指針

9ae59fb6dc568a9fd3838b9d87f004cc

能夠看到,當內核源文件編譯連接成 vmlinux 文件之後還進行了幾個模塊的編譯和連接。其中調試

(1)vmlinux 是ELF格式的object文件,這種文件只是各個源代碼通過鏈接之後的獲得的文件,並不能在arm平臺上運行htm

(2)通過objcopy這個工具轉換之後,獲得了二進制格式文件Image,Image文件相比於vmlinux 文件,除了格式不一樣之外,還被去除了許多註釋和調試的信息

(3)Image文件通過壓縮之後獲得了piggy.gz ,這個文件僅僅是Image的壓縮版,並沒有其餘不一樣

(4)接着編譯生成另外幾個模塊文件misc.o、big_endian.o、head.o、head-xscale.o,這幾個文件組成一個叫 bootstrap loader 的組件,又叫引導程序。編譯生成 piggy.o 文件。

(5)最後piggy.o文件和bootstrap loader 組成一個bootable kernel Image 文件(可啓動文件)。

能夠看到最後獲得的可執行文件就是上圖最右邊那個,這也是咱們最後燒寫到開發板的鏡像。其中piggy.o 就是內核鏡像,而剩下的幾個文件就組成了引導程序。

下面開始討論CPU的流轉過程,仍是用一個圖來展現:

294474c84d19f650fe64c3bbbc49ee19

從上圖能夠看出,系統一上電就開始執行bootloader。當bootloader 執行完之後,把控制權交給了引導程序的head.o 文件裏的start 標號處,當引導程序完成引導工做之後就將控制權轉給真正的內核的head.o 文件裏的start 標號處。這裏就是內核的入口點,最後內核的head.o將控制交給main.o 的start_kernel 函數。這樣,經過查看相應的代碼就能夠知道這些代碼到底完成了哪些工做。在這裏咱們能夠找到相應的代碼,分析一下,看它們到底完成哪些事。下面是個人分析結果

引導程序:

head.o從bootloader接過控制權,並完成以下任務:

  1. 使能 I/D caches ,關閉中斷 , 創建C運行環境(即設置堆棧)由 head.o 和head-xscal.o 完成
  2. 解壓縮並重定位代碼 ,由misc.o 完成
  3. 其餘硬件相關的設置,如big.endian.o 爲cpu設置大端模式

內核入口點:從引導程序接過控制權,完成以下任務

  1. 檢查有效的cpu 和cpu的信息
  2. 建立初始化頁表入口
  3. 使能MMU
  4. 檢測錯誤並報告
  5. 跳轉到內核自己 main.c 文件裏的 start_kernel()函數

內核啓動:

從 kernel 的head.o接過控制權,開始內核的啓動,在這裏完成內核的初始化,如內核各個子系統的初始化。

root filesystem

到此止,kernel完成了系統硬件探測及硬件驅動的初始化,內核空間的相關工做已經完成,開始向用戶空間轉移,內核空間經過一個間接的initrd(一個虛擬的文件系統)向用戶空間過分,而後開始掛載根文件系統了,其過程:initrd ----> /sbin/init ----> /etc/inittab

initrd是一個虛擬的文件系統,裏面有lib、bin、sbin、usr、proc、sys、var、dev、boot等一些目錄,其目錄有點像真的/,因此咱們稱之爲虛擬的根文件系統,做用就是將kernel和真的根文件系統創建關聯關係,讓kernel去initrd中加載根文件系統所須要的驅動程序,並以讀寫的方式掛載根文件系統,並讓執行用戶當中第一個進程init

init執行完畢之後會啓動系統內的/etc/inittab文件,來完成系統系統的初始化工做。

相關文章
相關標籤/搜索