4、日志查看工具:bcfg、EFI Shell 与 efibootmgr
日志拿到了,怎么读?怎么查?
这是很多初学者卡住的地方。说实话,我第一次接触 UEFI 启动日志时,面对满屏的十六进制和 GUID,也是一脸懵。后来我发现,关键不在于「看」,而在于「查」——用对工具,日志自己会说话。
这一章,我带你过一遍三个最实用的日志查看工具:bcfg、EFI Shell 和 efibootmgr。它们分别对应 UEFI 固件内部、Shell 环境和 Linux 用户态。你想想看,不管你在哪个环节出问题,总有一款工具能帮你定位。
4.1 bcfg:固件里的瑞士军刀
bcfg 是 UEFI Shell 内置的启动配置管理命令。我个人习惯把它叫做「固件里的注册表编辑器」——它能直接读写 NVRAM 中的启动项。
核心能力:bcfg 可以查看、添加、删除、修改启动项和驱动项。在安全启动调试中,我主要用它来检查签名数据库的加载顺序。
4.1.1 查看启动项列表
进入 UEFI Shell 后,直接敲:
Shell> bcfg boot dump
输出大概长这样:
Option: 00.00 — EFI Internal Shell
File: \EFI\Shell.efi
RC: Success
Option: 01.00 — Windows Boot Manager
File: \EFI\Microsoft\Boot\bootmgfw.efi
RC: Success
Option: 02.00 — Ubuntu
File: \EFI\ubuntu\shimx64.efi
RC: Success
每一行就是一个启动项。注意那个 RC 字段——它表示上次启动该条目时的返回码。如果看到 Not Found 或 Security Violation,基本就是安全启动在报错了。
我的小技巧:如果某个启动项显示 Security Violation,别急着重装系统。先用 bcfg boot dump -v 查看详细签名信息,八成是证书过期或镜像被篡改。
4.1.2 添加与删除启动项
添加一个手动启动项:
Shell> bcfg boot add 3 fs0:\EFI\test\test.efi "Test Boot"
删除一个启动项:
Shell> bcfg boot rm 2
我曾经在调试一台国产服务器时,发现 NVRAM 里塞了 30 多个废弃启动项,导致启动菜单加载极慢。用 bcfg boot rm 一个个清掉后,开机速度从 45 秒降到了 12 秒。嗯,有时候问题就这么简单。
4.2 EFI Shell:命令行下的全貌
EFI Shell 本身就是一个强大的日志查看环境。它不像 bcfg 那样只关注启动项,而是能让你看到整个固件运行时的状态。
4.2.1 查看系统表与协议
我最常用的几个命令:
devtree— 显示设备树,能看到所有 UEFI 驱动的加载情况drivers— 列出所有已加载的 UEFI 驱动及其状态dh— 显示所有句柄(Handle)及其绑定的协议
举个例子,当安全启动验证失败时,我会先跑 dh -d 查看 EFI_SECURITY_ARCH_PROTOCOL 是否被正确安装:
Shell> dh -d
...
Handle 0x3B
Image Device Path
Loaded Image Protocol
**EFI_SECURITY_ARCH_PROTOCOL** ← 这个必须有
EFI_SECURITY2_ARCH_PROTOCOL
...
如果看不到这两个安全协议,那说明固件压根没启用安全启动——你后面再怎么折腾签名都没用。
4.2.2 查看 NVRAM 变量
安全启动的签名数据库都存储在 NVRAM 变量中。用 dmpstore 可以导出所有变量:
Shell> dmpstore -all
但输出太长了。我一般只关注这几个:
| 变量名 | GUID | 作用 |
|---|---|---|
SecureBoot |
8be4df61-93ca-11d2-aa0d-00e098032b8c |
当前安全启动状态(0=关闭,1=开启) |
SetupMode |
同上 | 是否处于设置模式(1=可自定义签名) |
db |
d719b2cb-3d3a-4596-a3bc-dad00e67656f |
允许的签名/证书数据库 |
dbx |
同上 | 禁止的签名/证书数据库 |
KEK |
8be4df61-93ca-11d2-aa0d-00e098032b8c |
密钥交换密钥,用于更新 db/dbx |
避坑指南:我曾经在调试时直接用 dmpstore 把 NVRAM 全部导出到文件,然后试图用文本编辑器修改再写回去。结果固件直接变砖。记住,NVRAM 变量有校验和依赖关系,不要手动修改!
4.3 efibootmgr:Linux 下的远程遥控
很多时候你进不了 UEFI Shell——比如系统已经装好了,或者你远程登录服务器。这时候 efibootmgr 就是你的救星。
4.3.1 安装与基本用法
在大多数 Linux 发行版上:
# Debian/Ubuntu
sudo apt install efibootmgr
# RHEL/CentOS
sudo yum install efibootmgr
查看当前启动项:
$ sudo efibootmgr -v
BootCurrent: 0001
Timeout: 2 seconds
BootOrder: 0001,0002,0003
Boot0001* Windows Boot Manager HD(1,GPT,...)/File(\EFI\Microsoft\Boot\bootmgfw.efi)
Boot0002* Ubuntu HD(1,GPT,...)/File(\EFI\ubuntu\shimx64.efi)
Boot0003* UEFI Shell HD(1,GPT,...)/File(\EFI\Shell.efi)
注意那个 BootCurrent——它告诉你当前是从哪个条目启动的。如果这个值和你想的不一样,那说明启动顺序有问题。
4.3.2 安全启动相关操作
efibootmgr 还能直接操作安全启动的签名数据库。我个人觉得这是它最强大的地方:
# 查看安全启动状态
$ sudo efibootmgr -v | grep SecureBoot
SecureBoot: enabled
# 查看当前签名数据库
$ sudo efibootmgr -v --db
$ sudo efibootmgr -v --dbx
添加一个签名到 db 数据库:
$ sudo efibootmgr -D -d /dev/nvme0n1 -p 1 -L "MyCert" -l \EFI\test\mycert.cer
这个命令的意思是:把 mycert.cer 添加到 db 数据库中。注意 -D 参数表示操作的是 db,-d 和 -p 指定 EFI 系统分区所在的磁盘和分区。
为什么推荐 efibootmgr? 因为它不需要重启就能操作 NVRAM。我在调试远程服务器时,经常用 SSH 连上去,直接修改启动项或签名数据库,改完再重启验证。省去了来回跑机房的麻烦。
4.4 三款工具对比
说了这么多,你可能想问:到底该用哪个?
我的建议是:看场景。
| 工具 | 运行环境 | 最佳使用场景 | 局限性 |
|---|---|---|---|
| bcfg | UEFI Shell | 固件调试、启动项管理 | 需要进入 Shell,无法远程使用 |
| EFI Shell | UEFI Shell | 查看系统表、协议、NVRAM 变量 | 命令较多,学习曲线略陡 |
| efibootmgr | Linux 用户态 | 远程调试、批量操作、脚本化 | 依赖 Linux 内核的 efivars 支持 |
说白了,如果你人在机器前,用 bcfg 和 EFI Shell 最直接;如果你远程操作,efibootmgr 是唯一选择。我自己的习惯是:先用 efibootmgr 做初步诊断,再进 Shell 做深度排查。
4.5 本章知识体系
下面这张图帮你理清三个工具的关系和适用场景: