Linux 核心啟動流程)

來源:互聯網
上載者:User
啟動流程一覽

既然啟動是很嚴肅的一件事,那我們就來瞭解一下整個啟動的過程吧! 好讓大家比較容易發現啟動過程裡面可能會發生問題的地方,以及出現問題後的解決之道! 不過,由於啟動的過程中,那個啟動管理程式 (Boot Loader) 使用的軟體可能不一樣,例如目前各大 Linux distributions 的主流為 grub,但早期 Linux 預設是使用 LILO 。 但無論如何,我們總是得要瞭解整個 boot loader 的工作情況,才能瞭解為何進行多重啟動的配置時, 老是聽人家講要先安裝 Windows 再安裝 Linux 的原因~

假設以個人電腦架設的 Linux 主機為例 , 當你按下電源按鍵後電腦硬體會主動的讀取 BIOS 來載入硬體資訊及進行硬體系統的自我測試, 之後系統會主動的去讀取第一個可開機裝置 (由 BIOS 配置的) ,此時就可以讀入啟動管理程式了。

啟動管理程式可以指定使用哪個核心檔案來啟動,並實際載入核心到記憶體當中解壓縮與運行, 此時核心就能夠開始在記憶體內活動,並偵測所有硬體資訊與載入適當的驅動程式來使整部主機開始運行, 等到核心偵測硬體與載入驅動程式完畢後,一個最陽春的作業系統就開始在你的 PC 上面跑了。

主機系統開始運行後,此時 Linux 才會呼叫外部程式開始準備軟體啟動並執行環境, 並且實際的載入所有系統運行所需要的軟體程式哩!最後系統就會開始等待你的登陸與操作啦! 簡單來說,系統啟動的經過可以彙整成底下的流程的:

  1. 載入 BIOS 的硬體資訊與進行自我測試,並依據配置取得第一個可開機裝置;
  2. 讀取並運行第一個啟動裝置內 MBR 的 boot Loader (亦即是 grub, spfdisk 等程式);
  3. 依據 boot loader 的配置載入 Kernel ,Kernel 會開始偵測硬體與載入驅動程式;
BIOS, 啟動自我測試與 MBR

在個人電腦架構下,你想要啟動整部系統首先就得要讓系統去載入 BIOS (Basic Input Output System),並透過 BIOS 程式去載入 CMOS 的資訊,並且藉由 CMOS 內的配置值取得主機的各項硬體設定, 例如 CPU 與周邊裝置的溝通時脈啊、啟動裝置的搜尋順序啊、硬碟的大小與類型啊、 系統時間啊、各周邊匯流排的是否啟動 Plug and Play (PnP, 隨插即用裝置) 啊、 各周邊裝置的 I/O 位址啊、以及與 CPU 溝通的 IRQ 岔斷等等的資訊。

在取得這些資訊後,BIOS 還會進行啟動自我測試 (Power-on Self Test, POST) 。 然後開始運行硬體偵測的初始化,並配置 PnP 裝置,之後再定義出可開機裝置順序, 接下來就會開始進行啟動裝置的資料讀取了 (MBR 相關的任務開始)。

由於我們的系統軟體大多放置到硬碟中嘛!所以 BIOS 會指定啟動的裝置好讓我們可以讀取磁碟中的作業系統核心檔案。 但由於不同的作業系統他的檔案系統格式不相同,因此我們必須要以一個啟動管理程式來處理核心檔案載入 (load) 的問題, 因此這個啟動管理程式就被稱為 Boot Loader 了。那這個 Boot Loader 程式安裝在哪裡呢?就在啟動裝置的第一個磁區 (sector) 內,也就是我們一直談到的 MBR (Master Boot Record, 主要開機記錄區)。

那你會不會覺得很奇怪啊?既然核心檔案需要 loader 來讀取,那每個作業系統的 loader 都不相同, 這樣的話 BIOS 又是如何讀取 MBR 內的 loader 呢?很有趣的問題吧!其實 BIOS 是透過硬體的 INT 13 中斷功能來讀取 MBR 的,也就是說,只要 BIOS 能夠偵測的到你的磁碟 (不論該磁碟是 SATA 還是 IDE 介面),那他就有辦法透過 INT 13 這條通道來讀取該磁碟的第一個磁區內的 MBR 啦!這樣 boot loader 也就能夠被運行羅!

