當 x86 CPU 電源連通後,它的 EIP (The Instruction Pointer) 被硬編碼到地址 0xFFFFFFF0
,即內存的最後 16 位。這時 CPU 是處於實模式 (Real Mode) 的,所以相當於從 0xFFFFFFF0
開始 CPU 可以執行一條命令。
實模式 (Real Mode) 和 保護模式 (Protected Mode) 是 CPU 的兩種工作模式,實模式是早期 CPU 的工作模式,保護模式是現代 CPU 的工作模式。實模式出現在 8086 CPU 時代,運行的是 16 位指令。但 16 位 CPU 最多支持 1MB 的尋址(20 根地址線),所以後來內存越來越大後寄存器的位數就變成了 32 位。所以就引入了保護模式,用來實現更大空間的,更靈活的內存訪問。
與實模式尋址的
segment << 4 + offset
不同,保護模式的尋址方式是通過邏輯地址 (Logical Address) 的segment:offset
中的segment
作為selector
來索引到GDT/LDT
中的一項,然後通過flags
判斷當前程序是否可以訪問這段內存,可以訪問的話提取base
與offset
相加得到線性地址 (Linear Address),最後將線性地址通過分頁表得到物理地址 (Physical Address)。
現代 CPU 在運行 BootLoader 的時候仍然要先進入實模式,這是為了實現軟件的向後兼容。
0xFFFFFFF0
開始的這 16 位大小的地址被叫做 重置向量 (Reset Vector)。這時,BIOS 會將自己移動到 RAM 中,這樣可以在後面的運行中有更快的訪問速度,而主板廠商會保證 0xFFFFFFF0
這個地址指向 BIOS 的地址(通常 0xFFFFFFF0
這裡就是一個 jmp
指令)。於是 BIOS 就開始運行了。
BIOS 會按照設定掃描不同的設備(硬盤,CD-ROM,Flash Drive,等等)並判斷設備中是否可引導 (Bootable)。這個判斷的方式通常是去查看設備的第一個 Sector 的最後兩字節(即 511 和 512 字節)是否為 0xAA55
(注意是低字節序 Little-Endian 還是高字節序 Big-Endian),是的話該設備就是可引導的。
當 BIOS 發現了可引導設備後,他就會把該可引導設備的第一個 Sector 複製到 RAM 中的 0x7c00
(從 0x7c00
開始的 512 字節),並跳到 0x7c00
開始執行複製的程序。這一段程序通常被叫做 Bootloader。
Bootloader 於是開始從 RAM 中的 0x100000
加載系統內核。基本上所有的 x86 操作系統的內核都在 0x100000
。在這個過程中,Bootloader 或者是操作系統本身會把 CPU 的運行模式從實模式切換到保護模式。於是我們的操作系統就被啟動了。