2009年1月13日 星期二

boot loader 與 kernel 載入

由第一篇裡面談到的一些基礎的主機硬體概念當中,我們知道整個主機在開機的時候,第一個被讀取的地方, 就是 BIOS ( Basic Input Output System ) 啦,這個 BIOS 裡面記錄了主機板的晶片組與相關的設定, 例如 CPU 與周邊設備的溝通時脈啊、開機裝置的搜尋順序啊、硬碟的大小與類型啊、 系統時間啊、各周邊匯流排的是否啟動 Plug and Play (PnP, 隨插即用裝置) 啊、 各周邊設備的 I/O 位址啊、以及與 CPU 溝通的 IRQ 岔斷等等的資訊都記錄在此, 所以囉,系統要順利的開機,首先就是要去讀取 BIOS 的相關設定值了。

讀取了 BIOS 設定值之後,系統會根據 BIOS 的資料,進行開機自我測試 (power on self test, POST), 然後開始執行硬體偵測的初始化,並設定 PnP 裝置,之後再定義出可開機的裝置, 之後就會開始進行開機裝置的資料讀取了 (MBR 相關的任務開始)。

讀完了 BIOS 並且瞭解了主要的主機硬體相關資訊後,主機便會開始嘗試由儲存媒體載入作業系統了。 我們剛剛提到 BIOS 會記錄『可用來開機的裝置搜尋順序』對吧!所以,系統會開始去第一個開機裝置上面進行開機程序。 我們在第二篇的 磁碟檔案系統(filesystem) 當中提到過整個儲存裝置的特性, 如果以硬碟來看,那麼開機流程讀到硬碟的過程中,第一個要讀取的就是該硬碟的主要開機磁區 (Master Boot Record, MBR) 了,而系統可以由主要開機區所安裝的開機管理程式 (boot loader) 開始執行核心辨識的工作。
Tips:
我們知道每顆硬碟的第一個磁區稱為 MBR ,那麼如果我的主機上面有兩顆硬碟的話, 系統會去哪顆硬碟的 MBR 讀取資料呢?這個就得要看 BIOS 的設定了。 基本上,我們常常講的『系統的 MBR』其實指的是 第一個開機裝置的 MBR 才對! 所以,改天如果您要將開機管理程式安裝到某顆硬碟的 MBR 時, 要特別注意當時系統的『第一個開機裝置』是那個,否則會安裝到錯誤的硬碟上面喔!重要重要!
鳥哥的圖示
那麼為什麼要在 MBR 安裝 boot loader 呢?而這個 boot loader 有什麼功能呢? 還記得我們在第二篇提到的 磁碟檔案系統 吧? 我們的作業系統核心必須要認識磁碟檔案系統才能讀取裡面的資料啊, 但是整個系統才剛剛到開機起頭的地方而已,要如何認識磁碟檔案格式呢? 那就得要藉由 boot loader 來輔助啦!所以囉,當然必須要有 boot loader 才有辦法載入 Linux 的核心 (kernel) 啊!由於 boot loader 的特殊功能,因此,想要載入 Linux 核心時, 當然得使用支援 Linux filesystem 的 boot loader 了,目前主流的 grub 這套開機管理程式, 不但可以支援 Linux ,同時也支援 Windows 相關的核心系統呢!

好了,先再來回憶一下,如果你是以 grub 程式開機的話,那麼在開機的時候會顯示什麼資料呢?呵呵! 會顯示蠻多的開機選單,沒錯~就是『選單』,然後選擇了你的選擇項目之後, 系統就會跑到該磁區去讀取該作業系統的核心囉!呵呵!所以一個好的 boot loader 會具有兩個功能,就是:
  • 選單功能 (menu)
  • 指向功能 (pointer)
再來強調一下,因為 Windows 與 Linux 的檔案格式不一樣?! 為了載入系統核心,所以必須要安裝認識我們作業系統的 loader, 而 Linux 的 loader ( lilo 或 grub ) 是可以認識 windows 的核心檔案的,但是 Windows 的 loader 卻不認識 Linux 的核心檔案,因此,作為一個多重開機的設定 loader ,就無法使用 Windows 所提供的 loader 囉!由於需要讓系統認識你的 kernel ,因此,就需要 boot loader 啦!這樣想就對啦!

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

在載入核心的過程當中,我們必須要知道的是,系統只會『掛載根目錄』而已,而且是以唯讀的方式掛載的。 此外,有時為了讓某些功能可以用檔案的方式來讀取,因此,有的系統在開機的時候, 會製作所謂的虛擬硬碟 (RAM Disk) 來輔助的,那就是 initrd 以及 linuxrc 的功用了。 利用 boot loader 的功能,可以在載入核心的時候,一起載入 initrd 的映象檔 (/boot/initrd-xxxx.img), Linux 系統會主動的以 initrd (man 4 initrd) 來進行虛擬硬碟的建置, 並且利用 linuxrc (包含在 initrd 的映象檔內) 這個程式的功能來進行載入模組的動作。 linuxrc 主要的特性是:
  • 必須是 linuxrc 這個檔名;
  • 必須放置在 initrd 所建立的虛擬磁碟的最頂層目錄;
  • 必須要可以被核心所執行。
在核心驅動周邊硬體的工作完成之後, initrd 所建立的虛擬磁碟就會被移除了! 不過您要注意的是, initrd 並非必要的,是可有可無的,要看您當初建立該核心的時候, 整個編譯的角度與過程。一般來說,各大 Linux distributions 在建立核心時, 都會一起建立出這個 initrd 的映象檔,輔助開機的順利進行。

總之,在這個過程當中, boot loader 可以找到 Linux 的核心檔案並且將他載入到主記憶體當中, 同時可能可以藉由 initrd 建立起虛擬硬碟 (RAM Disk) 輔助開機的進行, 最後,將讀自 BIOS 的主機硬體資料交由 Linux 核心來進行偵測並且載入適當的驅動程式 (driver) ,就讓整個主機硬體準備系統的要求了。整個流程有點像這樣:

BIOS 與 boot loader 及核心載入流程示意圖
圖一、BIOS 與 boot loader 及核心載入流程示意圖

在核心完整的載入後,您的主機應該就開始正確的運作了,接下來,就是要開始執行系統的第一支程式: init。