ARM Linux啟動流程大致為:bootloader---->kernel---->root filesystem。bootloader 是一上電就拿到cpu 的控制權(quán)的,而bootloader實現(xiàn)了硬件的初始化。bootloader儼然就成了Power on 之后”第一個吃螃蟹”的代碼。
談到這就得想到硬件機制是如何滿足這個功能的了。CPU內(nèi)部一般都集成小容量的SRAM(又叫stapping stone,墊腳石),當(dāng)系統(tǒng)一上電,NAND controler 就自動地將Nand flash 里的前內(nèi)容復(fù)制到墊腳石里,而PC 指針一上電就指向墊腳石的起始地址0x00000000。這樣這一部分的代碼就可以得到執(zhí)行。所以,這一部分的代碼就是 bootloader 部分,那一上電bootloader 不就可以得到運行了么?事實確實如此,在嵌入式Linux的軟件系統(tǒng)中,nandflash前面一部分代碼往往就是bootloader ,然后就是kernel, 再接著就是根文件系統(tǒng)。
說了這么多,好像都沒說到啟動流程啊,別著急,咱慢慢談,所謂磨刀不誤砍柴工嘛。
要說啟動流程,如果只是簡單的介紹從哪到哪,誰干了啥啥,得到的結(jié)果可能只是只知其然不知其所以然。個人覺得隨著CPU的PC指針走,循著代碼的足跡才能把整個流程理清楚,當(dāng)找到了代碼的執(zhí)行過程,再分析一下代碼,自然知道了哪個部分完成了哪些事,更重要的是為代碼的移植打下了堅實的基礎(chǔ)。自然這個過程是痛苦和枯燥的,甚至是看代碼看了幾天也沒弄明白,不過這也是一種鍛煉。
bootloder
前面說了,bootloader一上電就拿到了cpu 的使用權(quán),它當(dāng)然得干一些初始化的工作啊,比如關(guān)閉看門狗、設(shè)置cpu 的運行模式、設(shè)置堆棧等等比較急迫的事情。當(dāng)然還要對主板的一些其他硬件進行簡單的初始化,比如外部DDR內(nèi)存、網(wǎng)卡、顯示屏、nand flash等等的初始化工作,最后還要負責(zé)把Linux內(nèi)核加載到內(nèi)存中。正所謂責(zé)任和權(quán)力是并存的嘛,你得到了權(quán)益,當(dāng)然就得付出。當(dāng)bootloader 完成它的使命之后就會把cpu 的使用權(quán)交給下一部分代碼:kernel 。
kernel
在討論kernel 是如何啟動之前,先了解kernel 的組成結(jié)構(gòu)以及是如何得來的。下面這張圖是內(nèi)核編譯即將結(jié)束時顯示的信息:
下面的這張圖說明了上面的編譯過程,
可以看到,當(dāng)內(nèi)核源文件編譯鏈接成 vmlinux 文件以后還進行了幾個模塊的編譯和鏈接。其中(1)vmlinux 是ELF格式的object文件,這種文件只是各個源代碼經(jīng)過連接以后的得到的文件,并不能在arm平臺上運行。(2)經(jīng)過objcopy這個工具轉(zhuǎn)換以后,得到了二進制格式文件Image,Image文件相比于vmlinux 文件,除了格式不同以外,還被去除了許多注釋和調(diào)試的信息。(3)Image文件經(jīng)過壓縮以后得到了piggy.gz ,這個文件僅僅是Image的壓縮版,并無其他不同。(4)接著編譯生成另外幾個模塊文件misc.o、big_endian.o、head.o、head-xscale.o,這幾個文件組成一個叫bootstrap loader的組件,又叫引導(dǎo)程序。編譯生成 piggy.o 文件。(5)最后piggy.o文件和bootstrap loader 組成一個bootable kernel Image 文件(可啟動文件)。
可以看到最后得到的可執(zhí)行文件就是上圖最右邊那個,這也是我們最后燒寫到開發(fā)板的鏡像。其中piggy.o 就是內(nèi)核鏡像,而剩下的幾個文件就組成了引導(dǎo)程序。
下面開始討論CPU的流轉(zhuǎn)過程,還是用一個圖來展示:
從上圖可以看出,系統(tǒng)一上電就開始執(zhí)行bootloader。當(dāng)bootloader 執(zhí)行完以后,把控制權(quán)交給了引導(dǎo)程序的head.o 文件里的start 標號處,當(dāng)引導(dǎo)程序完成引導(dǎo)工作以后就將控制權(quán)轉(zhuǎn)給真正的內(nèi)核的head.o 文件里的start 標號處。這里就是內(nèi)核的入口點,最后內(nèi)核的head.o將控制交給main.o 的start_kernel 函數(shù)。這樣,通過查看相應(yīng)的代碼就可以知道這些代碼到底完成了哪些工作。在這里我們可以找到相應(yīng)的代碼,分析一下,看它們到底完成哪些事。下面是我的分析結(jié)果:
引導(dǎo)程序:
head.o從bootloader接過控制權(quán),并完成如下任務(wù):
1.使能 I/D caches ,關(guān)閉中斷 , 建立C運行環(huán)境(即設(shè)置堆棧)由 head.o 和head-xscal.o 完成
2.解壓縮并重定位代碼 ,由misc.o 完成
3.其他硬件相關(guān)的設(shè)置,如big.endian.o 為cpu設(shè)置大端模式
內(nèi)核入口點:從引導(dǎo)程序接過控制權(quán),完成如下任務(wù)
1.檢查有效的cpu 和cpu的信息
2.創(chuàng)建初始化頁表入口
3.使能MMU
4.檢測錯誤并報告
5.跳轉(zhuǎn)到內(nèi)核本身 main.c 文件里的 start_kernel()函數(shù)
內(nèi)核啟動:
從 kernel 的head.o接過控制權(quán),開始內(nèi)核的啟動,在這里完成內(nèi)核的初始化,如內(nèi)核各個子系統(tǒng)的初始化。
root filesystem
到此止,kernel完成了系統(tǒng)硬件探測及硬件驅(qū)動的初始化,內(nèi)核空間的相關(guān)工作已經(jīng)完成,開始向用戶空間轉(zhuǎn)移,內(nèi)核空間通過一個間接的initrd(一個虛擬的文件系統(tǒng))向用戶空間過度,然后開始掛載跟文件系統(tǒng)了,其過程:initrd---->/sbin/init---->/etc/inittab。
initrd是一個虛擬的文件系統(tǒng),里面有l(wèi)ib、bin、sbin、usr、proc、sys、var、dev、boot等一些目錄,其目錄有點像真的/,所以我們稱之為虛擬的根文件系統(tǒng),作用就是將kernel和真的根文件系統(tǒng)建立關(guān)聯(lián)關(guān)系,讓kernel去initrd中加載根文件系統(tǒng)所需要的驅(qū)動程序,并以讀寫的方式掛載根文件系統(tǒng),并讓執(zhí)行用戶當(dāng)中第一個進程init。
init執(zhí)行完畢以后會啟動系統(tǒng)內(nèi)的/etc/inittab文件,來完成系統(tǒng)系統(tǒng)的初始化工作。
-
ARM
+關(guān)注
關(guān)注
134文章
9184瀏覽量
369619 -
嵌入式
+關(guān)注
關(guān)注
5096文章
19199瀏覽量
308173 -
Linux
+關(guān)注
關(guān)注
87文章
11353瀏覽量
210607
原文標題:嵌入式Linux從從Bootloader、kernel到filesystem啟動流程分析
文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
ARM嵌入式Linux系統(tǒng)開發(fā)詳解
嵌入式Linux系統(tǒng)開發(fā)基礎(chǔ)
![<b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b>系統(tǒng)開發(fā)基礎(chǔ)](https://file.elecfans.com/web2/M00/48/7E/pYYBAGKhtAmAawF0AABTn_Z4qrE364.jpg)
基于ARM9的嵌入式Linux開發(fā)流程的研究
基于ARM嵌入式Linux快速啟動
![基于<b class='flag-5'>ARM</b><b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b>快速<b class='flag-5'>啟動</b>](https://file.elecfans.com/web2/M00/49/C7/pYYBAGKhvF6ALdY7AABJBABz4OA387.png)
詳解bootloader的執(zhí)行流程與ARM Linux啟動過程分析
![詳解bootloader的執(zhí)行<b class='flag-5'>流程</b>與<b class='flag-5'>ARM</b> <b class='flag-5'>Linux</b><b class='flag-5'>啟動</b>過程分析](https://file1.elecfans.com//web2/M00/A7/19/wKgZomUMQmGATJLlAABw36rp0a4271.png)
如何使用ARM進行嵌入式linux的系統(tǒng)設(shè)計
![如何使用<b class='flag-5'>ARM</b>進行<b class='flag-5'>嵌入式</b><b class='flag-5'>linux</b>的系統(tǒng)設(shè)計](https://file.elecfans.com/web1/M00/90/FD/o4YBAFzPqxKASyqqAAWo83qf9vo274.png)
【嵌入式】基于ARM的嵌入式Linux開發(fā)總結(jié)
![【<b class='flag-5'>嵌入式</b>】基于<b class='flag-5'>ARM</b>的<b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b>開發(fā)總結(jié)](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
嵌入式linux和桌面linux的區(qū)別
![<b class='flag-5'>嵌入式</b><b class='flag-5'>linux</b>和桌面<b class='flag-5'>linux</b>的區(qū)別](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
嵌入式 Linux 啟動流程和 bootloader 介紹
![<b class='flag-5'>嵌入式</b> <b class='flag-5'>Linux</b> <b class='flag-5'>啟動</b><b class='flag-5'>流程</b>和 bootloader 介紹](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
嵌入式Linux專題(一)——嵌入式Linux系統(tǒng)構(gòu)成及啟動流程
![<b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b>專題(一)——<b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b>系統(tǒng)構(gòu)成及<b class='flag-5'>啟動</b><b class='flag-5'>流程</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評論