我們知道每顆硬碟的第一個磁區內含有 446 bytes的 MBR 地區,那麼如果我的主機上面有兩顆硬碟的話, 系統會去哪顆硬碟的 MBR 讀取 boot loader 呢?這個就得要看 BIOS 的配置了。 基本上,我們常常講的『系統的 MBR』其實指的是 第一個啟動裝置的 MBR 才對! 所以,改天如果你要將啟動管理程式安裝到某顆硬碟的 MBR 時, 要特別注意當時系統的『第一個啟動裝置』是哪個,否則會安裝到錯誤的硬碟上面的 MBR 喔! 

  Boot Loader

剛剛說到 Loader 的最主要功能是要認識作業系統的檔案格式並據以載入核心到主記憶體中去運行。 由於不同作業系統的檔案格式不一致,因此每種作業系統都有自己的 boot loader 啦!用自己的 loader 才有辦法載入核心檔案嘛!那問題就來啦,你應該有聽說過多重作業系統吧?也就是在一部主機上面安裝多種不同的作業系統。 既然你 (1)必須要使用自己的 loader 才能夠載入屬於自己的作業系統核心,而 (2)系統的 MBR 只有一個,那你怎麼會有辦法同時在一部主機上面安裝 Windows 與 Linux 呢?

其實每個檔案系統 (filesystem, 或者是 partition) 都會保留一塊啟動磁區 (boot sector) 提供作業系統安裝 boot loader , 而通常作業系統預設都會安裝一份 loader 到他根目錄所在的檔案系統的 boot sector 上。如果我們在一部主機上面安裝 Windows 與 Linux 後,該 boot sector, boot loader 與 MBR 的相關性會有點像:

圖 1.2.1、 boot loader 安裝在 MBR, boot sector 與作業系統的關係

如所示,每個作業系統預設是會安裝一套 boot loader 到他自己的檔案系統中 (就是每個 filesystem 左下角的方框),而在 Linux 系統安裝時,你可以選擇將 boot loader 安裝到 MBR 去,也可以選擇不安裝。 如果選擇安裝到 MBR 的話,那理論上你在 MBR 與 boot sector 都會保有一份 boot loader 程式的。 至於 Windows 安裝時,他預設會主動的將 MBR 與 boot sector 都裝上一份 boot loader!所以啦, 你會發現安裝多重作業系統時,你的 MBR 常常會被不同的作業系統的 boot loader 所覆蓋啦! ^_^

我們剛剛提到的兩個問題還是沒有解決啊!雖然各個作業系統都可以安裝一份 boot loader 到他們的 boot sector 中, 這樣作業系統可以透過自己的 boot loader 來載入核心了。問題是系統的 MBR 只有一個哩! 你要怎麼運行 boot sector 裡面的 loader 啊?

boot loader 主要的功能如下:

  • 提供菜單:使用者可以選擇不同的啟動項目,這也是多重啟動的重要功能!
  • 載入核心檔案:直接指向可開機程式區段來開始作業系統;
  • 轉交其他 loader:將啟動管理功能轉交給其他 loader 負責。

由於具有菜單功能,因此我們可以選擇不同的核心來啟動。而由於具有控制權轉交的功能,因此我們可以載入其他 boot sector 內的 loader 啦!不過 Windows 的 loader 預設不具有控制權轉交的功能,因此你不能使用 Windows 的 loader 來載入 Linux 的 loader 喔!這也是為啥第三章談到 MBR 與多重啟動時,會特彆強調先裝 Windows 再裝 Linux 的緣故。 我們將上述的三個功能以底下的圖示來解釋你就看的懂了!(與第三章的圖示也非常類似啦!)

圖 1.2.2、 啟動管理程式的菜單功能與控制權轉交功能

