Skip to main content

x86 Linux Boot Flow(x86 Linux 開機流程)

從按下電源鍵到登入提示符,x86 架構的 Linux 開機流程跨越韌體、Bootloader、Kernel 與 Userspace 四個層次。本文整理完整流程,並涵蓋 BIOS/Legacy 與現代 UEFI 兩種路徑的差異。

整體流程概覽

Power On


CPU Reset Vector(0xFFFFFFF0)

├─── Legacy ────────────────────────────────────────┐
│ │
▼ ▼
BIOS(POST) UEFI Firmware(POST)
│ │
▼ ▼
MBR Bootloader UEFI Boot Manager
│ │
▼ ▼
Stage 2 Bootloader(GRUB) EFI Application(GRUB / systemd-boot)
│ │
└────────────────────┬──────────────────────────────┘


Linux Kernel(vmlinuz)


initramfs / initrd


pivot_root → 真正的 RootFS


init(systemd / SysVinit)


Login / Desktop

1. CPU Reset Vector

說明

x86 處理器上電或 Reset 後,CS:IP 被設置為固定位址 0xFFFF:0xFFF0(實際映射至 0xFFFFFFF0),這是 Reset Vector,CPU 從此處取第一條指令執行。

該位址映射至主機板 SPI Flash 上的韌體(BIOS 或 UEFI)

硬體初始化背景

  • CPU 初始進入 Real Mode(16-bit,只能定址 1MB)
  • 多核心 CPU 只有 BSP(Bootstrap Processor) 執行開機流程
  • 其他 CPU 核心(AP, Application Processor)等待被喚醒

2a. BIOS(Legacy)路徑

POST(Power-On Self Test)

BIOS 執行一系列硬體自我測試:

  • 偵測並初始化 CPU、記憶體(DRAM)、晶片組
  • 偵測儲存裝置(IDE / SATA / NVMe)
  • 初始化 VGA 顯示
  • 若有錯誤,發出 POST Beep Code

INT 13h 與 Boot Device 選擇

BIOS 遍歷啟動裝置順序(Boot Order),找到可開機裝置後:

從 Boot Device 的第一個磁區(512 bytes)讀取 MBR

├─ 檢查結尾是否為 Magic Number 0x55AA

└─ 載入至記憶體位址 0x7C00 並跳轉執行

MBR 結構(512 bytes)

┌──────────────────────────────────────┐  偏移 0x000
│ Bootstrap Code(Stage 1) │ 446 bytes
├──────────────────────────────────────┤ 偏移 0x1BE
│ Partition Table Entry 1 │ 16 bytes
│ Partition Table Entry 2 │ 16 bytes
│ Partition Table Entry 3 │ 16 bytes
│ Partition Table Entry 4 │ 16 bytes
├──────────────────────────────────────┤ 偏移 0x1FE
│ Magic Number:0x55AA │ 2 bytes
└──────────────────────────────────────┘

MBR 限制

  • 最多 4 個主要分割區
  • 分割區大小最大 2TB(32-bit LBA)
  • Stage 1 程式碼空間僅 446 bytes,功能極有限

2b. UEFI(現代)路徑

UEFI 概覽

UEFI(Unified Extensible Firmware Interface)是 BIOS 的現代替代品,提供更豐富的功能:

特性BIOSUEFI
位元模式16-bit Real Mode32/64-bit Protected Mode
分割表MBR(最大 2TB)GPT(最大 9.4ZB)
安全開機Secure Boot
開機介面文字圖形 UI
網路開機有限完整支援(PXE via EFI)

UEFI 開機流程分階段(PI 規範)

SEC(Security Phase)
│ 初始化快取作為 RAM(Cache-as-RAM),執行最早期的信任根

PEI(Pre-EFI Initialization)
│ 初始化 DRAM,載入 DXE Core

DXE(Driver Execution Environment)
│ 載入驅動程式(儲存、網路、顯示...),初始化所有硬體

BDS(Boot Device Selection)
│ UEFI Boot Manager 讀取 NVRAM 中的 BootOrder 變數

EFI Boot Application(e.g., GRUB、systemd-boot)
│ 從 ESP(EFI System Partition)中的 .efi 檔案執行

OS Loader(handoff 到 Kernel)

ESP(EFI System Partition)

ESP(FAT32 分割區)
└── EFI/
├── BOOT/
│ └── BOOTX64.EFI ← 預設開機項目(Fallback)
├── ubuntu/
│ └── shimx64.efi ← Secure Boot shim
│ └── grubx64.efi
└── systemd/
└── systemd-bootx64.efi

Secure Boot

UEFI Firmware 持有 PK(Platform Key)

