計算機在啟動時都是先加電,然後進行硬體檢測並引導作業系統的初始化程式,然後作業系統的初始化程式程負責讀入系統核心並建產系統的執行環境.一這過程相對來說比較復而且與cpu體系結構相關,這裡我們通過linux並以i386的體系結構對這一過程進行較為詳細的說明.
一、硬體檢測
當 機器加電後它首先執行bios(基本輸入輸出系統)中的**,bios首先執行加電自檢程式(post),當自檢通過程便完成了硬體的啟動。post程式 通過對記憶體及其他硬體的裝置的診斷檢測確定硬體的存在並可正確操作。bios是固化在晶元裡的程式,執行這一過程一般只需要幾秒鐘。當自檢完成後 bios按照系統coms中設定的啟動順序搜尋有效的啟動驅動器(這裡我們以硬碟為例),並讀入系統引導扇區,並將系統控制權交給引導程式。
二、載入和執行引導程式
系 統引導程式主要是把系統核心裝載到記憶體,啟動盤必須在第乙個邏輯磁軌上包含引導記錄。這512個位元組的扇區又被稱作是引導扇區,在系統完成加電自檢後, bios從啟動盤中將引導扇區讀入到記憶體中。引導記錄中包含了一些磁碟的物理特性的引數。在引導扇區被讀入記憶體後,bios就能從這裡讀取到啟動盤的物理 引數。一旦引導記錄載入完畢,bios就交出系統的執行控制權,跳轉到引導程式
的頭部執行。引導記錄開頭是一條無條件轉移指令,它將立即跳轉到位址0x03e執行引導程式,在引導扇區中這個引導程式將從磁碟中讀出其他幾個更為複雜的程式並由它們載入系統核心。
linux的 引導程式由彙編**檔案arch/i386/boot/bootsect.s生成,它利用對bios功能的呼叫將 arch/i386/boot/下的setup.s檔案和核心映象載入到記憶體。i386的體系結構的cpu分保護模式和實模式兩種,在實模式下只能使用低 端的640k記憶體。系統在載入引導程式時cpu是處在實模式下,而現在的核心映象檔案一般都超過了640k的限制,即使是經過壓縮過的核心映象,這個核心 映象檔案通常是bzimage,我們在編譯核心時通常要用到這個檔案。由於bzimage超出了640k這一限制,所以linux設 計了乙個 bootsect_helper子程式(定義在arch/i386/boot/setup.s中),引導程式通過迴圈呼叫bootsect_helper 將核心映象一塊一塊的裝入記憶體,當核心載入完畢,系統跳轉到setup.s的開始位置開始執行,setup.s仍在實模式下執行,主要功能是設定系統引數 (如:記憶體、磁碟等),並為進入保護模式做準備,最後進入到保護模式並跳轉到核心映象檔案的頭部開始執行核心。這裡提一下有關linux的 引導程式 lilo和grub,lilo和grub可以引導多個系統,如果機器上要裝多系統的話一般都會用到它們,這一引導程式也儲存在引導扇區中或者存放在主引導 記錄中(mbr),lilo和grub都許允使用者自己配置,它們在系統安裝時建立了關於系統核心占用磁碟資料塊的位置對照表。當使用者選擇啟動linux系統後,同樣也跳轉到setup.s上執行。
三、核心初始化
當setup.s執行完後,cpu進行保護模式,並開始執行核心,如果核心是經過壓縮的,那麼首先執行 arch/i386/boot/compressed目錄下的head.s建立堆疊並解壓核心映象檔案,然後再轉入arch/i386/kernel下的head.s。如果沒有壓縮則直接轉到arch/i386/kernel下的head.s開始執行。arch/i386/kernel/head.s程式負責資料區(bbs)、中斷描述表(idt)、段描述表(gdt)、頁表和暫存器的初始化。最後進入start_kernel()模組。
此時系統執行在核心模式(0級別)下,轉入到init/main.c中的start_kernel()。start_kernel()繼續其他方面的初始化工作,主要是初始化系統的核心資料結構,主要包括:
setup_arch():執行與體系結構相關的設定。
trap_init():設定各種入口位址。
init_irq():初始化irq中斷處理機制。
sched_init():設定並啟動第乙個程序init_task()。
softirq_init():對軟中斷子系統進行初始化。
console_init():初始化控制台、顯示器.
init_modules():初始化kernel_module。
fork_init():定義系統最大程序數.
最後進入rest_init()函式並呼叫kernel_thread()建立init核心執行緒,進行系統配置。
init核心執行緒占用程序描述表的第一項,由它來建立其他完成系統初始他的程序。
init核心執行緒首先要銷定核心,然後呼叫do_basic_setup()來初始化外部裝置及載入驅動程式。主
要的初始化工作包括:
pci匯流排初始化。
網路初始化。
檔案系統初始化。
載入檔案系統。
在do_basic_setup()呼叫完成後,init()會釋放初始化函式據占用的記憶體,並且開啟/dev/console
裝置重新定向控制台,用系統呼叫execve來執行使用者態程式/sbin/init。至此,linux的核心初始化工作完成。
下面的工作就由使用者態的/sbin/init程式來完成。init程式程讀取/etc/inittab檔案來決定它具體的工作。在inittab中比較重要的幾條是:
id:5:initdefault 決定作業系統啟動時預設的執行級別(這裡說講的是系統的執行級別,而不同於cpu的級別)
si:sysinit:/etc/rc.d/rc.sysinit 執行/etc/rc.d/rc.sysinit的指令碼。rc.sysinit主要的工作是 啟用交換分割槽、檢查磁碟、載入硬體模組。
1:2345:respawn:/sbin/mingetty tty1 顯示登入介面
至此,整個系統的引導過程就完成了
Linux2 6核心啟動分析
我們已知u boot的終極目的是啟動核心,那麼核心啟動的開始必定是u boot傳入的引數。開啟armlinux.c 發現有一行的 為 thekernel 0,bd bi arch number,bd bi boot params 帶入三個引數 第乙個引數是0,第二個引數是機器id,第三個引數是引數所...
Linux 2 6核心編譯,核心公升級
本文描述了在fc8下公升級linux核心為2.6.25的詳細步驟.1.首先從如下 得到linux 2.6.25.2.然後在 usr src下untar這個包.tar xjfv linux 2.6.25.tar.bz2 3.配置核心 cd usr src linux 2.6.25 make mrpro...
Linux 2 6 核心驅動移植
隨著 linux 2.6的發布,由於2.6核心做了教的改動,各個裝置的 驅動程式在不同程度上要進行改寫。為了方便各位linux愛好者我把自己整理的這分文件share出來。該文當列舉了2.6核心同以前版本的絕大多數變化,可惜的是由於時間和精力有限沒有詳細列出各個函式的用法。1 使用新的入口 必須包含 ...