UBOOT
第一階段是從存儲介質(zhì)中讀取小部分程序到cpu中,這部分程序要完成引導(dǎo)linux所用的硬件的初始化,以及加載uboot其余程序到RAM中;
第二階段是繼續(xù)初始化必備硬件,加載linux鏡像到RAM中,把執(zhí)行權(quán)限交給linux,完成使命。
KERNEL
當(dāng)u-boot開始執(zhí)行bootcmd命令,就進(jìn)入linux內(nèi)核啟動階段
與u-boot類似,普通Linux內(nèi)核的啟動過程也可以分為兩個階段,但針對壓縮了的內(nèi)核如uImage就要包括內(nèi)核自解壓過程了。第一階段為內(nèi)核自解壓過程,第二階段主要工作是設(shè)置ARM處理器工作模式、使能MMU、設(shè)置一級頁表等,而第三階段則主要為C代碼,包括內(nèi)核初始化的全部工作,下面是詳細(xì)介紹。
一、Linux內(nèi)核自解壓過程
內(nèi)核壓縮和解壓縮代碼都在目錄kernel/arch/arm/boot/compressed,編譯完成后將產(chǎn)生head.o、misc.o、piggy.gzip.o、vmlinux、decompress.o這幾個文件,head.o是內(nèi)核的頭部文件,負(fù)責(zé)初始設(shè)置;misc.o將主要負(fù)責(zé)內(nèi)核的解壓工作,它在head.o之后;piggy.gzip.o是一個中間文件,其實是一個壓縮的內(nèi)核(kernel/vmlinux),只不過沒有和初始化文件及解壓文件鏈接而已;
二、Linux內(nèi)核啟動第一階段stage1
承接上文,這里所以說的第一階段stage1就是內(nèi)核解壓完成并出現(xiàn)Uncompressing Linux...done,booting the kernel.之后的階段。該部分代碼實現(xiàn)在arch/arm/kernel【或者kernel-3.18\arch\arm64\kernel】的?head.S中,該文件中的匯編代碼通過查找處理器內(nèi)核類型和機(jī)器碼類型調(diào)用相應(yīng)的初始化函數(shù),再建立頁表,最后跳轉(zhuǎn)到start_kernel()函數(shù)開始內(nèi)核的初始化工作。
三、Linux內(nèi)核啟動第二階段stage2
start_kernel函數(shù)是進(jìn)入系統(tǒng)內(nèi)核初始化后的入口函數(shù),它主要完成剩余的與硬件平臺相關(guān)的初始化工作,在進(jìn)行一系列與內(nèi)核相關(guān)的初始化后,調(diào)用第一個用戶進(jìn)程-?init?進(jìn)程并等待用戶進(jìn)程的執(zhí)行,這樣整個?Linux內(nèi)核便啟動完畢

四、掛載根文件系統(tǒng)
根文件系統(tǒng)至少包括以下目錄:
?/etc/:存儲重要的配置文件。
?/bin/:存儲常用且開機(jī)時必須用到的執(zhí)行文件。
?/sbin/:存儲著開機(jī)過程中所需的系統(tǒng)執(zhí)行文件。
?/lib/:存儲/bin/及/sbin/的執(zhí)行文件所需的鏈接庫,以及Linux的內(nèi)核模塊。
?/dev/:存儲設(shè)備文件。
? 注:五大目錄必須存儲在根文件系統(tǒng)上,缺一不可。
Linux內(nèi)核啟動后的最后一個動作,就是從根文件系統(tǒng)上找出并執(zhí)行init服務(wù)。Linux內(nèi)核會依照下列的順序?qū)ふ襥nit服務(wù):
1)/sbin/是否有init服務(wù)
2)/etc/是否有init服務(wù)
3)/bin/是否有init服務(wù)
4)如果都找不到最后執(zhí)行/bin/sh
找到init服務(wù)后,Linux會讓init服務(wù)負(fù)責(zé)后續(xù)初始化系統(tǒng)使用環(huán)境的工作,init啟動后,就代表系統(tǒng)已經(jīng)順利地啟動了linux內(nèi)核。啟動init服務(wù)時,init服務(wù)會讀取/etc/inittab文件,根據(jù)/etc/inittab中的設(shè)置數(shù)據(jù)進(jìn)行初始化系統(tǒng)環(huán)境的工作。/etc/inittab定義init服務(wù)在linux啟動過程中必須依序執(zhí)行以下幾個Script:
?/etc/rc.d/rc.sysinit
?/etc/rc.d/rc
/etc/rc.d/rc.local
/etc/rc.d/rc.sysinit主要的功能是設(shè)置系統(tǒng)的基本環(huán)境,當(dāng)init服務(wù)執(zhí)行rc.sysinit時 要依次完成下面一系列工作:
(1)啟動udev
(2)設(shè)置內(nèi)核參數(shù)
執(zhí)行sysctl –p,以便從/etc/sysctl.conf設(shè)置內(nèi)核參數(shù)
(3)設(shè)置系統(tǒng)時間
將硬件時間設(shè)置為系統(tǒng)時間
(4)啟用交換內(nèi)存空間
執(zhí)行swpaon –a –e,以便根據(jù)/etc/fstab的設(shè)置啟用所有的交換內(nèi)存空間。
(5)檢查并掛載所有文件系統(tǒng)
檢查所有需要掛載的文件系統(tǒng),以確保這些文件系統(tǒng)的完整性。檢查完畢后以可讀可寫的方式掛載文件系統(tǒng)。
(6)初始化硬件設(shè)備
????? Linux除了在啟動內(nèi)核時以靜態(tài)驅(qū)動程序驅(qū)動部分的硬件外,在執(zhí)行rc.sysinit時,也會試著驅(qū)動剩余的硬件設(shè)備。rc.sysinit驅(qū)動的硬件設(shè)備包含以下幾項:
??a)定義在/etc/modprobe.conf的模塊
? b)ISA PnP的硬件設(shè)備
? c)USB設(shè)備
(7)初始化串行端口設(shè)備
?Init服務(wù)會管理所有的串行端口設(shè)備,比如調(diào)制解調(diào)器、不斷電系統(tǒng)、串行端口控制臺等。Init服務(wù)則通過rc.sysinit來初始化linux的串行端口設(shè)備。當(dāng)rc.sysinit發(fā)現(xiàn)linux才能在這/etc/rc.serial時,才會執(zhí)行/etc/rc.serial,借以初始化所有的串行端口設(shè)備。因此,你可以在/etc/rc.serial中定義如何初始化linux所有的串行端口設(shè)備。
(8)清除過期的鎖定文件與IPC文件
(9)建立用戶接口
在執(zhí)行完3個主要的RC Script后,init服務(wù)的最后一個工作,就是建立linux的用戶界面,好讓用戶可以使用linux。此時init服務(wù)會執(zhí)行以下兩項工作:
(10)建立虛擬控制臺
?Init會在若干個虛擬控制臺中執(zhí)行/bin/login,以便用戶可以從虛擬控制臺登陸linux。linux默認(rèn)在前6個虛擬控制臺,也就是tty1~tty6,執(zhí)行/bin/login登陸程序。當(dāng)所有的初始化工作結(jié)束后,cpu_idle()函數(shù)會被調(diào)用來使系統(tǒng)處于閑置(idle)狀態(tài)并等待用戶程序的執(zhí)行。至此,整個Linux內(nèi)核啟動完畢。整個過程見圖4。
