首頁 > 軟體

Linux作業系統啟動流程淺析

2020-06-16 18:03:54

啟動BIOS程式

  當電源鍵按下之後,BIOS(Basic nput Output System)就會由主機板上的快閃記憶體來執行。BIOS程式會把自己解壓縮到系統的記憶體之中,然後讀取CMOS(Complementary Metal Oxide Semiconductor)記憶體儲的資訊(例如系統時間,啟動裝置順序等)來對系統進行設定。同時進行自檢(POST:Power-On Self Test)。檢測系統的硬體是否存在問題,自檢通過之後,BIOS會載入第一啟動裝置的MBR(Master Boot Record:主引導磁區)中的boot loader程式。

  需要說明的一點是,BIOS載入bootloader是通過硬體的INT 13中斷功能來載入的。即,BIOS讀取到了磁碟之後,通過INT 13這條通道來讀取該磁碟的第一個磁區中的boot loader程式!

  下面是BIOS程式的幾張截圖:

  圖1.1:BIOS程式的基本設定介面

   

  圖1.2:BIOS程式調整裝置啟動順序的介面

啟動Bootloader程式

  Linux下面的Bootloader有多種,比如早期預設使用LILO,還有目前主流的grub。下面以目前Linux系統上面主流的grub來說明一下bootloader主要幹了哪些事情?

  Grub啟動時會自動讀取/boot/grub/grub.conf這個組態檔,然後執行其中的grub命令!圖2.1是在CentOS6.5上面的一個grub.conf組態檔!Grub命令為紅線框內的部分,它主要分為三個部分:

   

  圖2.1

  1.設定啟動的硬碟分割區(root命令),傳遞給這個命令的引數是分割區,這個命令會去分析並掛載這個分割區,然後讀取出其中的/boot資料夾下面的內容。比如圖2.2所示,執行了命令之後,就能夠讀取出boot資料夾下面的內容了!

   

  圖2.2

  2.選擇引導的核心檔案,並設定好核心引數(kernel命令)

  3.載入initrd檔案,設定虛擬檔案系統。(initrd命令)

 

  需要特別說明的是這個initrd檔案,這個其實是一個虛擬檔案系統(Initial RAM Disk)。在Linux系統中,有些磁碟的驅動程式並沒有編譯在核心中,而是被打包成了模組存放在了/lib/modules目錄下面,而當核心啟動了之後就需要載入磁碟的驅動程式。可是/lib/modules還沒有被掛載,這時就產生矛盾了!為了解決這個矛盾,就產生了虛擬檔案系統的這個概念。我們可以講initrd檔案載入到記憶體中(為了擔心影響到磁碟上的檔案系統,此時根目錄的掛載是以唯讀的方式來掛載的),虛擬出一個根檔案系統出來,然後讀取虛擬根檔案系統中的磁碟驅動程式,然後再從新掛載真正的根目錄。

  如圖2.3所示,這些檔案就是initrd檔案所解壓出來的內容。

   

  圖2.3

載入系統核心與硬體驅動程式

   Grub程式執行完上面三個命令之後,核心檔案(vmlinuz-$(uname -r))就會被解壓到了記憶體之中開始執行了!此時,核心會自己再來從新檢測一遍硬體並載入驅動程式!檢查完成之後,核心就會呼叫Init程式,建立系統的第一個進程!

Init進程進行系統的初始化

   Init程式啟動之後,會首先去讀取/etc/inittab這個檔案來獲取作業系統的Run Level(執行級別)。什麼是執行級別呢,Linux下面系統根據有無網路和X Window來將

  系統分為了七個執行級別。它們的內容如圖3.1所示:

   

  圖3.1

  這是在Linux的/etc/inittab檔案中關於這其中模式的說明。

  模式0代表了關機狀態,模式1代表了單使用者模式(維護模式),模式2代表了多使用者的命令列模式,但是並沒有網路。模式3代表了包含網路的多使用者的命令列模式。模式4是系統保留的功能。模式5代表了圖形介面模式。模式6代表了系統重新啟動的狀態。

  對應於每個執行級別,/etc目錄下面分別設定的不同的目錄,如圖3.2所示:

   

  圖3.2

  系統執行某個級別,就會去執行相應目錄(/etc/rc[執行級別].d)內的指令碼檔案。這裡那個rc代表的是run command,即開始時要執行的命令,那個.d代表directory,代表的是目錄的意思!

  Inittab檔案中出了能夠設定系統的啟動級別外,還有一些其他的功能,如圖3.3所示:

   

  圖3.3

  這個是在CentOS6.5上面inittab檔案中關於其他設定的說明。

  總之,Init程式在獲取完了系統的執行等級之後,會繼續執行下面這幾個功能:

  對系統進行初始化(執行/etc/init/rcS.conf這個指令碼檔案或者通過/etc/init/rc.conf來執行一些自定義的執行等級程式)

  載入系統服務項(執行/etc/rc[執行等級].d/中的指令碼檔案)

  設定好Ctrl + Alt + Del鍵的功能

  執行mingetty來設定好六個相應的終端機

執行終端機並接受使用者登陸

  當系統的初始化內容完成之後,系統就會呼叫mingetty函數,來設定終端機,並等待使用者登陸!它的具體流程是這樣的,init進程先fork一個子進程,然後這個子進程來exec一個getty程式。Getty程式會試著去開啟一個終端,如果開啟成功了,那麼就會去螢幕上顯示login字樣,當使用者鍵入了使用者名稱之後,getty程式的任務就完成了!然後它在以exec的方式來呼叫login程式。Login程式會去讀取使用者名稱和使用者密碼,然後讀取shadow檔案來檢驗使用者的密碼是否正確。如果密碼不正確,則login通過呼叫exit 1來退出,此時init進程重新fork來重複上述步驟。

  如果密碼驗證成功的話,那麼login程式就會設定一些系統執行的環境(比如設定工作目錄,設定uid和gid,使用者名稱等)。設定好了這些系統環境之後,login程式就會通過exec來呼叫shell程式,shell程式執行並讀取一些啟動指令碼(例如/etc/bashrc等)。讀取完這些啟動指令碼之後,shell就列印出提示符,然後等待使用者鍵入命令!此時我們的系統就正常啟動了!

本文永久更新連結地址http://www.linuxidc.com/Linux/2015-03/115304.htm


IT145.com E-mail:sddin#qq.com