如所示,我的 MBR 使用 Linux 的 grub 這個啟動管理程式,並且裡面假設已經有了三個菜單, 第一個菜單可以直接指向 Linux 的核心檔案並且直接載入核心來啟動;第二個菜單可以將啟動管理程式控制權交給 Windows 來管理,此時 Windows 的 loader 會接管啟動流程,這個時候他就能夠啟動 windows 了。第三個菜單則是使用 Linux 在 boot sector 內的啟動管理程式,此時就會跳出另一個 grub 的菜單啦!瞭解了嗎?

而最終 boot loader 的功能就是『載入 kernel 檔案』啦!

 

載入核心偵測硬體與 initrd

當我們藉由 boot loader 的管理而開始讀取核心檔案後,接下來, Linux 就會將核心解壓縮到主記憶體當中, 並且利用核心的功能,開始測試與驅動各個周邊裝置,包括儲存裝置、CPU、網路卡、音效卡等等。 此時 Linux 核心會以自己的功能重新偵測一次硬體,而不一定會使用 BIOS 偵測到的硬體資訊喔!也就是說,核心此時才開始接管 BIOS 後的工作了。 那麼核心檔案在哪裡啊?一般來說,他會被放置到 /boot 裡面,並且取名為 /boot/vmlinuz 才對!

[root@www ~]# ls --format=single-column -F /bootconfig-2.6.18-92.el5      <==此版本核心被編譯時間選擇的功能與模組配置檔grub/                     <==就是啟動管理程式 grub 相關資料目錄initrd-2.6.18-92.el5.img  <==虛擬檔案系統檔!System.map-2.6.18-92.el5  <==核心功能放置到記憶體位址的對應表vmlinuz-2.6.18-92.el5     <==就是核心檔案啦!最重要者!

從上表我們也可以知道此版本的 Linux 核心為 2.6.18-92.el5 這個版本!為了硬體開發商與其他核心功能開發人員的便利, 因此 Linux 核心是可以透過動態載入核心模組的 (就請想成驅動程式即可),這些核心模組就放置在 /lib/modules/ 目錄內。 由於模組放置到磁碟根目錄內 (要記得 /lib 不可以與 / 分別放在不同的 partition !), 因此在啟動的過程中核心必須要掛載根目錄,這樣才能夠讀取核心模組提供載入驅動程式的功能。 而且為了擔心影響到磁碟內的檔案系統,因此啟動過程中根目錄是以唯讀的方式來掛載的喔。

一般來說,非必要的功能且可以編譯成為模組的核心功能,目前的 Linux distributions 都會將他編譯成為模組。 因此 隨身碟, SATA, SCSI... 等磁碟裝置的驅動程式通常都是以模組的方式來存在的。 現在來思考一種情況,假設你的 linux 是安裝在 SATA 磁碟上面的,你可以透過 BIOS 的 INT 13 取得 boot loader 與 kernel 檔案來啟動,然後 kernel 會開始接管系統並且偵測硬體及嘗試掛載根目錄來取得額外的驅動程式。

 

問題是,核心根本不認識 SATA 磁碟,所以需要載入 SATA 磁碟的驅動程式, 否則根本就無法掛載根目錄。但是 SATA 的驅動程式在 /lib/modules 內,你根本無法掛載根目錄又怎麼讀取到 /lib/modules/ 內的驅動程式?是吧!非常的兩難吧!在這個情況之下,你的 Linux 是無法順利啟動的! 那怎辦?沒關係,我們可以透過虛擬檔案系統來處理這個問題。

虛擬檔案系統 (Initial RAM Disk) 一般使用的檔名為 /boot/initrd ,這個檔案的特色是,他也能夠透過 boot loader 來載入到記憶體中, 然後這個檔案會被解壓縮並且在記憶體當中類比成一個根目錄, 且此類比在記憶體當中的檔案系統能夠提供一支可啟動並執行程式,透過該程式來載入啟動過程中所最需要的核心模組, 通常這些模組就是 隨身碟, RAID, LVM, SCSI 等檔案系統與磁碟介面的驅動程式啦!等載入完成後, 會協助核心重新呼叫 /sbin/init 來開始後續的正常啟動流程。

