1. 程式人生 > >開機啟動流程分析

開機啟動流程分析

boot 啟動流程

本節索引


在對系統啟動流程進行分析的時候,我想你一定是對系統有了一定的了解。系統的啟動目前來講大都為串行接力的方式來啟動。而所謂的並行方式的啟動方式也是某一個階段的並行。所以我按照系統啟動的順序來把文章連綴起來。

* BIOS階段

* BootLoader階段

* 內核階段

* 用戶層階段

技術分享


BIOS階段


加載BIOS

當按下開機鍵後,系統會自動自動加載BIOS,加載的詳細過程不再詳述,感興趣的讀者可學習微機原理和或對匯編代碼分析

BIOS從CMOS芯片中讀取硬件配置信息

開機所需要的BIOS設置和用戶自定義的設置都保存在CMOS芯片中。

POST自檢

POSTpower on system test

BIOS的代碼中包含有診斷功能,用以保證重要硬件被正確初始化,比如內存,CPU,以及一些主板上的各種芯片組。如果硬件損壞,用戶可通過主板的debug顯示或者蜂鳴器的聲音來診斷哪些硬件有故障。

加載Bootloader

POST自檢無誤後,BIOS會執行一個 INT 13的中斷例程來進入加載

Bootloader階段。

INT13 中斷會從第一啟動項的0磁道1扇區讀取BootLoader,把系統啟動的任務移交給BootLoader

Bootloader階段


Bootloader具體到Linux系統就是grub了。早期使用的LILO以不再使用。

BootLoader的主要作用就是識別和加載操作系統的內核文件,並移交至內存中運行,進而啟動操作系統。

磁盤的第一塊扇區被稱為主引導記錄(MBR—Master boot Record ),該扇區的446字節存儲grub第一階段的代碼。把一個龐大的操作系統內核交給446個字節來引導顯然是不現實的,所以可以簡單理解為第一階段的grub的任務就是為了加載第二階段的

grub

第二階段的grub把對資源的控制權轉交給內核鏡像。

BootLoader主要功能

  1. 提供菜單功能讓用戶選擇操作系統。

  2. 加載內核文件

  3. 移交給其他的BootLoader(該項有些bootloader不支持,比如Windowsloader)。

  4. 命令行編輯 當系統BootLoader 加載內核出現故障,用戶可在命令行模式下修改啟動參數。

