Linux內核啓動過程總結(圖文)

前些時間在學習linux內核的時候,有完整地看過linux內核啓動的代碼,但是可能是因爲彙編語言基礎不夠紮實,很多地方沒有理解到位,所以兩個月過去了,現在回頭看又覺得生疏了。不過我發現對啓動引導過程的整體理解非常有利於具體啓動代碼的理解和閱讀。所以就把《linux2.6內核標準教程中》一書中關於啓動引導過程的總結摘錄下來。以便在需要的時候看看。

啓動過程如下圖所示:

 

1、系統加電階段1

該階段完成了以下任務:系統加電後有BIOS進行加電自檢POST,檢查系統必備的引導設備是否存在,如內存、磁盤等關鍵硬件設備;然後讀取CMOS中的引導設備信息,從引導設備中讀取第一個扇區,該扇區包含着引導程序;在BIOS將引導設備第一個扇區的引導程序裝入內存後,由引導程序包操作系統的核心裝載到系統內存中。其中引導程序可以是一個很簡單,只佔一個扇區512字節,也可以很複雜如GRUB。2.6.x系列內核只支持GRUB、LILO等引導程序,廢除了bootsect的原有引導功能,所以我們以GRUB爲例來進行分析。

在引導程序GRUB被BIOS裝入到內存並獲得控制權之後,讀取/boot/grub.conf中的引導列表選擇默認要啓動的內核鏡像bzImage。根據bzImage中前512byte的bootsect中的setup、vmLinux.bib所佔扇區的大小,以及內核是否爲大內核鏡像(big kernel image)將bootsect放置到物理地址0x00090000,setup放到物理地址0x00090020,如果是大內核將vmLinux.bin放置到0x000100000,否則放置到0x00010000。在將內核搬到相應的地址後,引導程序跳到物理地址0x00090020,即setup所在的物理地址,開始執行setup代碼。

2、階段1——階段2

該階段有文件setup.S生成的代碼塊進行系統設備的探測,將探測到的相關信息保存到內存地址,在系統最終初始化時有系統使用。在按順序探測完設備後,跳轉到物理地址0x000100000,開始執行由src/arch/i386/boot/compressed /head.S生成的代碼塊。

3、階段2——階段3

該階段執行由 src/arch/i386/boot/compressed/head.S生成的代碼塊,該彙編代碼爲調用C語言函數設置相應的參數及棧指針後調用C函數decompress_kernel對壓縮的內核進行解壓縮,該函數按需要將解壓縮的內核片段放置到兩個不同的物理內存區域中,然後將head.S中名稱爲move。負責搬移的代碼段移動到物理地址0x00010000處,然後跳轉到該物理地址,執行代碼。

4、階段3——階段4

該階段執行復制到物理地址0x00010000的搬移代碼,該部分的搬移代碼將位於兩個物理區域的解壓縮內核代碼片段移動到0x00100000,此時物理地址0x00100000處包含解壓後的內核鏡像。

5、階段4——階段5

該階段搬移代碼執行完畢後,執行緊隨其後的跳轉指令,跳轉到物理地址0x00100000。執行位於src/arch/i386/kernel/head.S中的startup_32代碼段,開始進行系統核心的初始化過程。

6、階段5——系統完全啓動

該階段進行系統核心初始化,初始化過程由系統初始化進程init_task完成(也叫0號進程、idle進程)。該進程完成了系統內存管理子系統、進程管理子系統、中斷異常子系統、時間度量子系統等的初始化工作。最後該進程通過kernel_thread()創建了一個名爲init的內核線程,然後將0號進程調度器schedule(),釋放了處理器的使用權,成爲了系統的空閒(idle)進程。

在內核線程init獲得處理器後,首先完成對稱多處理器系統中應用處理器的初始化(對稱多處理器系統中,負責系統引導的處理器稱爲引導處理器BootStrap Processor,其他處理器稱爲應用處理器Application Process);然後掛載系統的根文件系統,完成系統總線網絡協議棧等的初始化;最後通過系統調用execve()開始執行用戶態程序/sbin/init,此時內核線程init轉換成了用戶進程。

該用戶態進程是系統中所有進程(除0號進程外)的祖先,它首先讀取系統的配置文件/etc/inittab,根據該配置文件完成系統的最終初始化。在RHEL5系統下,這些初始化包括:執行腳本文件/etc/rc.d/rc.sysinit完成系統環境的初始化,包括過去網絡參數,掛載進程文件系統proc(全稱爲process file system),內核2.6引入的用於描述系統設備層次結構的文件系統sys,掛載每個具體設備的驅動程序,設置系統時間和主機名。在需要對根文件系統進行檢測時調用fcsk檢查文件系統的一致性;根據文件/etc/inittab中指定的運行級別運行相應級別的啓動腳本,這些腳本通常負責控制一個後臺服務進程運行,每個運行級別的啓動腳本位於/etc/rc.d/rc<運行級別號>.d目錄中,如運行級別爲3的啓動腳本位於/etc/rc.d/rc3.d中;最後爲系統終端啓動一個getty進程,等待用戶登錄。(在RHEL5系統中,爲每個虛擬終端啓動一個mingetty進程,mingetty是getty的變體,專門針對虛擬終端進行了優化。)

 

發佈了18 篇原創文章 · 獲贊 8 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章