Linux的啟動流程(/etc/inittab)
1. 從BIOS到KERNEL
BIOS自檢->MBR(GRUB)->KERNEL->KERNEL自解壓->核心初始化->核心啟動
BIOS自檢
當電腦開機的時候,電腦會進入BIOS,BIOS的工作主要是偵測電腦的周邊配套裝置是否工作正常,如CPU的類型、速度、緩衝等
主板類型
記憶體的速度,容量
硬碟的大小,類型和工作模式
風扇速度等
主要是為了檢查這些裝置在開機的時候是否能通過檢測,如果能通過檢測,說明電腦可以正常的工作。
-----------------------------------------
一、載入啟動程式
BIOS自檢完成後,BIOS會根據使用者佈建的啟動順序來由那個裝置來啟動電腦的作業系統,這個裝置一般是硬碟。
也就是進入到硬碟的MBR地區(開機磁區),這個地區中的有512個位元組的大小,其中前446個位元組中儲存的程式是選擇開機磁碟分割,也就是電腦由 那個硬碟分區來載入開機的程式。那麼在這個446個位元組的空間中儲存的就是啟動程式,然後由這個小程式來載入儲存在其他位置的作業系統,也就是啟動 grub程式。
當找到啟動裝置(硬碟)時,第一階段所用的boot loader(存放在開機磁區)被裝載到RAM中並被執行。這裡的boot loader在大小上小於一個扇區的大小,也就是512位元組,而它的任務,就是載入第二階段的boot loader。
當負責第二階段的boot loader位於記憶體中並被執行時,通常會顯示一個一閃而過的螢幕,然後linux以及可選的初始化記憶體盤(一種臨時的根檔案系統,如果想得到具體的介 紹,請訪問http://likunarmstrong.bokee.com/5502266.html)會被裝載到儲存空間中。當系統鏡像被載入時,第二 階段的boot loader將把控制權轉交給核心鏡像,與此同時,核心開始自解壓並初始化。在這個階段,第二階段的boot loader會檢查系統的硬體,枚舉那些附加的硬體裝置,掛載根裝置,之後載入需要的核心模組。完成之後,第一個使用者空間程式(init)開始執行,更高 層次的系統初始化開始。
這就是從表面上看,linux的啟動過程。好了,現在,讓我們更進一步,更深入地探索linux啟動過程中的一些細節。
二、 系統的啟動
系統啟動的階段,依賴於linux在哪個硬體裝置上啟動。在嵌入式系統中,當系統被開啟或者重新啟動的時候,就要使用啟動載入的環境。這方面的 例子包括U -BOOT,RedBoot,和Lucent推出的MicroMonitor。嵌入式平台通常是綁定了啟動監視器的。這些程式位於目標硬體上flash存 儲器的特定位置,提供了將linux核心鏡像下載到flash儲存空間的方法,並在接下來的過程中執行它。除了擁有儲存和啟動linux鏡像的功能外,這些 啟動監視器還能進行一定程度上的系統檢測和硬體初始化。在一個嵌入式的目標板中,這些啟動監視器通常覆蓋了第一階段與第二階段boot loader的功能。
/************************************************************************************************/
小知識:如何查看你的MBR內容。如果你希望查看你MBR的具體內容,請用以下命令:
# dd if=/dev/hda of=mbr.bin bs=512 count=1
# od -xa mbr.bin
需要以root身份啟動並執行dd命令,讀取你的第一個整合電子磁碟機或者IDE磁碟機的前512位元組,並將他們寫入
mbr.bim檔案。od命令則是以十六進位和ASCII碼形式列印出這個二進位檔案
/************************************************************************************************/
在個人電腦中,linux的啟動是從0xFFFF0地址開始的。BIOS的第一步動作就是進行上電自檢(POST)。POST的工作是檢查硬體 裝置。BIOS的第二步動作就是枚舉本地裝置並初始化。
由於BIOS功能使用上的不同,它由兩個部分組成:POST碼runtime服務。POST完成後,它將從儲存空間中被清除,但是BIOS runtime服務會被保留,用於目標作業系統。
為了啟動作業系統,BIOS的runtime服務將搜尋那些啟用狀態的或是可引導啟動的裝置,搜尋的順序則由CMOS設定決定(也就是我們平時 所謂的在 BIOS中設定的啟動順序)。一個軟碟機,一台光碟機,一個硬碟上的分區,網路上的裝置甚至一個usb 快閃記憶體盤都可以作為一個啟動裝置。
當然,linux通常是從硬碟啟動的。硬碟上的MBR(主開機記錄)包含有基本的boot loader,它是一個512位元組大小的扇區,位於磁碟的第一個扇區(0磁頭0磁軌1扇區)。當MBR被裝載到RAM中後,BIOS就會將控制權轉交給 MBR。
三、 第一階段boot loader
位於MBR中的主boot loader是一個512位元組的鏡像,其中不僅包含了程式碼,還包含了一個小的分區表,2所示。最初的446位元組是主boot loader,它裡面就包含有可執行代碼以及錯誤訊息文本。接下來的64位元組是分區表,其中包含有四個分區的各自的記錄(一個分區佔16位元組)。MBR通 過特殊數字0xAA55(譯者註:在電子界中AA55確實是具有傳奇色彩的數字,想知道為什麼嗎?將它展開成二進位形式,看看有什麼規律)作為兩個位元組的 結束標誌。0x55AA同時也是MBR有效校正確認。
主boot loader的工作是尋找並載入第二boot loader。它通過分析分區表,找出啟用分區來完成這個任務,當它找到一個啟用分區時,它將繼續掃描剩下的分區表中的分區,以便確認他們都是未啟用的。 確認完畢後,啟用分區的開機記錄從裝置中被讀到RAM,並被執行。
四、 第二階段boot loader
起著次作用,或者說是第二boot loader,可以更加形象得被稱為核心載入程式。這個階段的任務就是載入linux核心,以及可選的初始化記憶體盤。
/*******************************************************************/
小知識:GRUB階段的boot loaders
在/boot/grub目錄中包含有stage1,stage2和stage1.5的boot loaders,同時還有不少可選的loaders(例如,CD-ROM使用的就是iso9660_stage_1_5)
/*******************************************************************/
把第一階段和第二階段的boot loaders聯合起來,就是在x86個人電腦中,我們所說的linux loader(LILO)或者GRand Unified Bootloader(GRUB)。由於GRUB修正了一些LILO中存在的缺陷,因此下面就讓我們來看看GRUB(如果你希望得到更多的關於GRUB, LILO和與之相關話題的討論資源,請見文後的參考資料)
對於GRUB來說,一個比較好的方面就是它包含了linux檔案系統的知識。與LILO使用裸扇區不同的是,GRUB能夠從ext2或者 ext3檔案系統中載入linux核心。它是通過將本來兩階段的boot loader轉換成三個階段的boot loader。在第一階段(MBR)中會啟動stage1.5的boot loader來理解linux核心鏡像中的特殊的檔案系統格式,例如,reiserfs_stage1-5(用於從reiserf記錄檔系統中進行加 載)或e2fs+stage1_5(用於從wxt2或ext3檔案系統進行載入)。當stage1.5的boot loader被載入並運行時,stage2 的boot loader才能被載入。
當stage2被載入時,GRUB能根據請求的情況顯示一個可選核心的清單(在 /etc/grub.conf 中進行定義,同時還有幾個軟符號連結 /etc/grub/menu.lst 和 /etc/grub.conf)。你可以選擇一個核心,修改其附加的核心參數。同時,你可以選擇使用命令列的shell來對啟動過程進行更深層次的手工控 制。
在第二階段boot loader存在與記憶體中後,就可以對檔案系統進行查詢了,同時,預設的核心鏡像以及初始化記憶體盤鏡像也被載入到記憶體中。一切準備完畢之後,第二階段的 boot loader就會調用核心鏡像。
2. 核心啟動:建立1#進程並執行,由它建立若干核心線程(kernel thread),然後裝入並執行程式/sbin/init(變成一個使用者進程)。此後,init根據/etc/inittab設定檔來執行相應的指令碼進 行系統初始化,如設定鍵盤、字型,裝載模組,設定網路等。
對於Redhat來說,執行的順序為:
/etc/rc.d/rc.sysinit # 由init執行的第一指令碼
/etc/rc.d/rc $RUNLEVEL # init執行指定運行層級($RUNLEVEL為預設的運行模式)的各指令碼;
/etc/rc.d/rc.local #運行模式2、3、5時會啟動並執行指令碼
/sbin/mingetty(或getty) # 等待使用者登入
/etc/inittab中指定了系統的運行層級(RUNLEVEL),init根據運行層級啟動相關的服務(一些後台進程),實現不同的功 能。
RUNLEVEL值為:0-6
0:halt, 1:單使用者,2:多使用者,3:多使用者並啟動NFS服務
4:保留,5:運行xdm(X window)以圖形介面方式登入
6:reboot
3./etc/inittab檔案
/etc/inittab的檔案內容如下:
# 設定系統開機預設的RUNLEVEL:
id:3:initdefault:
# 開始進行RUNLEVEL的服務啟動前,使用來偵測與初始化系統內容的設定檔案:
si::sysinit:/etc/rc.d/rc.sysinit
# 7 個不同 run level 的,需要啟動的服務的 scripts 放置路徑:
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
# 是否允許按下 [ctrl]+[alt]+[del] 就重新開機的設定項目:
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
# 本機端終端機啟動的個數:
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
# 在 X Window (RUNLEVEL 5) 環境下的啟動 script 設定項目:
x:5:once:/etc/X11/prefdm -nodaemon
這個檔案的文法是這樣的:
標識符:層級:init 的動作行為:指令項目
1. 標識符:
最多四個字元,代表 init 的主要工作項目,只是一個簡單的代表說明。
2. 層級:
該項目在哪些 run level 底下進行的意思。如果是 35 則代表 runlevel 3 與 5 都會執行。
3. init 的動作行為:
主要可以進行的動作項目意義有:
initdefault :代表預設的 run level 設定值;
sysinit :代表系統初始化的動作項目;
ctrlaltdel :代表 [ctrl]+[alt]+[del] 三個按鍵是否可以重新開機的設定;
wait :代表後面接的指令項目必須要執行完畢才能繼續後面的動作;
respawn :代表後面接的, init 仍會主動的『重新』啟動。
更多的設定項目請參考 man inittab 的說明。
4. 指令項目:
亦即應該可以進行的指令,通常是一些 script 囉。
說明:如根據上面的檔案,init程式執行時根據/etc/inittab檔案的內容,完成以下功能
(1)擷取RUNLEVEL(檔案中的這一行 id:3:initdefault:)為3
(2)執行rc.sysinit(檔案中的這一行 si::sysinit:/etc/rc.d/rc.sysinit)
(3)執行/etc/rc.d/rc3.d目錄中的指令碼(檔案中的這一行 l3:3:wait:/etc/rc.d/rc 3,且因為本例RUNLEVEL為3)
(4)然後設定是否允許按下 [ctrl]+[alt]+[del] 就重新開機(檔案中的這一行 ca::ctrlaltdel:/sbin/shutdown -t3 -r now,當然如果不允許,可把此行注釋掉)
(5)啟動六個終端介面tty1-tty6
(6)最後如果我們使用的是 run level 5 ,那麼除了這六個終端機之外, init 還會執行/etc/X11/prefdm -nodaemon 其主要的功能就是在啟動 X Window !