grub為例分析BootLoader階段多做的那些事:

  1. BIOS 進行POST自檢並無誤後,執行INT 13中斷,讀取對應MBR中前446字節的grub stag1代碼並執行。

  2. 加載boot分區文件系統驅動。Grubstag1階段存儲了grub的預啟動信息和grub stag1_5階段代碼地址信息,grub stag1_5 階段的代碼位於磁盤的主引導記錄之後的27個扇區中(修復grub時的數據,非標準,該段空間主要存儲掛載/boot分區文件系統所需要的驅動程序。一般在系統的/boot/grub目錄下會有stag1_5階段的備份文件。

  3. 掛載/boot目錄,進入grubstag2階段,讀取grub.conf配置文件,根據配置信息,啟動或者由用戶選擇內核啟動或者移交給其他其他BootLoader,並提供命令行功能用於手動加載內核。把所有的控制權移交給內核。

註:此階段的不含有rootfs的概念,尋找內核文件都是以boot為根

Grub.conf文件如下:

default=0

timeout=5

title CentOS 6 (2.6.32-696.el6.x86_64)

root (hd0,0)

kernel /vmlinuz-2.6.32-696.el6.x86_64 ro root=/dev/mapper/vg_centos6-lv_root

#以boot為根的內核路徑

initrd /initramfs-2.6.32-696.el6.x86_64.img

內核階段


Linux內核的設計風格是單內核,單內核設計要支持市面大部分硬件設備的前提下就要把很多的驅動程序編譯在內核文件中,會使得內核文件體積異常龐大。但是Linux系統內核在設計上吸收了微內核的一些優點,把大部分的驅動程序,文件系統驅動程序還有一些外圍的驅動程序封裝成一個個單獨的模塊,在使用過程中只需動態的加載所需要的模塊就好了。

內核模塊文件在/lib/modules/`uname -r` 這個目錄下,這時候問題就來了,如果內核文件要加載模塊驅動,就要先從根分區查找模塊位置,而要找到根分區,就要有根文件系統的驅動模塊,而模塊又在根文件系統下又回到了先有雞先有蛋的問題。

為了解決這個問題,一種方法是可以把根文件系統的文件系統驅動程序直接編譯在內核文件中,但是市場上的Linux發行版本要支持很多文件系統類型,把所有的文件系統驅動程序編譯進內核又會讓內核文件體積變得非常龐大。為了解決這一矛盾,就有了initrd這個文件,當然這個是最早期的,在centos6版本稱為initramfs也稱為虛擬文件系統,該文件是在系統安裝的最後階段生成的,只用來加載根文件系統的驅動程序,在內核無法驅動根文件系統的時候就要加載虛擬文件系統,然後在根文件系統下找到對應的驅動模塊後在進行根切換。

系統啟動內核階段的步驟

  1. 加載內核至內存後解壓運行,嘗試掛載根文件系統,如果掛載成功,動態加載個驅動模塊,對周圍硬件設備進行探測並進行初始化。

  2. 如果無法掛載根文件系統,加載initrd虛擬文件系統,然後掛載真正的根文件系統,並切換根,再執行第一步。

至此,Linux內核已經建立起來了。

用戶層階段


內核被加載成功之後,這個系統已經正常運行,這也是最初的Linux,但是作為一個用戶是無法直接使用內核的。所以就要初始化啟動相關的進程或者服務來供用戶來使用。

管理進程的工具多種,以centOS為例,有sysVinitsystemd兩種。本文主要分析sysVinit的啟動方式。

Systemd是由sysVint進化而來,因此更好的掌握了sysVinit啟動方式有助於理解systemd的啟動方式

執行init程序

內核在引導完成之後會執行系統的第一個進程init。這時也就正式進入了sysVinit的引導環境。Init之後的所有進程都是由init派生出來,它的PID永遠為1

init進程加載inittab配置文件

init進程依據inittab文件來設定運行級別,不同的運行級別可以定義一組不同服務的啟動順序。CentOS56版本默認有7個運行級別。詳情如下:

# Default runlevel. The runlevels used are:

# 0 - halt (Do NOT set initdefault to this)

# 1 - Single user mode

# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)

# 3 - Full multiuser mode

# 4 - unused

# 5 - X11

# 6 - reboot (Do NOT set initdefault to this)

#

id:3:initdefault: #默認的運行級別

生產環境中默認使用3級別,運行級別的只是用於定義一組不同的啟動順序,用戶完全可以自定義,也可以自定義這7種運行級別。

執行rc.sysinit

init在得到運行級別之後並不會立即執行該運行級別的一組服務程序,而執行的第一個程序是/etc/rc.d/rc.sysinit腳本程序。該程序的在centos5inittab文件中有如下一行:

si:sysinit:/etc/rc.d/rc.sysinit

這個腳本所做的工作有很多,包括主機名,文件系統,swapSELinuxudev,內核參數,系統時鐘,RaidLVM等服務的開啟。為後續服務啟動準備基礎環境。

加載rc$runlevel.d下的服務

rc.sysinit腳本初始化完成之後,會加載默認啟動級別下的一組服務。這個時候可以查看對應rc$runlevel.d下的文件,有大量以KS開頭的腳本文件(軟連接),跟蹤rc.d目錄下的rc腳本可以發現這樣兩個循環結構,仔細研究之後符合以下邏輯

for i in /etc/rc$runlevel.d/K* ; do

$i stop #依次關閉以K開頭的服務

done

for i in /etc/rc$runlevel.d/S* ; do

$i start #依次開啟以S開頭的服務,即開機自啟動

Done

通過這個結構我們很容易發現服務的啟動時順序執行的,前一個服務腳本沒有執行成功的後續腳本就要等待。

通過對rc腳本的分析可以得出對應runlevel下以S開頭的腳本是開機啟動的,我們可以通過chkconfig命令調整程序是否開啟啟動或者指定模式下的開機自啟動。

跟蹤對應模式下的腳本軟連接可以,找到服務腳本大多放置在/etc/init.d目錄之下。可以使用service 命令來管理這些腳本。

2345運行級別所對應的rc$runlevel.d目錄中都有一個$99local的腳本軟連接,該腳本一般是最後一個執行的腳本,該腳本位置在/etc/rc.d/local。所以用戶可以把開機後需要執行的操作寫在該腳本中。

當然也可以把開機需要的操作定義為服務放置於/etc/init.d目錄下,這時需要修改服務腳本的格式。


本文出自 “Keep simple keep stupid” 博客,請務必保留此出處http://yangzhiheng.blog.51cto.com/11586378/1967159

開機啟動流程分析