章節概覽#
本章說明 Linux kernel 從載入記憶體到啟動第一個 user space process 的完整過程。開機流程的簡化版本如下:
- 機器的 BIOS 或 boot firmware 載入並執行 boot loader
- Boot loader 在磁碟上找到 kernel image,載入記憶體並啟動
- Kernel 初始化裝置與驅動程式
- Kernel 掛載 root filesystem
- Kernel 啟動 init 程式(PID 1),這就是 user space start
- init 啟動其餘系統程序
- init 啟動登入程序,讓使用者可以登入
本章聚焦在前幾個階段,尤其是 boot loader 與 kernel 的部分。Chapter 6 則接續說明 user space 的啟動。
5.1 Startup Messages#
傳統 Unix 系統在開機時會產生大量診斷訊息,但現代 Linux 發行版通常會用 splash screen 隱藏這些訊息。
查看 kernel 開機與執行時診斷訊息的最佳方式:
# 查看當前開機的 kernel 訊息
journalctl -k
# 查看先前開機的訊息
journalctl -k -b -1如果沒有 systemd,可以檢查:
/var/log/kern.log日誌檔- 使用
dmesg命令查看 kernel ring buffer 中的訊息
kernel 啟動後,user-space 啟動程序也會產生訊息。在使用 systemd 的系統上,這些訊息會被自動捕捉保存。
5.2 Kernel Initialization and Boot Options#
Linux kernel 啟動時按以下順序進行初始化:
- CPU inspection — CPU 檢查
- Memory inspection — 記憶體檢查
- Device bus discovery — 裝置匯流排探索
- Device discovery — 裝置探索
- Auxiliary kernel subsystem setup — 輔助子系統設定(如網路)
- Root filesystem mount — 掛載根檔案系統
- User space start — 啟動 user space
前兩步較單純,但到了裝置探索階段就會出現依賴性問題。例如磁碟裝置驅動程式可能依賴匯流排支援和 SCSI 子系統支援。
某些必要元件可能是 loadable kernel modules 而非主 kernel 的一部分。部分機器需要在真正的 root filesystem 掛載前先載入這些 kernel modules,這就需要 initial RAM filesystem (initrd) 來解決。
Kernel 準備啟動第一個 user process 時,會釋放未使用的記憶體並保護自身資料:
Freeing unused kernel memory: 2408K
Write protecting the kernel read-only data: 20480k5.3 Kernel Parameters#
Linux kernel 啟動時會接收一組文字形式的 kernel parameters,用來指定系統行為,例如診斷輸出量和裝置驅動程式選項。
查看目前執行中 kernel 的參數:
cat /proc/cmdline參數格式為:
- 單字旗標,如
ro、quiet - key=value 配對,如
vt.handoff=1
重要的 kernel 參數#
- root — 指定 root filesystem 位置,這是最關鍵的參數。沒有它,kernel 無法執行 user space start。可以用裝置檔案、logical volume 或 UUID 指定:
root=/dev/sda1
root=/dev/mapper/my-system-root
root=UUID=17f12d53-c3d7-4ab3-943e-a0a72366c9fa- ro — 指示 kernel 以唯讀模式掛載 root filesystem,讓
fsck可以安全檢查。檢查完成後,開機程序會重新以讀寫模式掛載。
Kernel 遇到不認識的參數時,會將其傳遞給 init 程式。例如加上
-s參數,kernel 會把-s傳給 init,讓系統以 single-user mode 啟動。
如需更詳細的參數資訊,可以參考:
bootparam(7)man page- kernel 隨附的
kernel-params.txt參考檔案
5.4 Boot Loaders#
Boot loader 的工作看似簡單:從磁碟某處載入 kernel 到記憶體,然後帶著一組 kernel parameters 啟動它。但實際上相當複雜,因為這是一個「雞生蛋」問題 — kernel 尚未執行,正常的裝置驅動程式和檔案系統都不可用。
Boot loader 使用 BIOS 或 UEFI 來存取磁碟,透過 Logical Block Addressing (LBA) 讀取儲存硬體。LBA 效能不佳,但因為只有 boot loader 需要使用這種模式,所以不成問題。
要判斷系統使用 BIOS 或 UEFI,可以執行
efibootmgr。如果列出 boot targets,表示系統使用 UEFI。或者檢查/sys/firmware/efi是否存在。
5.4.1 Boot Loader Tasks#
Linux boot loader 的核心功能包括:
- 從多個 kernel 中選擇
- 切換不同的 kernel parameters 組合
- 允許使用者手動覆蓋和編輯 kernel image 名稱和參數
- 支援啟動其他作業系統
5.4.2 Boot Loader Overview#
常見的 boot loader:
- GRUB — Linux 系統上幾乎通用的標準,支援 BIOS/MBR 和 UEFI
- LILO — 最早的 Linux boot loader 之一(ELILO 是 UEFI 版本)
- SYSLINUX — 可從多種檔案系統執行
- LOADLIN — 從 MS-DOS 啟動 kernel
- systemd-boot — 簡單的 UEFI boot manager
- coreboot — 高效能的 PC BIOS 替代方案,可包含 kernel
- Linux Kernel EFISTUB — 直接從 EFI/UEFI System Partition 載入 kernel
- efilinux — UEFI boot loader 的參考實作
本書主要討論 GRUB。
5.5 GRUB Introduction#
GRUB 全名為 Grand Unified Boot Loader,本書涵蓋的是 GRUB 2(非已過時的 GRUB Legacy)。

