EFISTUB
EFI boot stub (也稱為 EFI stub)是本身就為 EFI 可執行程序的內核,也就是說,它可以直接被 UEFI 引導啟動。
此前,本文和 Debian Wiki 曾將該術語拼寫為單個單詞 (EFISTUB 或 EFIStub).
默認情況下,Arch Linux提供的內核都是 EFI boot stubs。如果自行編譯內核,需將 CONFIG_EFI_STUB 配置為 y 以啟用它,詳見The EFI Boot Stub。
在繼續之前,需要一個 EFI 系統分區(ESP),並且選擇其掛載方式。
另選方案:統一內核鏡像
統一內核鏡像 (UKI) 本身就是一個 EFI stub 內核,同時含有 initramfs 和啟動選項在單一文件中。下表列出了在它們被 UEFI 引導時,UKI 與非 UKI 的 EFI stub 的特性對比。
| UKI | 非 UKI 的 EFI stub | |
|---|---|---|
| initramfs | 包含在內 | 在單一文件中,存儲在 ESP 中 |
| 啟動選項 | 自身包包含在內含 | 存儲在 UEFI 變量中 |
當沒有問題時,UKI 更簡單,因為它只需要一個文件,並容納了所有啟動內核所必需的一切。然而,非 UKI 內核可以在不同的 initramfs 文件之間切換和嘗試不同的啟動選項。對於 UKI 來說,每次變動都會導致生成一個單獨的 UKI。
引導 EFI boot stub
esp/EFI/arch/initramfs-linux.img,則對應的 UEFI 格式行應為 initrd=\EFI\arch\initramfs-linux.img。在接下來的示例中將默認所有的文件都位於 esp/ 目錄中.直接使用 UEFI
UEFI 旨在擺脫對像 GRUB 這樣的中間引導加載程序的依賴. 如果你的主板有良好的 UEFI 實現,那麼可能直接將內核參數寫入 UEFI 引導項目以讓主板直接引導 Arch。可以使用 efibootmgr 或 UEFI Shell v2 以修改主板引導項目。
- 過時的UEFI 實現可能跟 Linux 內核有兼容性問題。如果設備的 UEFI 有新的修復了問題的版本,可以考慮使用主板廠商推薦的工具刷入。
- 此項可能已過時:一些固件 (尤其是 Lenovo 和 Dell 筆記本電腦) 不會將 NVRAM 中的引導項命令行參數傳給 EFI 可執行程序(詳見 Arch BBS 2014年的帖子)這種情況下,可以使用 UKI。
efibootmgr
使用 efibootmgr 添加加載內核的引導項
# efibootmgr --create --disk /dev/block_device_name --part X --label "Arch Linux" --loader /vmlinuz-linux --unicode 'root=block_device_identifier rw initrd=\initramfs-linux.img'
其中,block_device_name 是塊設備名,X 是分區編號, root= 後的 block_device_identifier 是實際的 Linux 根目錄分區標識符。
- 有關支持的設備名稱格式,請參見內核參數。
- 有關如何獲取對應的值,請參見塊設備持久化命名。
- 有關具體示例,請參見塊設備持久化命名#內核參數。
注意:-u/--unicode 後的字符串是內核參數,可能還需要根據實際情況添加其它參數(如用於休眠到磁碟的參數)。
基於 LTS Linux 內核、NVMe 存儲、帶有特定子卷的 BTRFS 文件系統以及 Swap 分區休眠的示例:
# efibootmgr --create \ --disk /dev/nvme0n1 --part 1 \ --label "EFISTUB Arch" \ --loader /vmlinuz-linux-lts \ --unicode 'root=UUID=01a40dd8-28f0-4636-be1e-aeed60c98095 resume=UUID=2d877d5d-4ca1-4d46-a3d6-b6ee94cbbd78 rw rootflags=subvol=@ loglevel=3 quiet initrd=\initramfs-linux-lts.img'
要獲取啟動項列表、設置引導順序或刪除啟動項,請參見 efibootmgr。
- kesboot-gitAUR 包可以簡易且自動地實現此過程,同時他還含有 pacman hook 可在執行軟體包操作時添加和移除 EFI 變量。
- https://github.com/de-arl/auto-UEFI-entry 是一個生成上述指令的 bash 輔助工具。
- 將創建引導項的命令保存到 Shell 腳本將非常方便,能讓後續修改(例如更改內核參數時)。在這個過程中,可以考慮將刪除舊啟動項自動化, 因為 efibootmgr 當前 不支持編輯現有引導項.
- 題為 The Linux kernel with built-in boot loader 的論壇帖子或許具有參考價值
bcfg
一些 UEFI的實現方式使得使用 efibootmgr 來成功修改 NVRAM 變得非常困難。如果 efibootmgr 無法成功創建相應的條目,那麼可以使用 UEFI Shell v2 中的bcfg命令來進行操作。 (即從Arch Linux的Live ISO鏡像中執行該命令)。
首先,需要找到您的 ESP分區 所使用的設備編號:
Shell> map
在示例中1被用作設備編號。要列出 ESP分區 的內容,請執行以下操作:
Shell> ls FS1:
要查看當前的啟動項,請執行以下操作:
Shell> bcfg boot dump
要為你的內核添加一條記錄,請使用以下格式:
Shell> bcfg boot add N FS1:\vmlinuz-linux "Arch Linux"
N是會在啟動菜單中添加該條目所在的位置。0 是第一個菜單項。已經存在的菜單項會被移動進去,而不會被刪除。
你可以直接添加內核選項:
Shell> bcfg boot -opt N "root=/dev/sda2 initrd=\initramfs-linux.img"
或者通過在你的 ESP 分區上創建一個文件來實現:
Shell> edit FS1:\options.txt
在文件中添加引導行。例如:
root=/dev/sda2 rw initrd=\initramfs-linux.img
按 F2 保存,然後按 F3 退出程序。
在之前的條目中添加這些選項:
Shell> bcfg boot -opt N FS1:\options.txt
對於其他所有條目,都重複進行這個步驟。
若要刪除之前添加的項目,請執行以下操作:
Shell> bcfg boot rm N
使用 UEFI Shell
如果你不想創建永久的啟動項,那麼可以從 UEFI Shell中啟動內核,因為 UEFI Shell本身就是一個普通的 UEFI 應用程式。
> FS0: > \vmlinuz-linux root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 rw initrd=\initramfs-linux.img
在這種情況下,內核參數將會被作為普通參數傳遞給 EFI 啟動腳本內核。
為了避免每次都需要記住所有的內核參數,你可以將可執行命令保存到一個 shell 腳本中,例如保存在 EFI 系統分區中的archlinux.nsh腳本,然後運行它:
> FS0: > archlinux
使用 startup.nsh 腳本
一些 UEFI 實現在冷啟動過程中不會保留 EFI 變量(例如,在 6.1版本之前的 VirtualBox ),因此通過 UEFI 設置的所有選項都會在關機時丟失。
UEFI Shell 規範 2.0規定,ESP 分區根目錄下的 startup.nsh 腳本始終會被執行並且可以包含任意指令。在這些指令中,你可以設置用於引導加載的語句。請確保將 ESP 分區掛載在 /boot並創建一個包含內核引導語句的 startup.nsh 腳本,例如:
vmlinuz-linux rw root=/dev/sdX [rootfs=myfs] [rootflags=myrootflags] \ [kernel.flag=foo] [mymodule.flag=bar] \ initrd=\initramfs-linux.img
這種方法適用於幾乎所有你在實際硬體中可能會遇到的 UEFI 版本。你可以將其作為最後的解決方案來使用。該腳本應該只包含一個長行代碼。括號中的內容是可選的,僅作為指導之用。類似 Shell 風格的換行符只是為了便於閱讀而設計的。FAT 文件系統使用反斜槓作為路徑分隔符,在這種情況下,反斜槓表示 initramfs 位於 ESP 分區的根目錄下。(對於其他設備,sd"X"代表的ESP分區設備或者編號都可能不同)
一些小提示和技巧
帶有啟動內存檔(ramdisk)的後備啟動項
如果沒有引導管理器,那麼內核命令行在啟動時是無法被修改的。為了至少提供一些後備方案,例如可以使用initramfs-linux-fallback.img 或者在不使用英特爾微碼的情況下啟動系統,只需使用 efibootmgr 創建一個額外的引導條目即可。這個引導條目的標籤可以命名例如「Arch Linux Fallback」,並設置所需的備用選項。
在ESP分區上的Archiso
可以將 Arch Linux 的 ISO 鏡像放置在 ESP 分區中,從而擁有一個恢復系統。截至 2026 年 7 月 1 日的版本發布時,鏡像的文件大小為 1.5G。
首先,下載 archlinux-YYYY.MM.DD-x86_64.iso。
接下來,在你的 ESP 目錄下創建一個用於 archiso 的目錄:
# mkdir -p esp/EFI/archiso
提取 arch 目錄中的所有內容:
# bsdtar -v -x --no-same-permissions --strip-components 1 -f archlinux-YYYY.MM.DD-x86_64.iso -C esp/EFI/archiso arch
在最後一步中,使用 efibootmgr 創建一個啟動項。請替換以下內容:
diskpath 是設備的路徑(例如:/dev/sda))
diskpart 是分區編號
# efibootmgr --create --disk diskpath \ --part diskpart \ --label "Arch (rescue system)" \ --loader '\EFI\archiso\boot\x86_64\vmlinuz-linux' \ --unicode 'archisobasedir=/EFI/archiso archisosearchfilename=/EFI/archiso/boot/x86_64/vmlinuz-linux initrd=\EFI\archiso\boot\x86_64\initramfs-linux.img'
現在你可以從 UEFI 啟動加載程序中選擇恢復系統了。
故障排除
一些主板,比如 Haswell 架構時代的華碩(ASUS)主板 (如在法國論壇上遇到的那樣), 在系統啟動時不會注意到引導條目發生的變化,除非是以另一個已存在的引導條目來啟動系統。