介紹
作業系統老師說,平時面試學生或者畢業答辯的時候他都會問這個問題,可見這個問題對於計算機專業的學生來說是如此重要。那麼,從開啟計算機電源到計算機的螢幕顯示,中間經歷了哪些過程呢?
啟動的英文是boot
,來自於一個諺語
pull oneself up by one's bootstraps
通過拉自己的鞋帶把自己拽起
這個很明顯是矛盾的。工程師早期用這句諺語用來比喻早期的計算機開機,
因為計算機啟動需要執行程式,而執行程式又需要計算機啟動。這個是一個很矛盾的過程。直到後來開機程式被刷入ROM
晶片後,這個開機的boot
大概過程是這樣的:
Turn on
CPU jump to physical address of BIOS(In Intel it is 0xFFFF0)
BIOS runs POST(Power-On Self Test)
Find bootable devices
Loads boot sector from MBR
BIOS yields control to OS BootLoader
1. BIOS
BIOS介紹:
BIOS(Basic Input/Output System)是基本輸入輸出系統的簡稱。BIOS 能為電腦提供最低階、最直接的硬體控制與支援,是聯絡最底層的硬體系統和軟體系統的橋樑。為了在關機後使 BIOS 不會丟失,早期的 BIOS 儲存在 ROM 中,並且其大小不會超過 64KB;而目前的 BIOS 大多有 1MB 到 2MB,所以會被儲存在 快閃記憶體(Flash Memory)中。
BIOS 設定程式是被固化到電腦主機板上地 ROM 晶片中的一組程式,其主要功能是為電腦提供最底層的、最直接的硬體設定和控制。 BIOS 通常與
硬體系統整合在一起(在計算機主機板的 ROM 或EEPROM 中),所以也被稱為 韌體
如何執行
BIOS存放在一個斷電後不會丟失內容的ROM中,這保證了“拽著鞋帶拉起自己”的這種情況不會發生。因為系統一上電或重置,處理器要執行第一條指令的地址會被定位到BIOS儲存器,初始化開始執行。在X86系統中,CPU加電後跳轉至BIOS的固定實體地址0xFFFF0。
開啟計算機電源,計算機會首先載入BIOS,包含
CPU相關資訊
裝置啟動順序資訊
硬碟資訊
記憶體資訊
時鐘資訊
PhP特性
...
硬體自檢(Power-On Self Test,POST)
如果硬體出現問題,主機板會發出不同含義的蜂鳴 ,啟動中止。如果沒有問題,螢幕就會顯示出CPU 、記憶體、硬碟等資訊。BIOS在執行完硬體自檢和初始化後,會將自己複製到從 0xA0000 開始的實體記憶體中並繼續執行。
BIOS 程式碼包含診斷功能,以保證某些重要硬體元件,像是
鍵盤、磁碟裝置、輸出輸入埠等等,可以正常運作且正
確地初始化。
BIOS產生的問題
- 開發效率低:大部分BIOS程式碼使用匯編開發,開發效率不言而喻。彙編開發的另一個缺點是使得程式碼與裝置的耦合程度太高,程式碼受硬體變化的影響大。
- 效能差:BIOS基本輸入/輸出服務需要通過中斷來完成,開銷大,並且BIOS沒有提供非同步工作模式,大量的時間消耗在等待上。
- 功能擴充套件性差,升級緩慢:BIOS程式碼採用靜態連結,增加硬體功能時,必須將16位程式碼放置在0x0C0000~0x0DFFFF區間,初始化時將其設定為約定的中斷處理程式。而且BIOS沒有提供動態載入裝置驅動的方案。
- 安全性:BIOS執行過程中對可執行程式碼沒有安全方面的考慮。
- 不支援從硬碟2TB以上的地址引導:受限於BIOS硬碟的定址方式,BIOS硬碟採用32位地址,因而引導扇區的最大邏輯塊地址是232(換算成位元組地址,即232×512=2TB)
由於這些問題的存在,UEFI
橫空出世
UEFI中文名為統一可擴充套件韌體介面(英語:Unified Extensible Firmware Interface,縮寫UEFI)是一種個人電腦系統規格,用來定義作業系統與系統硬體之間的軟體介面,作為BIOS的替代方案。可擴充套件韌體介面負責加電自檢(POST),聯絡作業系統以及提供連線作業系統與硬體的介面。
UEFI與BIOS的幾個區別
EFI使用模組化、C語言風格的引數堆疊傳遞方式以及動態連結形式構建的系統,相對於BIOS而言跟容易實現,容錯和糾錯特性更強,減少系統研發的時間。
執行於32位或64位模式,面對未來增強的處理器模式下,能突破BIOS 16位程式碼的定址能力,達到處理器最大定址。
UEFI有良好的滑鼠操控圖形化介面,在開機速度也比BIOS快不少
BIOS過程
UEFI過程
相對來說UEFI比BIOS少了一個硬體檢測
即使如此,本章啟動過程還是著重於分析利用BIOS啟動的過程。
2.讀取MBR
MBR-全稱是Master Boot Record(主開機記錄或主開機記錄),是一個512byte的扇區,位於磁碟的固定位置。之所以叫“主開機記錄”,是因為其存在於驅動器開始部分的一個特殊扇區,個扇區包含已安裝的作業系統啟動記載器和驅動器的邏輯分割槽資訊。BIOS完成POST和初始化之後,會根據CMOS中設定的順序選擇引導的裝置,這個裝置可以是U盤可以是硬碟。若設定為硬碟,則BIOS就會讀取MBR。MBR裡面包含了一段載入程式,一個分割槽表和Magic Number。
MBR的結構
位置 | 作用 |
---|---|
1-445位元組 | 呼叫作業系統的機器碼(Call OS) |
447-510位元組 | 分割槽表(Partition table) |
511-512位元組 | 主開機記錄簽名(只有兩個,0x55和0xAA,為Magic Number),如果不是這兩個幻數,就認為這是一個沒有被分割槽的硬碟。 |
分割槽表的長度只有64個位元組,裡面分為四項,每項為16個位元組。所以一個硬碟只可以分四個一級分割槽,又叫做“主分割槽”。每個主分割槽的16個位元組,結構如下
位置(位元組) | 作用 |
---|---|
1 | 如果第一個為0x80,表示該主分割槽是啟用分割槽(active),控制權將轉交給此分割槽。幾個分割槽中只能有一個是啟用分割槽,其他都是非啟用分割槽(inactive)。 |
2-4 | 主分割槽的第一個扇區物理位置(柱面、磁頭、扇區號等) |
5 | 主分割槽的型別 分割槽型別符 |
6-8 | 主分割槽最後一個扇區的物理位置 |
9-12 | 主分割槽第一個扇區的邏輯位置 |
13-16 | 主分割槽的扇區總數,決定了主分割槽的長度 |
其中第5位元組分割槽型別符,有如下特定符
00H H —— 表示該分割槽未用 ( 即沒有指定 ) ;
06H H —— FAT 16 基本分割槽;
0 0 BH —— FAT 32 基本分割槽;
05H H —— 擴充套件分割槽;
07H H —— NTFS 分割槽;
0 0 FH —— ( LBA 模式 ) 擴充套件分割槽 (83H H 為 Linux)
分出主分割槽後,其餘的部分可以分成擴充套件分割槽,一般是剩下的部分全部分成擴充套件分割槽,也可以不全分,剩下的部分就浪費了。擴充套件分割槽不能直接使用,必須分成若干邏輯分割槽。所有的邏輯分割槽都是擴充套件分割槽的一 部分 。
硬碟的容量 = 主分割槽的容量 + 擴充套件分割槽的容量
擴充套件分割槽的容量 = 各個邏輯分割槽的容量之和
3.啟動Boot Loader
Linux的Boot的過程
Boot Loader
又叫做 作業系統核心載入器(OS kernel loader),一個在kernel
執行前執行的一段小程式,通過這段程式可以初始化硬體裝置,建立記憶體空間的對映,將系統軟硬體環境帶到一個合適的狀態,便於未來呼叫作業系統核心。
LILO | GRUB |
---|---|
無互動命令介面 | 有互動命令介面 |
不支援網路引導 | 支援 |
錯誤配置MBR會讓系統無法引導 | 如果配置檔案錯誤,則預設跳轉到GRUB命令列介面 |
GRUB 磁碟引導的過程如下
- stage1: grub 讀取磁碟第一個 512 位元組(硬碟的0道0 面1扇區,被稱為 MBR (主開機記錄), 也稱為bootsect )。 MBR 由一部分 bootloader 的引導代
碼、分割槽表和魔數三部分組成。( 啟動的第二步 )
- Stage1.5: 識別各種不同的檔案系統格式。這使得 grub 識別到檔案系統。
- stage2: 載入系統引導選單 (/boot/grub/ menu.lst或 grub.lst) ) ,載入核心映像 (kernel image) 和 RAM磁碟 initrd (可選)。
執行主載入程式的具體過程
BIOS將硬碟主開機記錄讀入7C00處,並將控制權交給主載入程式:
- 檢查0x7dfe地址處是否等於0xaa55。不是則去其他介質;如果沒有啟動的介質,顯示“No ROME BASIC”並當機。
- 成功找到介質,跳轉到0X7C00執行MBR的程式
- 將自己複製到0x0600處且繼續執行
- 主分割槽表中搜尋標誌為啟用的分割槽,如果發現沒有啟用分割槽或者不止一個啟用分割槽則停止。
- 將啟用分割槽的第一個扇區讀入記憶體地址0x7c00
- 再次檢查位於地址0x7dfe的內容是否等於0xaa55,若不等則停止並嘗試軟盤啟動
- 跳轉到0x7c00繼續執行特定系統的啟動程式
補充:MBR和引導扇區的關係
- MBR存放的位置是整個硬碟的第一個扇區
- Boot Sector是硬碟上每一個分割槽的第一個扇區
4. 載入kernel
主要有兩個步驟:
根據 grub 設定的核心映像所在路徑 ,系統讀取記憶體映像 ,並進行解壓縮操
作 。系統將解壓後的核心放置在記憶體之中, 初始化函式並初始化各種裝置 , 完
成 Linux 核心環境的建立 。
以Linux系統為例,先載入/boot目錄下面的kernel。
核心載入成功後,第一個執行的程式是/sbin/init。它根據配置檔案(Debian系統是/etc/initab)產生init程式。這是Linux啟動後的第一個程式,pid程式編號為1,其他程式都是它的後代。
然後,init執行緒載入系統的各個模組,比如視窗程式和網路程式,直至執行/bin/login程式,跳出登入介面,等待使用者輸入username和password。
至此,全部啟動過程完成。