└─ 驗證 KEK(Key Exchange Key)

└─ 驗證 db(Allowed Signatures Database)

└─ 驗證 shim / Bootloader 簽章

└─ 驗證 Kernel 簽章

Secure Boot 確保整條啟動鏈上的每個元件都有可信任的簽章,防止 Bootkit 攻擊。


3. GRUB(GRand Unified Bootloader)

GRUB 是 Linux 最廣泛使用的 Bootloader,支援 Legacy MBR 與 UEFI 兩種模式。

GRUB 載入階段

Legacy 模式

Stage 1(MBR,446 bytes)
│ 位置有限,只夠儲存跳轉指令

Stage 1.5(MBR Gap 或 Boot Partition)
│ 提供讀取檔案系統的基本驅動(ext4、XFS...)

Stage 2(/boot/grub/)
│ 完整 GRUB 環境,顯示選單、讀取設定

grub.cfg 解析與選單

UEFI 模式

grubx64.efi(直接從 ESP 載入)
│ 包含完整 GRUB,無需 Stage 1.5

grub.cfg 解析(通常位於 /boot/grub/grub.cfg)

grub.cfg 範例

menuentry 'Ubuntu 24.04 LTS' {
insmod gzio
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
linux /boot/vmlinuz-6.8.0-45-generic \
root=/dev/sda2 ro quiet splash
initrd /boot/initrd.img-6.8.0-45-generic
}

GRUB 傳遞給 Kernel 的資訊

  • Kernel Image 路徑(vmlinuz)
  • initrd/initramfs 路徑
  • Kernel cmdline 參數root=roquietconsole=...)
  • 記憶體映射表(e820 map)

4. Linux Kernel 初始化

Kernel 被載入至記憶體後開始執行,分為幾個明確的階段:

4.1 解壓縮階段(Decompression)

vmlinuz 是壓縮過的 Kernel Image,自帶解壓縮程式碼:

vmlinuz(壓縮 Image)
│ 執行頭部的解壓縮 stub

vmlinux(解壓縮後的真實 Kernel ELF)
│ 位於記憶體中

Kernel Entry Point(start_kernel())

4.2 早期初始化(Arch Setup)

// arch/x86/kernel/head_64.S → init/main.c
start_kernel()

├─ setup_arch() // CPU 架構設定、記憶體偵測
├─ mm_init() // 記憶體管理初始化(buddy allocator、slab)
├─ sched_init() // 排程器初始化
├─ irq_init() // 中斷向量表設置
├─ time_init() // 時鐘初始化(TSC / HPET / PIT)
└─ rest_init() // 啟動 kernel threads

4.3 CPU 模式切換

Real Mode(16-bit)
│ BIOS/UEFI 期間

Protected Mode(32-bit)
│ Kernel 早期初始化

Long Mode(64-bit)
│ 現代 x86-64 Kernel 標準模式

啟用 MMU(虛擬記憶體分頁)

4.4 重要 Kernel 子系統初始化順序

記憶體管理(Memory Management)

虛擬記憶體(VMM / paging)

中斷與例外處理(IRQ / IDT)

處理器排程(Scheduler / CFS)

計時器(jiffies / hrtimer)

驅動程式核心(Driver Core / sysfs)

PCI 總線掃描

儲存裝置驅動(AHCI / NVMe / virtio)

虛擬檔案系統(VFS)

掛載 initramfs

執行 /init(第一個 userspace 程序)

Kernel 參數(cmdline)常見參數

root=/dev/sda2         # RootFS 裝置
ro # 唯讀掛載 root(fsck 後重新 remount rw)
quiet # 抑制開機訊息
splash # 顯示開機動畫
console=tty0 # 主控台輸出至螢幕
console=ttyS0,115200 # 同時輸出至序列埠
init=/bin/bash # 緊急模式:直接執行 bash
single # 進入單人模式(maintenance mode)
nomodeset # 停用 KMS(顯示驅動問題時使用)

5. initramfs / initrd

為什麼需要 initramfs?

Kernel 本身不包含所有驅動程式(例如 LUKS 加密、RAID、特定 NVMe 驅動),但掛載 RootFS 前就需要這些驅動,形成「雞生蛋、蛋生雞」的問題。initramfs 是解法:在 Kernel 內建立一個暫時的 in-memory RootFS,提供必要工具後再切換至真正的 RootFS。

initramfs 結構

initramfs(cpio + gzip/zstd 壓縮)
├── bin/ ← BusyBox 等基本工具
├── sbin/
│ └── init ← 暫時的 init 腳本
├── lib/
│ └── modules/ ← 必要的 Kernel 模組(.ko)
├── etc/
└── scripts/ ← 掛載腳本(Debian 系)

