1. 程式人生 > >Centos7系統詳細的啟動流程

Centos7系統詳細的啟動流程

運行 讀取 限制 提示 進程 ystemd 正常 linux安裝 程序

熟悉系統啟動流程對於我們學習Linux系統是非常有幫助的,雖然基礎,但能幫助我們更加理解Linux系統的工作機制。以下將以CentOS發行版為例來介紹Linux系統的啟動流程,因為在CentOS 5、CentOS 6以及CentOS 7使用的初始化程序init各不相同,雖然CentOS 6和CentOS 7都有向後兼容,但在工作機制上仍有一些差異,因此以下主要介紹CentOS 5/6系統啟動流程。

CentOS的啟動流程總體順序如下(以CentOS 6為例):

POST --> Boot Sequence --> bootloader(MBR) --> Kernel --> 加載rootfs --> switchroot --> /sbin/init --> (配置文件:/etc/inittab, /etc/init/*.conf) --> 根據init配置文件設置默認運行級別 --> 運行系統初始化腳本/etc/rc.d/rc.sysinit,完成系統初始化 --> 開啟或關閉用戶選定的對應運行級別下所對應的服務 --> 啟動終端,打印登錄提示符。

註意:紅色部分代表內核空間的系統啟動流程,紫色部分代表用戶空間的系統啟動流程。

接下來逐一詳解:

第一步:POST加電自檢

主要實現的功能是檢測各個外圍硬件設備是否存在而且能夠正常運行起來,實現這一自檢功能的是固化在主板上的ROM(主要代表為CMOS)芯片上的BIOS(Basic Input/Output System)程序;例如BIOS會檢測CPU、Memory以及I/O設備是否能夠正常運行,如果是個人計算機的話可能還會檢測一下顯示器。只要一通電,CPU就會自動去加載ROM芯片上的BIOS程序,是這樣來實現的。而檢測完成之後就進行硬件設備的初始化。

第二步:Boot Sequence(選擇啟動設備以加載MBR)

主要實現的功能是選擇要啟動的硬件設備,選擇了之後就可以讀取這個設備上位於MBR裏頭的bootloader了。這一步的實現是這樣的:根據BIOS中對啟動順序的設定,BIOS自己會依次掃描各個引導設備,然後第一個被掃描到具有引導程序(bootloader)的設備就被作為要啟動的引導設備。

第三步:加載bootloader(MBR)

這一步實現起來的步驟比較多,前面的BIOS通過讀取並執行啟動設備的MBR中的bootloader,而bootloader要實現的功能就是提供一個菜單給用戶,讓用戶去選擇要啟動的系統或不同的內核版本,然後把用戶選擇的內核版本加載至RAM中的特定空間,接著在RAM中解壓、展開,而後把系統控制權移交給內核。

grub是bootloader中的一種,就grub來說,為了打破在MBR中只有446Bytes用於存放bootloader這一限制,所以這一步的實現是這樣的:grub是通過分成三個階段來實現加載內核這一功能的,這三個階段分別是:stage1, stage1.5以及stage2。其中:

stage1:存放於MBR的前446Bytes,用於加載stage1.5階段,目的是為了識別並驅動stage2(或者/boot)所在分區的文件系統;

stage1.5:存放於MBR之後的扇區,加載stage2所在分區的文件系統驅動,讓stage1中的bootloader能識別stage2所在分區的文件系統;

stage2:存放於磁盤分區之上,具體存放於/boot/grub目錄之下,主要用於加載內核文件(vmlinuz-VERSION-RELEASE)以及ramdisk這個臨時根文件系統(initrd-VERSION-RELEASE.img或initramfs-VERSION-RELEASE.img)。

概述:假如要啟動的是硬盤設備,首先我們的硬件平臺主板BIOS必須能夠識別硬盤,然後BIOS才能加載硬盤中的bootloader,而bootloader自身加載後就能夠直接識別當前主機上的硬盤設備了;不過,能夠識別硬盤設備不代表能夠識別硬盤設備中的文件系統,因為文件系統是額外附加的一層軟件組織的文件結構,所以要對接一種文件系統,就必須要有對應的能夠識別和理解這種文件系統的驅動,這種驅動就稱為文件系統驅動。而stage1.5就是向grub提供文件系統驅動的,這樣stage1就能訪問stage2及內核所在的分區(/boot)了。

註意:kernel和initramfs的文件路徑均以grub的"根"作為起始目錄,且存放於stage2所在分區上;

需要註意的是,stage2、內核以及ramdisk文件通常放置於一個基本磁盤分區之上,因為grub無法驅動lvm、高級軟raid等復雜邏輯設備,除非提供一個復雜的驅動接口,否則如果stage2及內核等文件都存放在lvm等復雜邏輯設備上將無法被stage1所識別,更別說加載了!

第四步:Kernel自身初始化

Kerenl在得到系統控制權之後,首先要進行自身初始化,而初始化的主要作用是:

(1)探測可識別到的所有硬件設備;

bootloader將系統控制權移交給內核就好比如後朝推翻前朝,統治者(內核)當權之後,首先要檢查一下有哪些是前朝所留下的,例如有哪些領土、人力、財力、兵力可用等等。

(2)加載硬件驅動程序,即加載真正的根文件系統所在設備的驅動程序(有可能會借助於ramdisk加載驅動);

這就像統治者(內核)在得知底下存在的人力、財力之後,開始將可以“為我所用”的人力納入麾下,聽自己使喚,而不聽使喚的殺掉;

(3)以只讀方式掛載根文件系統;

如果有借助於ramdisk這個臨時文件系統(虛根),則在這一步之後會執行根切換;否則不執行根切換。

(4)運行用戶空間的第一個應用程序:/sbin/init.

到這裏內核空間的啟動流程就結束了,而接下來是用戶空間完成後續的系統啟動流程。

註意:

ramdisk和內核是由bootloader一同加載到內存當中的,ramdisk是用於實現系統初始化的、基於內存的磁盤設備,即加載至內存(的某一段空間)後把內存當磁盤使用,並在內存中作為臨時根文件系統提供給內核使用,幫助內核掛載真正的根文件系統。而之所以能夠幫助內核掛載根文件系統是因為在ramdisk這個臨時文件系統的/lib/modules目錄下有真正的根文件系統所在設備的驅動程序;除此之外,這個臨時文件系統也遵循FHS,例如有這些固定目錄結構:/bin, /sbin, /lib, /lib64, /etc, /mnt, /media, ...

因為Linux內核有一個特性就是通過使用緩沖/緩存來達到加速對磁盤上文件的訪問的目的,而ramdisk是加載到內存並模擬成磁盤來使用的,所以Linux就會為內存中的“磁盤”再使用一層緩沖/緩存,但是我們的ramdisk本來就是內存,它只不過被當成硬盤來使用罷了,這就造成雙緩沖/緩存了,而且不會起到提速效果,甚至影響了訪問性能;CentOS 5系列以及之前版本的ramdisk文件為initrd-VERSION-RELEASE.img,就會出現上述所說到的問題;而為了解決一問題,CentOS 6/7系列版本就將其改為initramfs-VERSION-RELEASE.img,使用文件系統的方式就可以避免雙緩沖/緩存了,我們可以說這是一種提速機制。

需要註意的是,系統發行商為了適應於各個不同的硬件接口,因此將各個不同的硬件接口的驅動組裝打包起來,例如在用戶第一次使用光盤安裝完系統之後,會動態探測當前主機上的硬件設備並調用與之對應的設備驅動再做成ramdisk文件的。所以,ramdisk文件並非必須的,如果只是為了將Linux安裝於特定硬件平臺上,就可以直接把對應的驅動編譯進內核即可,而不需要去使用ramdisk文件了。

第五步:init管理用戶空間服務進程

init可以理解成是內核派來管理用戶空間的使者,就好像天使代表上帝來訪問人間一樣。init這個初始化程序會根據其配置文件執行一系列操作。雖然CentOS 5、CentOS 6以及CentOS 7的init配置 文件各不相同,但總體的啟動流程是不變的。

這一步的流程是:/sbin/init --> 根據init配置文件設置默認運行級別 --> 運行系統初始化腳本/etc/rc.d/rc.sysinit,完成系統初始化 --> 關閉或啟動用戶選定的默認運行級別所對應的服務 --> 啟動終端,打印登錄提示符

(1)根據init配置文件設置默認運行級別

對於CentOS 5來說,初始化程序init是SysV init,其配置文件為:/etc/inittab;

對於CentOS 6來說,初始化程序init是upstart,其配置文件為:/etc/inittab, /etc/init/*.conf,也就是upstart將配置文件拆分成多個,在/etc/init/目錄下以conf結尾的都是upstart風格的配置文件,而/etc/inittab僅用於設置默認運行級別;

對於CentOS 7來說,初始化程序init是systemd,其配置文件為:/usr/lib/system/systemd/*, /etc/systemd/system/*;

Centos7系統詳細的啟動流程