# 13.6 引导管理器与 UEFI 固件

## UEFI 系统检测方法

`efibootmgr` 是 FreeBSD 系统中用于查看和管理 EFI 启动项的工具，通过与 UEFI 固件交互来操作启动项配置。

* 如果是非 UEFI 将输出如下：

```sh
# efibootmgr # 基本系统默认内置，无需额外安装
efibootmgr: efi variables not supported on this system. root? kldload efirt?
```

* 如果当前系统是 UEFI，efibootmgr 会输出类似于：

```sh
# efibootmgr
Boot to FW : false
BootCurrent: 0004
BootOrder  : 0004, 0000, 0001, 0002, 0003
+Boot0004* FreeBSD
Boot0000* EFI VMware Virtual SCSI Hard Drive (0.0)
Boot0001* EFI VMware Virtual IDE CDROM Drive (IDE 1:0)
Boot0002* EFI Network
Boot0003* EFI Internal Shell (Unsupported option)
```

## UEFI 与 efibootmgr

* 查看当前启动项：

```sh
# efibootmgr
Boot to FW : false
BootCurrent: 0001
Timeout    : 1 seconds
BootOrder  : 0002, 0003, 0000, 0001
 Boot0002* Windows Boot Manager
 Boot0003* UEFI OS
 Boot0000* refind
+Boot0001* freebsd # + 为默认启动项
```

> **技巧**
>
> 详细说明可以使用 `efibootmgr -v`。

设置 rEFInd 优先启动（这并不意味着它是默认启动项，仅是改变 BIOS/UEFI 中的启动顺序）：

> **警告**
>
> 不要使用 `efibootmgr -o 0000` 直接指定启动顺序，这样会删除其他启动项。

设置 EFI 启动顺序为 0000, 0001, 0002, 0003：

```sh
# efibootmgr -o 0000,0001,0002,0003
Boot to FW : false
BootCurrent: 0001
Timeout    : 1 seconds
BootOrder  : 0000, 0001, 0002, 0003
 Boot0000* refind
+Boot0001* freebsd
 Boot0002* Windows Boot Manager
 Boot0003* UEFI OS
```

### 参考文献

* archlinuxcn. efibootmgr 无法添加 UEFI 启动项\[EB/OL]. \[2026-03-26]. <https://bbs.archlinuxcn.org/viewtopic.php?id=12914>.
* FreeBSD Project. efibootmgr(8)\[EB/OL]. \[2026-03-26]. <https://man.freebsd.org/cgi/man.cgi?efibootmgr(8)>.
* emacs\_8861834. 深入掌握 efibootmgr 操作要领安全删除启动项方法解析\[EB/OL]. \[2026-03-26]. <https://my.oschina.net/emacs_8861834/blog/17450288>.

## UEFI 操作实例

在多硬盘系统中，有时需要将分散的 EFI 分区合并为单一分区管理，以简化启动配置。以下示例演示如何将两块硬盘上的 EFI 配置文件统一到一块硬盘的 EFI 分区中。

EFI 分区的目录结构如下：

```sh
/mnt/efi/                  # EFI 分区挂载点
└── EFI/
    ├── freebsd/            # FreeBSD 引导文件目录
    │   └── bootx64.efi     # FreeBSD EFI 引导程序
    ├── Boot/                # 默认引导目录（可能存在）
    └── Microsoft/           # Windows 引导目录（双系统场景）
```

此示例删除 nda0 上由 FreeBSD 安装生成的 EFI 分区，并将 FreeBSD 的引导文件迁移到 `ada0` 硬盘的 EFI 分区中。

首先关闭 Windows 的快速启动：命令为 `powercfg /h off`。（如果能进入 BIOS 设置界面就不用关）

随后关机并重启进入 FreeBSD 系统，创建挂载点：

```sh
# mkdir /mnt/efi
```

检测 `ada0p1`（硬盘的第一个分区）是不是我们要挂载的 EFI 分区，输入命令：

```sh
# fstyp /dev/ada0p1 # 检测 /dev/ada0p1 分区的文件系统类型
```

我的输出是 `NTFS`，可见不是我们想要的 EFI 分区；

再看看第二块分区：

```sh
# fstyp /dev/ada0p2 # 检测 /dev/ada0p2 分区的文件系统类型
```

输出 `msdosfs`，表明这是 Windows 磁盘上的 EFI 分区

接下来挂载 ada0 磁盘上的 EFI 分区到 FreeBSD 的 `/mnt/efi`：

```sh
# mount -t msdosfs /dev/ada0p2 /mnt/efi
```

为 FreeBSD 引导项在 EFI 路径下创建目录：

```sh
# mkdir /mnt/efi/EFI/freebsd
```

然后将 FreeBSD 启动文件复制到该路径：

```sh
# cp /boot/boot1.efi /mnt/efi/EFI/freebsd/bootx64.efi
```

创建名为“FreeBSD 15.0”的 EFI 启动项，指向 FreeBSD 的引导程序：

```sh
# efibootmgr -c -l /mnt/efi/EFI/freebsd/bootx64.efi -L "FreeBSD 15.0"
```

重启进入 Windows，使用 easyuefi 激活 `FreeBSD 15.0` 启动项即可。

若再次启动 FreeBSD 没有问题，方可使用 [DiskGenius](https://www.diskgenius.cn/) 或其他分区工具删除 nda0 磁盘的 EFI 分区及其文件。

## Grub

目前测试显示，GRUB 无法直接引导 FreeBSD 内核启动系统，只能通过 GRUB 的 chainload 机制（例如使用 `chainloader +1` 配置）间接引导。

```ini
menuentry "FreeBSD-13.0 Release" { # 指定 GRUB 条目名称
set root='(hd0,gpt1)'  # 请根据实际情况自行确认
chainloader /boot/boot1.efi # 指定 FreeBSD 的 EFI 引导文件
}
```

### 参考资料

* Stack Exchange. Working GRUB configuration for UEFI booting FreeBSD\[EB/OL]. \[2026-03-26]. <https://unix.stackexchange.com/questions/354260/working-grub-configuration-for-uefi-booting-freebsd>.
* Reddit. Trying to boot FBSD13 via grub2\[EB/OL]. \[2026-03-26]. <https://www.reddit.com/r/freebsd/comments/q4qgq9/trying_to_boot_fbsd13_via_grub2/>.

目前配置的报错（`grub2-efi` FBSD 15.0）：

```sh
# grub-install --target=x86_64-efi --efi-directory=/boot/efi/efi/ --bootloader-id=grub --boot-directory=/boot/ --modules="part_gpt part_msdos bsd zfs"
grub-install: error: relocation 0x4 is not implemented yet.
# grub-install --target=x86_64-efi --efi-directory=/boot/efi/efi/ --bootloader-id=grub --boot-directory=/boot/ --modules="part_gpt part_msdos bsd zfs"
Installing for x86_64-efi platform.
grub-install: error: unknown filesystem.
```

加上参数 `-vvv` 可以查看详细错误信息，输出内容较长，可在 <https://gist.github.com/ykla/9b6de6c8d4eee524840acb9981bf850a> 查看。

## 课后习题

1. 使用 efibootmgr 添加、删除和修改 EFI 启动项，追踪这些操作如何影响 UEFI 固件中的变量。
2. 尝试配置 GRUB 通过 chainload 方式引导 FreeBSD，如遇到文中提到的错误则分析错误信息。
3. 将两块硬盘的 EFI 分区合并到单一分区管理，对比合并前后的启动流程差异。
