1,當系統上電或複位時,CPU會將PC指標賦值為一個特定的地址0xFFFF0並執行該地址處的指令。在PC機中,該地址位於BIOS中,它儲存在主板上的ROM或Flash中
2,BIOS運行時按照CMOS的設定定義的啟動裝置順序來搜尋處於活動狀態並且可以引導的裝置。若從硬碟啟動,BIOS會將硬碟MBR(主引導記錄)中的內容載入到RAM。MBR是一個512位元組大小的扇區,位於磁碟上的第一個扇區中(0道0柱面1扇區)。當MBR被載入到RAM中之後,BIOS就會將控制權交給MBR
3,主引導載入程式尋找並載入次引導載入程式。它在分區表中尋找使用中的磁碟分割,當找到一個使用中的磁碟分割時,掃描分區表中的其他分區,以確保它們都不是活動的。當這個過程驗證完成之後,就將 使用中的磁碟分割的引導記錄從這個裝置中讀入RAM中並執行它
4,次引導載入程式載入Linux核心和可選的初始RAM磁碟,將控制權交給Linux核心原始碼。
5,運行被載入的核心,並啟動使用者空間應用程式
另外,第5階段,它完成啟動核心並運行使用者空間的 init進程
當核心映像被載入到RAM之後,Bootloader的控制權被釋放,核心階段就開始了。核心映像並不是完全可直接執行的目標代碼,而是一個壓縮的zImage(小核心)或bzImage(大核心,b表示big)
但是,並非zImage和bzImage映像中的一切都被壓縮了,否則Bootloader把控制權交給菏澤哥核心映像它就傻了。實際上,映像中包含未被壓縮的部分,這部分中包含解壓縮程式,解壓縮程式會解壓映像中被壓縮的部分。zImage和bzImage都是用gzip壓縮的,它們不僅是一個壓縮檔,而且在這兩個檔案的開頭部分內嵌有gzip解壓縮代碼
當bzImage(用於i386映像)被調用時,它從/arch/i386/boot/head.S的start彙編常式開始執行。這個程式執行一些基本的硬體設定,並調用
/arch/i386/boot/compressed/head.S中的startup_32常式。startup_32程式設定一些基本的運行環境(如堆棧)後,清除BSS段,調用
/arch/i386/boot/compressed/misc.c中的decompress_kernel()C函數解壓核心。核心被解壓到記憶體之後,會調用
/arch/i386/kernel/head.S檔案中的startup_32常式,這個新的startup_32常式(稱為清除程式或進程0)會初始化頁表,並啟用記憶體分頁機制,接著為任何可選的浮點單位(FPU)檢測CPU的類型,並將其儲存起來供以後使用。這些都做完之後,/init/main.c中的start_kernel()函數被調用,進入與體繫結構無關的Linux核心部分
start_kernel()會調用一系列初始化函數來設定中斷,執行進一步的記憶體配置。之後,/arch/i386/kernel/process.c中kernel_thread()被調度以啟動第一個核心線程,該線程執行init()函數,而原執行序列會調用cpu_idle()等待調度
作為核心線程init()函數完成外設及驅動程式的載入和初始化,掛接根檔案系統。
init()開啟/dev/console裝置,重新導向stdin、stdout和stderr到控制台。之後,它搜尋檔案系統中的init程式(也可以由“init=”命令列參數指定init程式),並使用execve()系統調用執行init程式。搜尋init程式的順序為:/sbin/init、/etc/init、/bin/init和/bin/sh。在嵌入式系統中,多數情況下,可以傳給核心一個簡單的shell指令碼來啟動必需的嵌入式應用程式
至此,漫長的Linux核心引導和啟動過程就此結束,而init()對應的這個由start_kernel()建立的第一個線程也進入使用者模式