Figure 5-1: GRUB menu
GRUB 最重要的能力是檔案系統導覽,讓 kernel image 和設定的選擇變得容易。
存取 GRUB 選單的方式:
- BIOS 系統:開機時按住 SHIFT
- UEFI 系統:開機時按 ESC
在 GRUB 選單中按 e 可以查看和編輯預設開機選項的設定命令。

Figure 5-2: GRUB configuration editor
GRUB 不使用 Linux kernel,它的工作是啟動 kernel。GRUB 設定中看到的命令(如
insmod、root、ls)是 GRUB 自己的命令,與 Linux 系統命令完全獨立。GRUB 中的 root 指的是 GRUB 搜尋 kernel 和 RAM filesystem image 的檔案系統,與系統的 root filesystem 不同。
5.5.1 Exploring Devices and Partitions with the GRUB Command Line#
在 GRUB 選單或設定編輯器中按 c 可進入 GRUB 命令列。
列出裝置:
grub> ls
(hd0) (hd0,msdos1)
grub> ls -l
# 顯示詳細資訊,包括 UUIDhd0表示第一個硬碟msdos前綴表示 MBR 分割表,gpt前綴表示 GPT 分割表
檔案系統導覽:
grub> echo $root
hd0,msdos1
grub> ls ($root)/
# 列出檔案和目錄
grub> ls ($root)/boot
# 檢視 /boot 目錄內容查看 GRUB 變數:
grub> set
# 顯示所有變數,包括 $prefix 和 $root$prefix 變數指向 GRUB 設定和輔助檔案的所在位置。
5.5.2 GRUB Configuration#
GRUB 設定目錄通常在 /boot/grub 或 /boot/grub2,核心設定檔為 grub.cfg。
不要直接修改
grub.cfg,因為它是自動產生的,系統更新時會被覆蓋。應使用grub-mkconfig命令(Fedora 上為grub2-mkconfig)來產生新設定。
grub.cfg 的結構:
- 開頭是初始化步驟(函數定義、預設值、影像設定)
- 接著是
menuentry命令定義的各開機選項
自訂 GRUB 設定的方式:
- 在
/etc/grub.d/目錄中加入自訂 script - 使用 40_custom(可自行編輯但較不穩定)或 41_custom(載入
/boot/grub/custom.cfg,較簡單穩定)
產生並安裝新設定:
# 僅輸出設定到標準輸出(不會覆蓋現有設定)
grub-mkconfig
# 產生並寫入設定檔
grub-mkconfig -o /boot/grub/grub.cfg
/etc/grub.d/中檔名前的數字影響處理順序,數字較小的先處理。
5.5.3 GRUB Installation#
安裝 GRUB 比設定更複雜,但通常發行版的安裝程式會處理。
在 MBR 系統上安裝:
# 安裝到目前磁碟的 MBR
grub-install /dev/sda
# 安裝到外部儲存裝置
grub-install --boot-directory=/mnt/boot /dev/sdc在 UEFI 系統上安裝:
grub-install --efi-directory=efi_dir --bootloader-id=name其中 efi_dir 是 UEFI 目錄的掛載點(通常是 /boot/efi/EFI),name 是 boot loader 的識別名稱。
錯誤安裝 GRUB 可能會破壞開機流程。安裝前請備份 MBR 和現有的 GRUB 目錄,並確保有緊急開機方案。
5.6 UEFI Secure Boot Problems#
Secure boot 是較新的 UEFI 功能,要求所有 boot loader 必須經過受信任的機構數位簽章才能執行。Microsoft 要求搭載 Windows 8 及以後版本的硬體啟用 secure boot。
- 主流 Linux 發行版沒有問題,因為它們包含已簽章的 boot loader(通常基於 UEFI 版 GRUB)
- 常見做法是使用一個小型已簽章的 shim,UEFI 執行 shim,shim 再執行 GRUB
- 部分發行版更進一步,要求整個開機鏈(包括 kernel)都經過簽章
如果你在實驗自製 boot loader,可以在 UEFI 設定中停用 secure boot。但注意,這在雙重開機系統中可能會造成問題,因為 Windows 可能需要 secure boot 才能運行。
5.7 Chainloading Other Operating Systems#
UEFI 系統可以在 EFI partition 中安裝多個 boot loader,方便支援多重開機。但在 MBR 系統上,GRUB 使用 chainloading 技術 — 載入並執行另一個分割區上的 boot loader。
在 GRUB 設定中新增 chainload 項目的範例(Windows 安裝在磁碟第三個分割區):
menuentry "Windows" {
insmod chain
insmod ntfs
set root=(hd0,3)
chainloader +1
}+1 選項告訴 chainloader 載入分割區第一個 sector 的內容。也可以直接指定檔案路徑來載入。
5.8 Boot Loader Details#
本節深入探討 boot loader 的內部運作。PC 開機機制有兩種主要方式:MBR 和 UEFI。
5.8.1 MBR Boot#
MBR 包含一個 441 bytes 的小區域,PC BIOS 在 POST(Power-On Self-Test)後會載入並執行這段程式碼。由於空間極為有限,這導致了 multistage boot loader 的出現:
- MBR 中的初始程式碼僅負責載入 boot loader 的其餘部分
- 其餘 boot loader 程式碼通常塞在 MBR 和第一個分割區之間的空間
對於使用 GPT 的磁碟搭配 BIOS 開機,GPT 資訊佔用了 MBR 後方的空間,解決方案是建立一個 BIOS boot partition(具有特殊 UUID)來存放完整的 boot loader 程式碼。
5.8.2 UEFI Boot#
UEFI (Unified Extensible Firmware Interface) 是傳統 PC BIOS 的替代方案,功能更強大:
- 內建 shell
- 可讀取分割表和導覽檔案系統
- GPT 分割方案是 UEFI 標準的一部分
UEFI 開機方式與 MBR 截然不同:
- 系統上有一個 EFI System Partition (ESP),格式為 VFAT,包含名為
EFI的目錄 - ESP 通常掛載在
/boot/efi,目錄結構在/boot/efi/EFI - 每個 boot loader 有自己的子目錄(如
efi/microsoft、efi/ubuntu、efi/grub) - Boot loader 檔案有
.efi副檔名(如grubx64.efi、shimx64.efi)
ESP 和 BIOS boot partition 是不同的東西,具有不同的 UUID,系統不會同時使用兩者。
5.8.3 How GRUB Works#
GRUB 的運作流程:
- PC BIOS 或 firmware 初始化硬體,搜尋開機儲存裝置
- BIOS/firmware 找到 boot code 並執行,GRUB 從這裡開始
- GRUB core 載入
- Core 初始化,此時 GRUB 可以存取磁碟和檔案系統
- GRUB 識別其 boot partition 並載入設定
- GRUB 給使用者機會修改設定
- 逾時或使用者操作後,GRUB 執行
grub.cfg中的命令序列 - 執行過程中,GRUB 可能從 boot partition 載入額外模組
- GRUB 執行
boot命令,載入並執行 kernel
GRUB core 的位置有三種可能:
- 塞在 MBR 和第一個分割區之間
- 在一般分割區中
- 在特殊的 boot partition(GPT boot partition、ESP 等)
在非 UEFI/ESP 的情況下,PC BIOS 從 MBR 載入 512 bytes(源自 GRUB 目錄中的 boot.img),這段程式碼負責找到並載入 GRUB core。