统一可扩展固件接口 (UEFI)
统一可扩展固件接口 (UEFI) 是操作系统和固件之间的接口。它为引导操作系统和运行预启动应用程序提供了一个标准环境。
它与遗留 BIOS 系统使用的 MBR 引导代码 方法不同。有关它们之间的差异以及使用 UEFI 的启动过程,请参阅 Arch 启动过程。要设置 UEFI 引导加载程序,请参阅 Arch 启动过程#引导加载程序。
- 早期厂商的 UEFI 实现可能比其 BIOS 对等项携带更多错误。如果您遇到无法解决的问题,请考虑为此类系统使用遗留 BIOS 引导。
- Apple 的 UEFI 实现不符合标准。除非明确说明,否则这些说明是通用的,其中一些可能不适用于 Mac,或者在 Mac 上有所不同。
UEFI 固件的位深度
在 UEFI 下,每个程序,无论是操作系统引导加载程序还是实用程序(例如内存测试或恢复工具),都应是与 UEFI 固件位深度/架构相对应的 EFI 应用程序。
绝大多数 x86_64 系统,包括最新的 Apple Mac,都使用 x64(64 位)UEFI 固件。唯一已知的 IA32(32 位)UEFI 设备是较旧的(2008 年之前)Apple Mac、Intel Atom 片上系统(截至 2013 年 11 月 2 日)[1] 以及一些较旧的 Intel 服务器主板,它们已知运行在 Intel EFI 1.10 固件上。
x64 UEFI 固件不包含启动 32 位 EFI 应用程序的支持(与包含此类支持的 x86_64 Linux 和 Windows 版本不同)。因此,EFI 应用程序必须针对该特定固件处理器位深度/架构进行编译。
检查固件位深度
固件位深度可以从已启动的操作系统中检查。
从 Linux
在运行 Linux 内核 4.0 或更高版本的发行版上,可以通过 sysfs 接口找到 UEFI 固件位深度。运行
$ cat /sys/firmware/efi/fw_platform_size
对于 64 位 (x64) UEFI,它将返回 64,对于 32 位 (IA32) UEFI,它将返回 32。如果文件不存在,则表示您尚未以 UEFI 模式启动。
从 macOS
2008 年之前的 Mac 大多具有 IA32 EFI 固件,而 2008 年之后的 Mac 大多具有 x64 EFI。所有能够运行 Mac OS X Snow Leopard 64 位内核的 Mac 都具有 x64 EFI 1.x 固件。
要找出 Mac 中 EFI 固件的架构,请在 Mac OS X 终端中键入以下命令
$ ioreg -l -p IODeviceTree | grep firmware-abi
如果命令返回 EFI32,则表示它是 IA32(32 位)EFI 固件。如果返回 EFI64,则表示它是 x64 EFI 固件。大多数 Mac 不具备 UEFI 2.x 固件,因为 Apple 的 EFI 实现不完全符合 UEFI 2.x 规范。
从 Microsoft Windows
64 位版本的 Windows 不支持在 32 位 UEFI 上启动。因此,如果您有一个在 UEFI 模式下启动的 32 位 Windows 版本,则表示您拥有一个 32 位 UEFI。
要检查位深度,请运行 msinfo32.exe。在“系统摘要”部分查看“系统类型”和“BIOS 模式”的值。
对于 64 位 UEFI 上的 64 位 Windows,将是 系统类型: x64 PC 和 BIOS 模式: UEFI。对于 32 位 UEFI 上的 32 位 Windows,将是 系统类型: x86 PC 和 BIOS 模式: UEFI。如果“BIOS 模式”不是 UEFI,则表示 Windows 未以 UEFI 模式启动。
UEFI 变量
UEFI 通过变量定义,操作系统可以通过这些变量与固件进行交互。UEFI 启动变量由引导加载程序使用,而操作系统仅在系统早期启动时使用。UEFI 运行时变量允许操作系统管理固件的某些设置,例如 UEFI 启动管理器或管理 UEFI 安全启动协议的密钥等。您可以使用以下命令获取列表
$ efivar --list
Linux 内核中的 UEFI 变量支持
Linux 内核通过 **efivarfs**(**EFI** **VAR**iable **F**ile**S**ystem)接口(CONFIG_EFIVAR_FS)将 UEFI 变量数据暴露给用户空间。它使用 efivarfs 内核模块挂载在 /sys/firmware/efi/efivars 目录下,没有每个变量的最大大小限制,并且支持 UEFI 安全启动变量。在内核 3.8 中引入。
UEFI 变量支持的要求
- 内核应通过 EFI 引导存根(可选地使用 引导管理器)或 UEFI 引导加载程序以 UEFI 模式启动,而不是通过 BIOS 或 CSM,或 Apple 的 Boot Camp(它也是一个 CSM)。
- 内核中的 EFI 运行时服务支持应存在(
CONFIG_EFI=y,使用zgrep CONFIG_EFI /proc/config.gz检查是否存在)。 - 内核中的 EFI 运行时服务**不应**通过 内核命令行禁用,即**不应**使用
noefi内核参数。 efivarfs文件系统应挂载在/sys/firmware/efi/efivars,否则请按照下面的 #挂载 efivarfs 部分操作。efivar应在没有错误的情况下列出(选项-l/--list)UEFI 变量。
如果在满足上述条件后 UEFI 变量支持仍不起作用,请尝试以下解决方法
- 如果列出 UEFI 变量(
efivar -l)导致efivar: error listing variables: Function not implemented错误,并且系统已启动到 实时内核,请将efi=runtime添加到 内核参数并重启(efivarfs 功能在这些内核上默认禁用)。 - 有关更多故障排除步骤,请参阅 #用户空间工具无法修改 UEFI 变量数据。
挂载 efivarfs
如果 efivarfs 在启动时未被 systemd 自动挂载到 /sys/firmware/efi/efivars,您需要手动挂载它,以便将 UEFI 变量暴露给 *efibootmgr* 等 用户空间工具。
# mount -t efivarfs efivarfs /sys/firmware/efi/efivars
有关内核文档,请参阅 efivarfs.html。
用户空间工具
有几种工具可以访问/修改 UEFI 变量,即
- efivar — 用于操作 UEFI 变量的库和工具(由 efibootmgr 使用)
- efibootmgr — 用于操作 UEFI 固件引导管理器设置的工具
- uefivars — 转储 UEFI 变量列表,并附带一些额外的 PCI 相关信息(内部使用 efibootmgr 代码)
- efitools — 用于操作 UEFI 安全启动平台的工具
- Ubuntu 的固件测试套件 — 对 Intel/AMD PC 固件执行健全性检查的测试套件
efibootmgr
您需要安装 efibootmgr 包。
- 如果您的系统上 *efibootmgr*不起作用,您可以重启到 #UEFI Shell 并使用
bcfg为引导加载程序创建启动项。 - 如果您无法使用
efibootmgr,一些 UEFI 固件允许用户直接从其启动时界面管理 UEFI 启动项。例如,一些固件有一个“Add New Boot Option”选项,让您选择本地 EFI 系统分区并手动输入 EFI 应用程序路径,例如\EFI\refind\refind_x64.efi。 - 以下命令以 rEFInd 引导管理器为例。
要使用 *efibootmgr* 添加新的启动项,您需要知道三件事
- 包含 EFI 系统分区 (ESP) 的磁盘。例如:
/dev/sda,/dev/nvme0n1。 - 该磁盘上 ESP 的分区号。
/dev/sdaY或/dev/nvme0n1pY中的Y。 - EFI 应用程序的路径(相对于 ESP 的根目录)
例如,如果您想为 /efi/EFI/refind/refind_x64.efi 添加一个启动项,其中 /efi 是 ESP 的挂载点,请运行
$ findmnt /efi
TARGET SOURCE FSTYPE OPTIONS /efi /dev/sda1 vfat rw,flush,tz=UTC
在此示例中,findmnt(8) 指示 ESP 位于磁盘 /dev/sda 上,分区号为 1。EFI 应用程序相对于 ESP 根目录的路径是 /EFI/refind/refind_x64.efi。因此,您将如下创建启动项
# efibootmgr --create --disk /dev/sda --part 1 --loader '\EFI\refind\refind_x64.efi' --label 'rEFInd Boot Manager' --unicode
获取所有启动项和启动顺序的概览
# efibootmgr --unicode
设置启动顺序
# efibootmgr --bootorder XXXX,XXXX --unicode
其中 XXXX 是上一个 *efibootmgr* 命令输出中出现的数字。
删除不需要的条目
# efibootmgr --delete-bootnum --bootnum XXXX --unicode
有关更多信息,请参阅 efibootmgr(8) 或 efibootmgr README。
\ 作为路径分隔符,但 *efibootmgr* 可以自动转换 UNIX 风格的 / 路径分隔符。禁用 UEFI 变量访问
对 UEFI 的访问可能会在运行操作系统级别之外造成危害。存在危险的 UEFI 漏洞,例如 LogoFAIL,它允许恶意行为者完全控制机器。在某些 UEFI 实现不佳的情况下,甚至可能发生硬件级变砖[2]。
因此,由于日常系统使用不需要 UEFI 变量访问,您可能希望禁用它,以避免潜在的安全漏洞或意外损坏。
可能的解决方案是
- 使用 fstab 以只读模式挂载
efivars。例如efivarfs /sys/firmware/efi/efivars efivarfs ro,nosuid,nodev,noexec 0 0
- 使用
noefi内核参数完全禁用操作系统对 UEFI 的访问。
systemctl reboot --firmware-setup)也将无法工作。UEFI Shell
UEFI Shell 是固件的 shell/终端,允许启动 EFI 应用程序,包括 UEFI 引导加载程序。除此之外,该 shell 还可用于获取系统或固件的各种其他信息,例如内存映射(memmap)、修改引导管理器变量(bcfg)、运行分区程序(diskpart)、加载 UEFI 驱动程序、编辑文本文件(edit)、hexedit 等。
获取 UEFI Shell
您可以从 TianoCore EDK2 项目获取 BSD 许可的 UEFI Shell。
- Shell v2
- 在 Arch 安装介质上:
/shellx64.efi。ISO 构建时/usr/share/edk2-shell/x64/Shell_Full.efi的副本。 - edk2-shell 提供 x64 UEFI 的 x64 Shell 和 IA32 UEFI 的 IA32 Shell - 直接从最新的 TianoCore EDK2 版本编译。
- uefi-shell-gitAUR 提供 x64 UEFI 的 x64 Shell 和 IA32 UEFI 的 IA32 Shell - 直接从最新的 TianoCore EDK2 源代码编译。
- 在 Arch 安装介质上:
- Shell v1
- TianoCore 的预编译 UEFI Shell v1 二进制文件(截至 2014 年 1 月 10 日,上游不再更新)。
- 修补过的 shell
- 预编译的 UEFI Shell v2 二进制文件,其 bcfg 已修改为适用于 UEFI pre-2.3 固件[死链 2023-07-30—HTTP 403] - 来自 Clover EFI 引导加载程序。
- 与广泛固件兼容的预编译 UEFI Shell v2 二进制文件 - 来自 OpenCore 引导加载程序。在发布存档中:
EFI/OC/Tools/OpenShell.efi。
Shell v2 在 UEFI 2.3+ 系统上效果最好,并推荐在这些系统上使用,而非 Shell v1。Shell v1 应在所有 UEFI 系统上工作,无论固件遵循哪种规范版本。更多信息请参阅 ShellPkg 和 EDK2 邮件列表线程—在 Linux 发行版 ISO 中包含 UEFI shell。
启动 UEFI Shell
一些 Asus 和其他基于 AMI Aptio x64 UEFI 固件的主板(从 Sandy Bridge 起)提供了一个名为 *Launch EFI Shell from filesystem device* 的选项。对于这些主板,请将 x64 UEFI Shell 复制到您的 EFI 系统分区的根目录,并命名为 shellx64.efi。
- Arch Linux 安装介质在卷的根目录下有
shellx64.efi。 - 如果
shellx64.efi位于 EFI 系统分区的根目录,rEFInd 和 systemd-boot 将自动添加 UEFI Shell 的启动菜单项。
具有 Phoenix SecureCore Tiano UEFI 固件的系统已知嵌入了 UEFI Shell,可以使用 F6、F11 或 F12 键启动。
/USB_drive_mointpoint/EFI/BOOT/BOOTx64.EFI。此 USB 驱动器应出现在固件启动菜单中。启动此选项将为您启动 UEFI Shell。重要的 UEFI Shell 命令
UEFI Shell 命令通常支持 -b 选项,该选项会在每页输出后暂停。运行 help -b 可列出可用的内部命令。可用命令要么内置于 shell 中,要么是独立的 EFI 应用程序。
有关更多信息,请参阅 Intel Scripting Guide 2008[死链 2023-07-30—HTTP 404] 和 Intel "Course" 2011[死链 2023-07-30—HTTP 404]。
bcfg
bcfg 修改 UEFI NVRAM 条目,允许用户更改启动项或驱动程序选项。此命令在 UEFI Shell Specification 2.2 文档的第 96 页(第 5.3 节)中有详细描述。
- 仅当 *efibootmgr* 在您的系统上创建有效的启动项失败时,才尝试使用 *bcfg*。
- UEFI Shell v1 的官方二进制文件不支持
bcfg命令。有关可能适用于 UEFI pre-2.3 固件的修改版 UEFI Shell v2 二进制文件,请参阅 #获取 UEFI Shell。
转储当前启动项列表
Shell> bcfg boot dump -v
为 rEFInd(例如)添加一个启动菜单项,作为启动菜单中的第 4 个(编号从零开始)选项
Shell> bcfg boot add 3 FS0:\EFI\refind\refind_x64.efi "rEFInd Boot Manager"
其中 FS0: 是与 EFI 系统分区对应的映射,FS0:\EFI\refind\refind_x64.efi 是要启动的文件。
要添加一个直接启动到您的系统的条目而不使用引导加载程序,请参阅 EFI 引导存根#bcfg。
删除第 4 个启动项
Shell> bcfg boot rm 3
将启动项 #3 移动到 #0(即 UEFI 启动菜单中的第一个或默认条目)
Shell> bcfg boot mv 3 0
有关 bcfg 的帮助文本
Shell> help bcfg -v -b
或者
Shell> bcfg -? -v -b
map
map 显示设备映射列表,即可用文件系统(FS0)和存储设备(blk0)的名称。
在运行文件系统命令(如 cd 或 ls)之前,您需要通过键入其名称将 shell 更改到相应的文件系统
Shell> FS0: FS0:\> cd EFI/
edit
edit 提供了一个基本的文本编辑器,其界面类似于 nano,但功能略少。它处理 UTF-8 编码,并处理 LF 与 CRLF 行尾符。
例如,要编辑 EFI 系统分区(固件中的 FS0:)上的 rEFInd 的 refind.conf,
Shell> edit FS0:\EFI\refind\refind.conf
按 Ctrl+e 获取帮助。
UEFI 驱动
UEFI 驱动是支持某种功能的软件片段。例如,通常无法从 UEFI shell 访问 NTFS 格式的分区。efifs 包包含支持从 EFI shell 读取更多文件系统的驱动程序。使用示例是复制此类驱动程序到一个可以从 UEFI shell 访问的分区。然后,在 UEFI shell 中,发出类似以下命令
Shell> load ntfs_x64.efi Shell> map -r
执行 map 命令后,用户应该能够从 UEFI shell 访问 NTFS 格式的分区。
- systemd-boot 会自动从
esp/EFI/systemd/drivers/加载 UEFI 驱动。 - rEFInd 会自动从 ESP 上其自身安装目录的
drivers和drivers_x64子目录加载 UEFI 驱动。例如esp/EFI/refind/drivers_x64/。它可以配置为扫描其他目录。
UEFI 可启动介质
从光盘介质移除 UEFI 启动支持
- 本节提到的是从 **仅 CD/DVD**(通过 EL Torito 进行光盘介质启动)移除 UEFI 启动支持,而不是从 USB 闪存驱动器移除。
- 为了隐藏 USB 驱动器上的 UEFI 设备,请在将 ISO 复制到闪存驱动器后使用分区编辑器。删除类型为
EF的分区。**不要**接受转换为 GPT 的提议。
大多数 32 位 EFI Mac 和一些 64 位 EFI Mac 拒绝从 UEFI(X64)+BIOS 可启动 CD/DVD 启动。如果您希望继续使用光盘介质进行安装,可能需要先移除 UEFI 支持。
提取 ISO 时跳过 UEFI 特定目录
$ mkdir extracted_iso $ bsdtar -x --exclude=EFI/ --exclude=loader/ -f archlinux-version-x86_64.iso -C extracted_iso
然后使用 xorriso(1)(来自 libisoburn)重建 ISO,排除 UEFI 光盘介质启动支持。确保设置正确的卷标,例如 ARCH_202103;可以使用原始 ISO 上的 file(1) 获取。
$ xorriso -as mkisofs \
-iso-level 3 \
-full-iso9660-filenames \
-joliet \
-joliet-long \
-rational-rock \
-volid "ARCH_YYYYMM" \
-appid "Arch Linux Live/Rescue CD" \
-publisher "Arch Linux <https://archlinux.org.cn>" \
-preparer "prepared by $USER" \
-eltorito-boot syslinux/isolinux.bin \
-eltorito-catalog syslinux/boot.cat \
-no-emul-boot -boot-load-size 4 -boot-info-table \
-isohybrid-mbr "extracted_iso/syslinux/isohdpfx.bin" \
-output archlinux-version-x86_64-noUEFI.iso extracted_iso/
将 archlinux-version-x86_64-noUEFI.iso 刻录到光盘介质,然后正常进行安装。
在没有原生支持的系统上测试 UEFI
虚拟机使用 OVMF
OVMF 是 TianoCore 项目,用于为虚拟机启用 UEFI 支持。OVMF 包含一个示例 UEFI 固件和一个独立的非易失性变量存储,用于 QEMU。
您可以从 extra 存储库安装 edk2-ovmf。
建议为您的虚拟机本地复制非易失性变量存储。
$ cp /usr/share/edk2/x64/OVMF_VARS.4m.fd my_OVMF_VARS.4m.fd
要使用 OVMF 固件和此变量存储,请将以下内容添加到您的 QEMU 命令
-drive if=pflash,format=raw,readonly,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd \ -drive if=pflash,format=raw,file=my_OVMF_VARS.4m.fd
例如:
$ qemu-system-x86_64 -enable-kvm -m 1G -drive if=pflash,format=raw,readonly,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd -drive if=pflash,format=raw,file=my_OVMF_VARS.4m.fd …
仅 BIOS 系统使用 DUET
DUET 是 TianoCore 项目,它允许从 BIOS 系统链式加载完整的 UEFI 环境,方式类似于 BIOS 操作系统启动。此方法已被广泛讨论。可从其中一个 仓库[死链 2023-04-07—404 Page Not Found] 下载预编译的 DUET 映像。阅读特定说明[死链 2023-04-07—404 Page Not Found] 以设置 DUET。然而,截至 2018 年 11 月,DUET 代码已从 TianoCore git 仓库中移除。
您也可以尝试 Clover,它提供修改过的 DUET 映像,可能包含一些特定于系统的修复,并且更新比 gitlab 仓库更频繁。
故障排除
当被 Windows 困住时,引导回 Arch Linux
当被 Windows 困住时,要引导回 Arch Linux,请使用 Windows PowerShell 命令 shutdown /r /o 或通过 *Settings > Update & Security > Recovery > Advanced startup* 并选择 *Restart now* 来进入 Windows 的*高级启动*。进入*高级启动*菜单后,选择*使用设备*(它实际上包含您的 UEFI 启动选项,不限于 USB 或 CD,也可以启动硬盘上的操作系统),然后选择“Arch Linux”。
在没有功能键的情况下进入固件设置
在某些笔记本电脑上,例如 Lenovo XiaoXin 15are 2020,使用 F2 或 F12 等键无效。这可能可以通过将笔记本电脑退回 OEM 维修主板信息来解决,但有时无法做到或不希望这样做。然而,还有其他方法可以进入固件设置。
- 使用 systemctl
$ systemctl reboot --firmware-setup
这将重启您的计算机进入固件设置。 - 使用 GRUB:按
c进入命令行,在 GRUB 命令行中使用fwsetup进入固件设置。 - 在 Windows 中:进入*高级启动*,请参阅 #当被 Windows 困住时,引导回 Arch Linux。
用户空间工具无法修改 UEFI 变量数据
如果任何用户空间工具无法修改 UEFI 变量数据,请检查是否存在 /sys/firmware/efi/efivars/dump-* 文件。如果它们存在,请删除它们,然后重启并重试。如果上述步骤未能解决问题,请尝试使用 efi_no_storage_paranoia 内核参数启动,以禁用内核 UEFI 变量存储空间检查,这可能会阻止写入/修改 UEFI 变量。
efi_no_storage_paranoia 仅应在需要时使用,不应作为常规启动选项保留。此内核命令行参数的效果是关闭了为避免 NVRAM 空间不足导致机器变砖而设置的安全防护。有关更多信息,请参阅 FS#34641。无法使用 efibootmgr 创建新的启动项
某些内核和 efibootmgr 版本组合可能拒绝创建新的启动项。这可能是由于 NVRAM 中可用空间不足。您可以尝试 #Userspace tools are unable to modify UEFI variable data 中的解决方案。
您还可以尝试将 efibootmgr 降级到版本 0.11.0。此版本与 Linux 版本 4.0.6 兼容。有关更多信息,请参阅错误讨论 FS#34641,特别是 关闭评论。
Windows 更改启动顺序
如果您 与 Windows 双启动,并且您的主板直接启动 Windows 而不是您选择的 EFI 应用程序,则可能存在多种原因和解决方法。
- 确保在 Windows 电源选项中禁用 快速启动
- 确保在固件中禁用 安全启动(如果您不使用签名启动加载程序)
- 确保您的 UEFI 启动顺序未将 Windows Boot Manager 设置为第一项,例如使用 efibootmgr 以及您在 UEFI 的配置工具中看到的内容。某些主板会默认覆盖 Windows 检测到 efibootmgr 设置的任何设置。这已在 Packard Bell 笔记本电脑上得到确认。
- 如果您的主板正在启动默认启动路径 (
\EFI\BOOT\BOOTx64.EFI),则此文件可能已被 Windows 启动加载程序覆盖。尝试设置正确的启动路径,例如使用 efibootmgr。 - 如果以上步骤不起作用,您可以指示 Windows 启动加载程序运行不同的 EFI 应用程序。从 Windows 管理员命令提示符运行
bcdedit /set "{bootmgr}" path "\EFI\path\to\app.efi" - 或者,通过以 root 用户身份运行
efibootmgr -A -b bootnumber来停用 Windows Boot Manager。将bootnumber替换为实际的 Windows Boot Manager 启动编号;您可以通过运行不带任何选项的efibootmgr来查看它。 - 或者,您可以设置一个 Windows 启动脚本,以确保每次启动 Windows 时启动顺序都正确设置。
- 以管理员权限打开命令提示符。运行
bcdedit /enum firmware并找到您想要的启动项。 - 复制标识符,包括括号,例如
{31d0d5f4-22ad-11e5-b30b-806e6f6e6963} - 创建一个批处理文件,命令为
bcdedit /set "{fwbootmgr}" DEFAULT "{copied-boot-identifier}" - 打开 gpedit.msc,然后在 本地计算机策略 > 计算机配置 > Windows 设置 > 脚本(启动/关机) 下,选择 启动
- 在 脚本 选项卡下,选择 添加 按钮,然后选择您的批处理文件
- 以管理员权限打开命令提示符。运行
- 或者,可以使用任务计划程序在 Windows 中运行启动脚本
- 按照上述步骤 1-3 创建批处理文件。
- 运行 taskschd.msc,然后在 操作 菜单中选择 创建任务...。
- 在 常规 选项卡下
- 输入任何合适的 名称 和 描述。
- 确保选择的用户帐户是“管理员”,而不是“标准用户”。
- 选择“无论用户是否登录,都运行”。
- 选择“以最高权限运行”。
- 在 触发器 选项卡下,从菜单中选择“启动时”,然后单击 确定。
- 在 操作 选项卡下,单击 新建...,然后单击 浏览...,并找到步骤 1 中的批处理文件。
- 在 条件 选项卡下,取消勾选 电源 选项,以便脚本在电池供电时运行(适用于笔记本电脑)。
- 单击 确定,并在提示时输入步骤 4 中选择的用户帐户的密码。
USB 媒体卡在黑屏上
此问题可能由 KMS 问题引起。尝试在启动 USB 时 禁用 KMS。
UEFI 引导加载程序未显示在固件菜单中
某些固件不支持自定义引导项。它们只会从硬编码的引导项中启动。
一种典型的解决方法是不依赖 NVRAM 中的引导项,而是将引导加载程序安装到 EFI 系统分区上的常用回退路径之一。
以下部分描述了回退路径。
可移动驱动器的默认启动路径
UEFI 规范定义了用于从可移动媒体启动的 EFI 二进制文件的默认文件路径。相关的路径是:
esp/EFI/BOOT/BOOTx64.EFI(适用于 x64 UEFI)esp/EFI/BOOT/BOOTIA32.EFI(适用于 IA32 UEFI)。
虽然规范仅为可移动驱动器定义了这些路径,但大多数固件支持从任何驱动器启动它们。
有关如何安装或迁移引导加载程序到默认/回退引导路径的信息,请参阅相应的 引导加载程序 文章。
Microsoft Windows 引导加载程序位置
在某些 UEFI 主板上,例如某些带有 Intel Z77 芯片组的主板,使用 efibootmgr 或 UEFI Shell 中的 bcfg 添加条目将不起作用,因为它们在添加到 NVRAM 后不会出现在启动菜单列表中。
此问题的原因是主板只能加载 Microsoft Windows。要解决此问题,您必须将 .efi 文件放置在 Windows 使用的位置。
将 Arch Linux 安装介质 (FSO:) 中的 BOOTx64.EFI 文件复制到您 ESP 分区上的 Microsoft 目录(FS1:)。这可以通过启动到 EFI shell 并键入以下命令来完成:
Shell> mkdir FS1:\EFI\Microsoft Shell> mkdir FS1:\EFI\Microsoft\Boot Shell> cp FS0:\EFI\BOOT\BOOTx64.EFI FS1:\EFI\Microsoft\Boot\bootmgfw.efi
重启后,添加到 NVRAM 的任何条目都应该会出现在启动菜单中。
UEFI/BIOS 卡在加载屏幕
这是 Acer 笔记本电脑上反复出现的问题,如果 .efi 文件未手动授权,就会发生此问题。请参阅 Laptop/Acer#Firmware Setup became inaccessible after Linux installation。
使用 efibootmgr 创建的启动项未能显示在 UEFI 中
efibootmgr 可能无法检测到 EDD 3.0,从而导致在 NVRAM 中创建无法使用的启动项。有关详细信息,请参阅 efibootmgr issue 86。
为了解决此问题,在手动创建启动项时,将 -e 3 选项添加到 efibootmgr 命令。例如:
# efibootmgr --create --disk /dev/sda --part 1 --loader '\EFI\refind\refind_x64.efi' --label 'rEFInd Boot Manager' --unicode -e 3
要修复引导加载程序安装程序,例如 grub-install 和 refind-install,请创建一个包装脚本 /usr/local/bin/efibootmgr 并使其 可执行
/usr/local/bin/efibootmgr
#!/bin/sh exec /usr/bin/efibootmgr -e 3 "$@"
删除引用驱动器后,UEFI 引导项消失
某些固件会在启动时删除引用不存在驱动器的启动项。当频繁分离/连接驱动器或从可移动驱动器启动时,这可能会成为一个问题。
启动项被随机删除
某些主板可能会因为 NVRAM 中的可用空间不足而删除启动项,而不是在创建时给出错误。为防止这种情况发生,请通过最小化条目创建过程来减少要添加的启动项数量,并通过从 UEFI 设置中禁用 兼容性支持模块 (CSM) 来减少自动驱动器启动项的数量。请参阅 BBS#1608838。
启动项可能被删除的另一个原因是,UEFI 规范允许 OEM 在启动过程中执行“NVRAM 维护”。制造商的做法很简单:他们查找设备上预定义、硬编码路径中的 EFI 应用程序。如果找不到任何,他们就会认为设备上没有操作系统,并擦除 NVRAM 中与之关联的所有启动项,因为他们认为 NVRAM 包含损坏或过时的数据。如果您不打算安装 Windows,但仍想直接从固件加载 Linux 内核,一个可能的解决方法是创建一个空文件 esp/EFI/BOOT/BOOTx64.EFI
# mkdir -p esp/EFI/BOOT # touch esp/EFI/BOOT/BOOTx64.EFI
然后恢复删除的启动项。现在,在重新启动后,主板将看到“Fake OS”,并且不应擦除 NVRAM 中的其他启动项。当然,只要您保留标准的 fallback 名称,就可以将其更改为实际的 EFI 应用程序,前提是您将其伪装成一个假的操作系统加载程序。
Lenovo ThinkPad:由于“OS 优化默认值”导致启动项不持久
在最近的 Lenovo ThinkPad 笔记本电脑(例如 T16 Gen 2 AMD 型号)上,用户报告称自定义 UEFI 启动项(使用 efibootmgr 或 bootctl 创建)在每次启动时都会被自动删除,只有 Windows Boot Manager 和 Lenovo 自有条目(PXE、Recovery、Diagnostics)会被恢复。
这是由于 BIOS 选项“Restart / OS Optimized Defaults”(重启/操作系统优化默认值)引起的,该选项会在每次重新启动时将 UEFI 启动变量重置为针对 Windows 优化的默认值。
解决方案:在 BIOS/UEFI 设置中禁用“OS Optimized Defaults”(操作系统优化默认值)。禁用后,手动创建的启动项将正确持久化,从而允许 systemd-boot 或其他自定义引导管理器按预期工作。
参见
- UEFI Forum - 包含官方 UEFI 规范 - GUID 分区表是 UEFI 规范的一部分
- UEFI 启动:它是如何工作的?- AdamW 的博客文章
- Linux 内核 UEFI 文档(针对 x86_64 平台)
- Intel 的 EFI 页面
- Intel Architecture Firmware Resource Center[链接已失效 2023-07-30—HTTP 404]
- Matt Fleming - Linux EFI 启动存根
- Matt Fleming - 从 Linux 访问 UEFI 变量
- Rod Smith - Linux on UEFI:快速安装指南
- 某些新型机器上的 UEFI 启动问题(LKML)
- LPC 2012 将 UEFI 整合到 Linux[链接已失效 2021-05-17—域名未解析]
- LPC 2012 UEFI 教程:第一部分[链接已失效 2021-05-17—域名未解析]
- LPC 2012 UEFI 教程:第二部分[链接已失效 2021-05-17—域名未解析]
- Intel 的 TianoCore 项目 - 开源 UEFI 固件,包括用于直接基于 BIOS 启动的 DuetPkg 和用于 QEMU 和 Oracle VirtualBox 的 OvmfPkg
- FGA:EFI 启动过程
- Microsoft 的 Windows 和 GPT FAQ
- 在不重装的情况下将 Windows x64 从 BIOS-MBR 模式转换为 UEFI-GPT 模式
- 创建 Linux BIOS+UEFI 和 Windows x64 BIOS+UEFI 可启动 USB 驱动器
- Rod Smith - BIOS 到 UEFI 的转变
- EFI Shells 和脚本 - Intel 文档
- UEFI Shell - Intel 文档
- UEFI Shell - bcfg 命令信息
- EFI 系统上的引导过程