嘔心瀝血!CentOS系統(tǒng)啟動流程詳解!
系統(tǒng)啟動流程是Linux一個重要的內(nèi)容,深入了解啟動流程會對我們學習Linux起到一個順水推舟的作用。因為CentOS 7改動較大,所以下面的內(nèi)容只是針對CentOS 5和6來說的。下面進入正題。
啟動流程:
***步:POST加電自檢
此過程的就是為了檢測一下外界的硬件設備是否能夠正常運行,如CPU,內(nèi)存設備,硬盤等等這些硬件設備是否可以正常工作。
第二步:BIOS選擇啟動方式
BIOS對于經(jīng)?;A計算機的人應該不會陌生,特別是那些經(jīng)常裝系統(tǒng)的人,它就是列出幾個選項,讓你選擇以什么方式來啟動系統(tǒng),常見的有硬盤啟動,光盤,以及網(wǎng)絡方式啟動。
第三步:BootLoader
這個步驟略有復雜,但是其實現(xiàn)的功能就是,引導加載系統(tǒng)中的核心文件,并提交到內(nèi)存運行,它會列出一個grub菜單,其中的選項是我們操作系統(tǒng)的內(nèi)核,你選擇的內(nèi)核文件會被加載至內(nèi)存中運行。
引導加載器grub:找到內(nèi)核文件,提供grub菜單
代碼分析:
- [root@localhost testdir]# cp /boot/initramfs-2.6.32-642.el6.x86_64.img . //將/boot下的ramfs文件拷貝至當前目錄
- [root@localhost testdir]# zcat initramfs-2.6.32-642.el6.x86_64.img |cpio -id //將其解壓縮
- 140023 blocks
- [root@localhost testdir]# ls //其包含的內(nèi)如如下,因為是臨時的根文件,所以目錄結構也類似于我們的rootfs,其中包含rootfs所需要的文件系統(tǒng)的驅(qū)動
- bin dracut-004-409.el6 init initqueue-settled lib netroot pre-trigger sbin tmp
- cmdline emergency initqueue initqueue-timeout lib64 pre-mount pre-udev sys usr
- dev etc initqueue-finished initramfs-2.6.32-642.el6.x86_64.img mount pre-pivot proc sysroot var
- [root@localhost testdir]#
第四步:加載內(nèi)核文件
通過上面所選擇的內(nèi)核文件,來將其加載至內(nèi)存中解壓縮,分為以下四個步驟
1)探測可識別到的所有硬件設備。
2)加載硬件驅(qū)動程序(可能借助于ramdisk/ramfs加載驅(qū)動)
3)以只讀方式掛載根文件系統(tǒng)
4)運行用戶空間的***個應用程序:/sbin/init
注意:其中Ramdisk/ramfs即stage2所在分區(qū)的rootfs文件系統(tǒng)驅(qū)動的文件,有了內(nèi)核文件及所需要的rootfs的文件系統(tǒng)驅(qū)動,為避免內(nèi)核文件有bug或者人為操作問題,先以只讀方式掛載rootfs
代碼分析:
Init程序初始化
1)根據(jù)init的配置文件獲取到運行級別信息,并獲取系統(tǒng)初始化腳本的文件路徑。(CentOS 5的init文件為/etc/inittab,CentOS6將/etc/inittab文件拆分為多個文件)
2)讀取系統(tǒng)初始化腳本/etc/rc.d/rc.sysinit,并按照腳本內(nèi)容執(zhí)行,作用如下: (1)設置主機名(2)設置歡迎信息(3)激活udev和selinux(4)掛載/etc/fstab文件中定義的文件系統(tǒng)(5)檢測根文件系統(tǒng),并以讀寫方式重新掛載根文件系統(tǒng)(6)設置系統(tǒng)時鐘(7)激活swap設備(8)根據(jù)/etc/sysctl.conf文件設置內(nèi)核參數(shù)(9)激活lvm及software raid設備(10)加載額外設備的驅(qū)動程序(11)清理操作 3)根據(jù)前面獲取的運行級別,運行/etc/rc.d/rc腳本文件
/etc/rc.d/目錄下有幾個rc#.d(#號數(shù)字,也就是代表運行級別),其目錄下文件為鏈接文件,其指向/etc/init.d/下的服務腳本文家,根據(jù)在/etc/inittab獲取的默認運行級別和/etc/rc#.d下的鏈接文件,來啟動和關閉系統(tǒng)的服務,想必現(xiàn)在也能聯(lián)想到了為什么不同級別下啟動的服務不相同,為什么有的服務開機啟動,有的卻關閉 /etc/rc#.d/下的鏈接文件以K或者S開頭,K表示開機要被停止的服務,S表示開機要被啟動的服務,而且服務腳本都會有一個優(yōu)先級,
- K*:K##*:##運行次序;數(shù)字越小,越先運行;數(shù)字越小的服務,通常為依賴到別的服務
- S*:S##*:##運行次序;數(shù)字越小,越先運行;數(shù)字越小的服務,通常為被依賴到的服務
注意:在2345級別的/etc/rc#.d目錄下都會有一個rc.local,它其實也是一個鏈接文件,鏈接到/etc/rc.d/rc.local,它并不是啟動文件,而是一個普通的文件,不過它的優(yōu)先級最小,所以***啟動,如果你想要開機做一些什么操作,可以寫到這個腳本里面。
代碼分析:以下為CentOS 5中的/etc/inittab文件
下圖為系統(tǒng)啟動時服務開啟的界面
第六步:啟動終端
根據(jù)前面獲取的默認運行級別來啟動終端,如果運行級別為5,則啟動圖形界面
第七步:用戶登錄
系統(tǒng)啟動流程結束!
問題總結:
在此之前,一直有幾點問題困惑著我,我對它們做了一下總結
1)內(nèi)核文件在磁盤上,系統(tǒng)還沒有啟動,系統(tǒng)還沒有啟動,/目錄也沒有掛載,前面說先找到boot分區(qū),但是boot分區(qū)也是在/的目錄下,/還沒有,去哪找boot!?
問題解答:注意,此時系統(tǒng)去尋找boot分區(qū)下的grub菜單、內(nèi)核文件及rootfs的驅(qū)動并不是通過/目錄來尋找,因為此時的/還沒有掛載,無法找到/下面的boot目錄,而是直接去boot的那個磁盤分區(qū)去尋找所需要的文件,具體看一下代碼:
2)上面問題的繼續(xù),即使你先加載boot分區(qū),boot分區(qū)系統(tǒng)的系統(tǒng)驅(qū)動在哪里呢
問題解答:從以下代碼得知,分區(qū)信息是從1柱面開始的,那么0柱面被狗吃了么?答案是沒有被狗吃,MBR存放在了0柱面,0磁道的***個扇區(qū)內(nèi),但是它只占據(jù)了512個字節(jié),因為0柱面包括了好多扇區(qū),后面的扇區(qū)就是為了存放/boot分區(qū)的文件系統(tǒng)驅(qū)動的。stage1->stage1.5->stage2這個過程就是為了掛載/boot分區(qū),而其中的stage1.5就是尋找/boot分區(qū)的文件系統(tǒng)驅(qū)動的。
3)加載內(nèi)核后,為避免bug或者人為操作失誤,rootfs先以只讀方式掛載,只讀方式掛載怎么寫數(shù)據(jù)呢?
問題解答:內(nèi)核在讀取到init程序后,其中有一個系統(tǒng)初始化腳本,即/etc/rc.d/rc.sysinit腳本,其中有一段代碼如下,在這rootfs會被重新以讀寫方式掛載。
流程圖:
俗話說的好,一圖抵千言,我將上面所述的啟動流程又畫了一幅圖,希望以更加清晰地描述CentOS的啟動流程。