跳至內容

EFISTUB

出自 Arch Linux 中文维基

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),並且選擇其掛載方式

提示:
  • 如果將ESP分區掛載到/bootpacman 更新的內核就能直接使 UEFI 讀取。
  • EFI boot stub也可以使用引導加載程序間接啟動:
    • 一些 UEFI 啟動管理器可以為 UEFI 引導提供額外選項或簡化過程
    • 這對於測試內核參數或有多個內核/作業系統且主板 UEFI 啟動菜單不易使用的情況尤為有用
    • 如果啟動管理器擁有內核和 initramfs 所在分區的文件系統的驅動(例如rEFInd),則無需將他們保存在 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

注意:傳遞給內核 EFI boot stub 的 initramfs 路徑應當相對於 ESP 的根目錄,並使用反斜槓分隔路徑(遵循 EFI 標準)。例如,如果initramfs 在 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 有新的修復了問題的版本,可以考慮使用主板廠商推薦的工具刷入。
  • 此項可能已過時:一些固件 (尤其是 LenovoDell 筆記本電腦) 不會將 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

提示:

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)主板 (如在法國論壇上遇到的那樣), 在系統啟動時不會注意到引導條目發生的變化,除非是以另一個已存在的引導條目來啟動系統。


參見