initramfs 主要工作

/init(initramfs 內)

├─ 載入必要 Kernel 模組(insmod)
│ 例如:dm_crypt、raid1、nvme、xfs

├─ 解鎖 LUKS 加密磁區(若有)

├─ 組裝 RAID / LVM(若有)

├─ 執行 fsck(檔案系統檢查)

└─ pivot_root / switch_root

└─ 切換至真正的 RootFS,執行 /sbin/init

6. systemd(現代 init)

說明

現代 Linux 發行版(Ubuntu、Fedora、Debian、Arch)幾乎全面採用 systemd 作為 PID 1 的 init 系統。

啟動 Target 順序

default.target(通常指向 graphical.target 或 multi-user.target)

├─ graphical.target
│ ├─ multi-user.target
│ │ ├─ basic.target
│ │ │ ├─ sysinit.target
│ │ │ │ ├─ local-fs.target(掛載本地磁區)
│ │ │ │ ├─ swap.target
│ │ │ │ └─ systemd-udevd(裝置偵測)
│ │ │ └─ network.target
│ │ ├─ NetworkManager.service
│ │ ├─ sshd.service
│ │ └─ crond.service
│ └─ display-manager.service(GDM / SDDM / LightDM)

systemd 平行化啟動

systemd 的核心優勢是平行啟動:透過分析服務相依關係(After=Requires=Wants=),讓不相依的服務同時啟動,大幅縮短開機時間。

# 分析開機時間
systemd-analyze
systemd-analyze blame # 各服務啟動耗時
systemd-analyze critical-chain # 關鍵路徑
systemd-analyze plot > boot.svg # 視覺化圖表

7. 磁碟分割架構比較

MBR vs GPT

特性MBRGPT
最大磁碟大小2 TB9.4 ZB
最大分割區數4 個主要分割區128 個分割區(預設)
備份分割表有(磁碟尾部備份)
開機方式BIOS / UEFI(CSM)UEFI(推薦)
識別方式分割區編號GUID(全域唯一識別碼)

典型 Linux 磁碟配置(UEFI + GPT)

磁碟(/dev/nvme0n1)
├── /dev/nvme0n1p1 ESP(FAT32, ~512MB) ← /boot/efi
├── /dev/nvme0n1p2 /boot(ext4, ~1GB) ← Kernel / initrd
├── /dev/nvme0n1p3 swap(或 swapfile)
└── /dev/nvme0n1p4 /(ext4 / XFS / btrfs)← RootFS

常見除錯方法

查看開機 log

# 查看 systemd 開機 log(本次開機)
journalctl -b

# 查看上次開機(崩潰或重啟後)
journalctl -b -1

# 查看 Kernel 訊息
dmesg
dmesg | grep -i "error\|fail\|warn"
dmesg --level=err,warn

# 查看開機時間分析
systemd-analyze blame

GRUB 救援模式

# 在 GRUB 選單按 'e' 編輯開機參數
# 在 kernel 行末尾加入:
init=/bin/bash # 直接進 bash(bypass init)
single # 進入單人維護模式
ro recovery # Ubuntu recovery mode

常見開機失敗原因

現象可能原因對策
黑畫面,無 GRUBMBR/ESP 損壞,GRUB 未安裝GRUB rescue 或 Live CD 修復
GRUB rescue 提示符GRUB 找不到 grub.cfgset root=insmod、手動 boot
Kernel panic: VFS mount failroot= 參數錯誤、RootFS 損毀確認 UUID/裝置名、fsck
initramfs 提示符fsck 失敗、模組缺失fsck -y /dev/sda1
systemd 服務失敗服務設定錯誤、相依未滿足journalctl -u <service>
開機卡在某服務服務 timeoutsystemctl disable <service>

BIOS vs UEFI 開機路徑對照

BIOS Legacy                          UEFI
─────────────────────────────────────────────────────────
Reset Vector (0xFFFFFFF0) Reset Vector (0xFFFFFFF0)
│ │
BIOS POST(Real Mode) SEC → PEI(Cache-as-RAM)
│ │
INT 13h 讀取 MBR DXE(驅動載入,Protected Mode)
│ │
GRUB Stage 1(446 bytes) BDS(BootOrder in NVRAM)
│ │
GRUB Stage 1.5(MBR Gap) GRUB / systemd-boot(.efi)
│ │
GRUB Stage 2(grub.cfg) grub.cfg(在 ESP 或 /boot)
│ │
└──────────── Linux Kernel ──────────┘

initramfs

systemd

參考資料