http://blog.csdn.net/YEYUANGEN/article/details/37901567
2014.07
圖1 linux系統(tǒng)過程big view
MBR 中的主引導(dǎo)加載程序是一個 512 字節(jié)大小的映像,其中包含程序代碼和一個小分區(qū)表(參見圖 2)。前 446 個字節(jié)是主引導(dǎo)加載程序,其中包含可執(zhí)行代碼和錯誤消息文本。接下來的 64 個字節(jié)是分區(qū)表,其中包含 4 個分區(qū)的記錄(每個記錄的大小是 16 個字節(jié))。MBR 以兩個特殊數(shù)字的字節(jié)(0xAA55)結(jié)束。這個數(shù)字會用來進(jìn)行 MBR 的有效性檢查。
次引導(dǎo)加載程序(第二階段引導(dǎo)加載程序)可以更形象地稱為內(nèi)核加載程序。這個階段的任務(wù)是加載 Linux 內(nèi)核和可選的初始 RAM 磁盤。
/boot/grub
目錄中包含了 stage1
、stage1.5
和stage2
引導(dǎo)加載程序,以及很多其他加載程序(例如,CR-ROM 使用的是 iso9660_stage_1_5
)。
關(guān)于 GRUB,很好的一件事情是它包含了有關(guān) Linux 文件系統(tǒng)的知識。GRUB 不像 LILO 一樣使用裸扇區(qū),而是可以從 ext2 或 ext3 文件系統(tǒng)中加載 Linux 內(nèi)核。它是通過將兩階段的引導(dǎo)加載程序轉(zhuǎn)換成三階段的引導(dǎo)加載程序來實現(xiàn)這項功能的。階段 1 (MBR)引導(dǎo)了一個階段 1.5 的引導(dǎo)加載程序,它可以理解包含 Linux 內(nèi)核映像的特殊文件系統(tǒng)。這方面的例子包括reiserfs_stage1_5
(要從 Reiser 日志文件系統(tǒng)上進(jìn)行加載)或 e2fs_stage1_5
(要從 ext2 或 ext3 文件系統(tǒng)上進(jìn)行加載)。當(dāng)階段 1.5 的引導(dǎo)加載程序被加載并運行時,階段 2 的引導(dǎo)加載程序就可以進(jìn)行加載了。
當(dāng)階段 2 加載之后,GRUB 就可以在請求時顯示可用內(nèi)核列表(在 /etc/grub.conf
中進(jìn)行定義,同時還有幾個軟符號鏈接/etc/grub/menu.lst
和 /etc/grub.conf
)。我們可以選擇內(nèi)核甚至修改附加內(nèi)核參數(shù)。另外,我們也可以使用一個命令行的 shell 對引導(dǎo)過程進(jìn)行高級手工控制。
將第二階段的引導(dǎo)加載程序加載到內(nèi)存中之后,就可以對文件系統(tǒng)進(jìn)行查詢了,并將默認(rèn)的內(nèi)核映像和 initrd
映像加載到內(nèi)存中。當(dāng)這些映像文件準(zhǔn)備好之后,階段 2 的引導(dǎo)加載程序就可以調(diào)用內(nèi)核映像了。
圖3 linux內(nèi)核i386引導(dǎo)函數(shù)流程
通過調(diào)用 start_kernel
,會調(diào)用一系列初始化函數(shù)來設(shè)置中斷,執(zhí)行進(jìn)一步的內(nèi)存配置,并加載初始 RAM 磁盤。最后,要調(diào)用kernel_thread
(在 arch/i386/kernel/process.c
中)來啟動 init
函數(shù),這是第一個用戶空間進(jìn)程(user-space process)。最后,啟動空任務(wù),現(xiàn)在調(diào)度器就可以接管控制權(quán)了(在調(diào)用 cpu_idle
之后)。通過啟用中斷,搶占式的調(diào)度器就可以周期性地接管控制權(quán),從而提供多任務(wù)處理能力。
在內(nèi)核引導(dǎo)過程中,初始 RAM 磁盤(initrd
)是由階段 2 引導(dǎo)加載程序加載到內(nèi)存中的,它會被復(fù)制到 RAM 中并掛載到系統(tǒng)上。這個initrd
會作為 RAM 中的臨時根文件系統(tǒng)使用,并允許內(nèi)核在沒有掛載任何物理磁盤的情況下完整地實現(xiàn)引導(dǎo)。由于與外圍設(shè)備進(jìn)行交互所需要的模塊可能是 initrd
的一部分,因此內(nèi)核可以非常小,但是仍然需要支持大量可能的硬件配置。在內(nèi)核引導(dǎo)之后,就可以正式裝備根文件系統(tǒng)了(通過 pivot_root
):此時會將 initrd
根文件系統(tǒng)卸載掉,并掛載真正的根文件系統(tǒng)。
函數(shù) decompress_kernel
就是顯示我們通??吹降慕鈮合⒌牡胤剑?/p>
Uncompressing Linux... Ok, booting the kernel.
initrd
函數(shù)讓我們可以創(chuàng)建一個小型的 Linux 內(nèi)核,其中包括作為可加載模塊編譯的驅(qū)動程序。這些可加載的模塊為內(nèi)核提供了訪問磁盤和磁盤上的文件系統(tǒng)的方法,并為其他硬件提供了驅(qū)動程序。由于根文件系統(tǒng)是磁盤上的一個文件系統(tǒng),因此 initrd
函數(shù)會提供一種啟動方法來獲得對磁盤的訪問,并掛載真正的根文件系統(tǒng)。在一個沒有硬盤的嵌入式環(huán)境中,initrd
可以是最終的根文件系統(tǒng),或者也可以通過網(wǎng)絡(luò)文件系統(tǒng)(NFS)來掛載最終的根文件系統(tǒng)
當(dāng)內(nèi)核被引導(dǎo)并進(jìn)行初始化之后,內(nèi)核就可以啟動自己的第一個用戶空間應(yīng)用程序了。這是第一個調(diào)用的使用標(biāo)準(zhǔn) C 庫編譯的程序。在此之前,還沒有執(zhí)行任何標(biāo)準(zhǔn)的 C 應(yīng)用程序。
在桌面 Linux 系統(tǒng)上,第一個啟動的程序通常是 /sbin/init
。但是這不是一定的。很少有嵌入式系統(tǒng)會需要使用 init
所提供的豐富初始化功能(這是通過 /etc/inittab
進(jìn)行配置的)。在很多情況下,我們可以調(diào)用一個簡單的 shell 腳本來啟動必需的嵌入式應(yīng)用程序。
聯(lián)系客服