??本文以centos5為例,詳細說明從按下電源直到屏幕出現命令行提示符的Linux整個啟動過程。當用戶按下電源,BIOS開機自檢,按BIOS中設置的啟動設備啟動,接著啟動設備上安裝的引導程序grub開始引導Linux。Linux首先進行內核的引導,接下來執行init程序,init調用了rc.sysinit和rc等程序,rc.sysinit和rc完成系統初始化和運行服務的任務后,返回init;init啟動了mingetty后,打開了終端供用戶登錄系統,用戶登錄成功后進入了Shell,這樣就完成了從開機到登錄的整個啟動過程。
??整個Linux啟動過程分成以下幾個部分:
- POST加電自檢
- 引導加載器引導程序
- 加載內核
- 運行init
- 系統初始化
- 啟動對應運行級別的守護進程
- 建立終端
- 登錄系統,啟動完成
POST加電自檢
??開機按下電源鍵后,計算機加電,主板上的BIOS或UEFI基本輸入輸出程序開始對計算機硬件進行檢查,主要是負責完成對CPU、主板、內存、硬盤子系統、顯示子系統、 串并行接
口、鍵盤、 CD-ROM光驅等硬件情況的檢測。當檢測到錯誤的時候,機器有可能會中斷或者啟動不了。如果沒什么重大錯誤,接下來就會按次序查找引導設備,第一個有引導程序的設備為本次啟動設備。
引導加載器引導程序
??確定引導介質后,便開始從介質中裝載引導程序如grub,這是一個微小程序,我們知道MBR引導記錄大小為512字節,其中前446個字節就是Bootloader,主要用來引導用戶選擇要啟動的系統或不同的內核版本,把用戶選定的內核裝載到RAM中的特定空間中,解壓,展開,而后把系統控制權移交給內核。
??grub是Linux中Bootloader程序,由于MBR記錄大小的限制,所以grub分為三個部分:
- stage1: mbr,引導啟動介質的grub主體文件
- stage1_5: mbr之后的扇區,讓stage1中的bootloader能識別stage2所在的分區上的文件系統
- stage2:磁盤分區(/boot/grub/)
??需要注意的是:stage1和stage1_5不屬于任何分區,這兩個階段是沒有文件系統的,都是以磁盤0101的方式直接訪問的。
??stage2階段中,會進入/boot/grub/,里面有grub.conf配置文件,根據里面的內核配置信息去加載內核。
加載內核
??這時候kernel開始進行自身初始化:探測可識別的硬件設備,加載硬件驅動程序(借助于ramdisk加載驅動,ramdisk是輔助的偽根系統,虛擬磁盤),并且以只讀方式掛載根文件系統,運行用戶空間的第一個應用程序 /sbin/init。
??kernel在內存中加載時,為了模擬系統環境,會生成一個ramdisk文件,來進行下一步操作,等到加載到真正的根文件系統時,就會退出ramdisk,切換到真正的根文件系統中去。
??/boot/initrd-VERSION-release.img,也就是上面提到的ramdisk,存放了和內核啟動相關的最基本驅動,和啟動無關的一般都放在/lib/modules/下面。/boot/initrd-VERSION-release.img是解決根的掛載問題,掛載根之前必然已經進入/boot了。進/boot 是grub來負責的,注意/boot 和/ 的文件系統是可以不一樣的,這兩個是獨立的分區。內核是放在/boot下面的,先加載內核,然后掛載根/,掛載根的時候需要用到文件系統驅動,而文件系統的驅動放在/lib/modules/下面,就是在根下面,就矛盾了。而ramdisk就是來解決這個問題的 。
運行init
??init的進程號是1,從這一點就能看出,init進程是系統所有進程的起點,Linux在完成內核引導以后,就開始運行init進程。init進程需要讀取配置文件/etc/inittab。inittab是一個不可執行的文本文件,它有若干行指令所組成。
??/sbin/init:運行系統的第一個進程。這個進程會讀取相應配置文件,比如Centos 5的配置文件:/etc/inittab。init讀取其初始化文件: /etc/inittab,來確定初始運行級別(RUN LEVEL),運行系統初始化腳本以及對應運行級別的腳本目錄里面的腳本等。
系統初始化
??在init的配置文件/etc/inittab中有這么一行: si::sysinit:/etc/rc.d/rc.sysinit,這是調用系統初始化腳本,主要實現的功能:
(1) 設置主機名
(2) 設置歡迎信息
(3) 激活udev和selinux
(4) 掛載/etc/fstab文件中定義的文件系統
(5) 檢測根文件系統,并以讀寫方式重新掛載根文件系統
(6) 設置系統時鐘
(7) 激活swap設備
(8) 根據/etc/sysctl.conf文件設置內核參數
(9) 激活lvm及software raid設備
(10) 加載額外設備的驅動程序
(11) 清理操作
啟動對應運行級別的守護進程
??在rc.sysinit執行后,將返回init繼續其它的動作,通常接下來會執行到/etc/rc.d/rc程序。以運行級別5為例,init將執行配置文件/etc/inittab中的以下這行: l5:5:wait:/etc/rc.d/rc 5。
??這一行表示以5為參數運行/etc/rc.d/rc,/etc/rc.d/rc是一個Shell腳本,它接受5作為參數,去執行 /etc/rc.d/rc5.d/目錄下的所有的rc啟動腳本,/etc/rc.d/rc5.d/目錄中的這些啟動腳本實際上都是一些軟鏈接文件,而不是真正的rc啟動腳本,真正的rc啟動腳本實際上都是放在/etc/rc.d/init.d/目錄下。而這些rc啟動腳本有著類似的用法,它們一般能接受 start、stop、restart、status等參數。
??/etc/rc.d/rc5.d/中的rc啟動腳本通常是K或S開頭的軟鏈接文件,對于以以S開頭的啟動腳本,將以start參數來運行。而如果發現存在相應的腳本也存在K打頭的鏈接,而且已經處于運行態了(以 /var/lock/subsys/下的文件作為標志),則將首先以stop為參數停止這些已經啟動了的守護進程,然后再重新運行。這樣做是為了保證是當 init改變運行級別時,所有相關的守護進程都將重啟。
建立終端
??rc執行完畢后,返回init。這時基本系統環境已經設置好了,各種守護進程也已經啟動了。init接下來會打開6個終端,以便用戶登錄系統。通過按Ctrl+Alt+Fn(n對應1-6)可以在這6個終端中切換。在inittab中的以下6行就是定義了6個終端:
??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
??從上面可以看出在2、3、4、5的運行級別中都將以respawn方式運行mingetty程序,mingetty程序能打開終端、設置模式。同時它會顯示一個文本登錄界面,這個界面就是我們經常看到的登錄界面,在這個登錄界面中會提示用戶輸入用戶名,而用戶輸入的用戶將作為參數傳給login程序來驗證用戶的身份。
登錄系統,啟動完成
??對于運行級別為5的圖形方式用戶來說,他們的登錄是通過一個圖形化的登錄界面。登錄成功后可以直接進入KDE、Gnome等窗口管理器。
??至此,centos5的系統啟動過程就大致介紹完了,不足之處,請多多指正。