如所示,boot loader 可以載入 kernel 與 initrd ,然後在記憶體中讓 initrd 解壓縮成為根目錄, kernel 就能夠藉此載入適當的驅動程式,最終釋放虛擬檔案系統,並掛載實際的根目錄檔案系統, 就能夠開始後續的正常啟動流程。更詳細的 initrd 說明,你可以自行使用 man initrd 去查閱看看。 底下讓我們來瞭解一下 CentOS 5.x 的 initrd 檔案內容有什麼吧!

# 1. 先將 /boot/initrd 複製到 /tmp/initrd 目錄中,等待解壓縮:[root@www ~]# mkdir /tmp/initrd[root@www ~]# cp /boot/initrd-2.6.18-92.el5.img /tmp/initrd/[root@www ~]# cd /tmp/initrd[root@www initrd]# file initrd-2.6.18-92.el5.imginitrd-2.6.18-92.el5.img: gzip compressed data, ...# 原來是 gzip 的壓縮檔!因為是 gzip ,所以副檔名給他改成 .gz 吧!# 2. 將上述的檔案解壓縮:[root@www initrd]# mv initrd-2.6.18-92.el5.img initrd-2.6.18-92.el5.gz[root@www initrd]# gzip -d initrd-2.6.18-92.el5.gz[root@www initrd]# file initrd-2.6.18-92.el5initrd-2.6.18-92.el5: ASCII cpio archive (SVR4 with no CRC)# 搞了老半天,原來還是 cpio 的命令壓縮成的檔案啊!解壓縮看看!# 3. 用 cpio 解壓縮[root@www initrd]# cpio -ivcdu < initrd-2.6.18-92.el5[root@www initrd]# lldrwx------ 2 root root    4096 Apr 10 02:05 bindrwx------ 3 root root    4096 Apr 10 02:05 devdrwx------ 2 root root    4096 Apr 10 02:05 etc-rwx------ 1 root root    1888 Apr 10 02:05 init-rw------- 1 root root 5408768 Apr 10 02:00 initrd-2.6.18-92.el5drwx------ 3 root root    4096 Apr 10 02:05 libdrwx------ 2 root root    4096 Apr 10 02:05 proclrwxrwxrwx 1 root root       3 Apr 10 02:05 sbin -> bindrwx------ 2 root root    4096 Apr 10 02:05 sysdrwx------ 2 root root    4096 Apr 10 02:05 sysroot# 看!是否很像根目錄!尤其也是有 init 這個運行檔!務必看一下許可權!# 接下來看看 init 這個檔案內有啥咚咚?# 4. 觀察 init 檔案內較重要的運行項目[root@www initrd]# cat init#!/bin/nash                  <==使用類似 bash 的 shell 來運行mount -t proc /proc /proc    <==掛載記憶體的虛擬檔案系統....(中間省略)....echo Creating initial device nodesmknod /dev/null c 1 3        <==建立系統所需要的各項裝置!....(中間省略)....echo "Loading ehci-hcd.ko module"insmod /lib/ehci-hcd.ko      <==載入各項核心模組,就是驅動程式!....(中間省略)....echo Creating root device.mkrootdev -t ext3 -o defaults,ro hdc2 <==嘗試掛載根目錄啦!....(底下省略)....

透過上述運行檔的內容,我們可以知道 initrd 有載入模組並且嘗試掛載了虛擬檔案系統。 接下來就能夠順利的運行啦!那麼是否一定需要 initrd 呢?

是否沒有 initrd 就無法順利啟動?答:不見得的!需要 initrd 最重要的原因是,當啟動時無法掛載根目錄的情況下, 此時就一定需要 initrd ,例如你的根目錄在特殊的磁碟介面 (隨身碟, SATA, SCSI) , 或者是你的檔案系統較為特殊 (LVM, RAID) 等等,才會需要 initrd。如果你的 Linux 是安裝在 IDE 介面的磁碟上,並且使用預設的 ext2/ext3 檔案系統, 那麼不需要 initrd 也能夠順利的啟動進入 Linux 的!

在核心完整的載入後,您的主機應該就開始正確的運行了

 

 轉自 http://vbird.dic.ksu.edu.tw/linux_basic/0510osloader_1.php

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.