fwupd
fwupd 是一个简单的守护程序,允许用户会话中的软件更新本机设备固件。主要面向桌面环境设计,但也支持手机和无头服务器。
安装
大多数外设的固件可以直接在操作系统中更新。但是,更新 BIOS/UEFI 固件通常需要 UEFI 模式(UpdateCapsule),从而在重启时安全地应用更新。若需要进行此类更新,请参见 #UEFI 升级设置。
图形化前端
某些桌面环境提供的图形化软件内置有 fwupd 支持:
- Discover — Plasma 的软件中心。随着 KDE Plasma 5.14 的发布,KDE Discover 中实现了新的 fwupd 后端,用于固件更新。这些固件更新与其他系统更新一起显示。属于 plasma包组。
- GNOME 固件 — 在 fwupd 支持的设备上更新、降级和重新安装固件的应用程序。可以解锁锁定的 fwupd 设备、在受支持的设备上验证固件和显示 fwupd 设备的所有固件版本。
使用
软件包提供了 fwupd.service 服务,在首次接收到 D-Bus 查询请求时自动启动 fwupd 守护进程。[1]
列出 fwupd 检测到的所有设备:
$ fwupdmgr get-devices
从 Linux 供应商固件服务(Linux Vendor firmware Service, LVFS)下载最新的元数据:
$ fwupdmgr refresh
fwupd-refresh.timer 可以自动执行该操作。列出系统上设备可用的所有更新:
$ fwupdmgr get-updates
安装更新:
$ fwupdmgr update
- 可以实时应用的更新会立即完成。
- 需要在启动时运行的更新会在下次启动时执行。
- 某些设备需要使用 root 用户更新。
- 某些设备需要手动进行更新(例如下载所需文件,将其写入 U 盘,然后手动应用更新)。对于主板(BIOS/UEFI)固件更新(其固件更新过程通常称为“Q-Flash”或类似名称)来说,情况尤其如此。
配置
禁用本地缓存服务器(passim)
fwupd 于 2023 年 9 月发布的 v1.9.5 版本引入了对 passim包 的依赖。passim 是一个本地缓存服务器,引入是为了通过让每台机器向其他机器提供其每日下载的元数据文件,来减少 LVFS 的带宽占用。[2][3]
passim 的守护进程 passimd 会监听“任意 IP 地址”的 27500 端口(即,监听 0.0.0.0:27500)。这一点因安全影响而招致了一些批评 [4][5],并且就在几周后,确实报告了数个漏洞 [6][7]。
在 Arch Linux 上,请求在编译时将依赖设为可选的 FS#79614 被驳回,因为这需要为依赖库创建分包。
因此,如果想要禁用 passim,应遵循作者给出的建议 [8]:在 /etc/fwupd/fwupd.conf 的 [fwupd] 部分下,添加 P2pPolicy=nothing,并屏蔽 passim.service。
UEFI 升级设置
升级 UEFI 需要满足以下要求:
- 使用 UEFI 模式启动系统,否则 efibootmgr 无法工作。
- 验证能够获取 EFI 变量。
- 正确挂载 EFI 系统分区(ESP)。
- 安装可选依赖 udisks2包,并确保
udisks2.service在fwupd.service前启动。该可选依赖提供了 UEFI 升级支持。
准备 ESP 目录
fwupd 会将所有必需的文件复制到 esp(该部分使用 esp 表示 ESP 挂载点)上,但是要使其正常工作,esp 上必须存在基本的文件夹布局,即需要在 esp 上创建一个 EFI 目录:
mkdir esp/EFI/
EFI 目录名必须全部大写。如果使用小写字母,fwupd 可能会认为 esp/efi/ 是 ESP 挂载点,并寻找 esp/efi/EFI/。创建后重新启动 fwupd.service 服务。然后可以执行 fwupdmgr refresh、fwupdmgr update,系统将提示重启(进入固件更新程序)。
安全启动
fwupd 目前依赖 shim 在启用了安全启动的系统上链式加载 fwupd 的 EFI 二进制文件。使用该功能前请确保正确安装 shim。
使用自己的密钥
sbctl 辅助
sbctl包 可用于签名 UEFI 可执行文件。关于安装 sbctl 的说明,请参阅安全启动#sbctl 辅助。
# sbctl sign -s -o /usr/lib/fwupd/efi/fwupdx64.efi.signed /usr/lib/fwupd/efi/fwupdx64.efi
之后,每次更新 fwupd包 时,UEFI 可执行文件都会通过 sbctl 的 pacman 钩子(/usr/share/libalpm/hooks/zz-sbctl.hook)自动签名。
最后,需要在 /etc/fwupd/fwupd.conf 中设置 DisableShimForSecureBoot 并重新启动 fwupd.service:
/etc/fwupd/fwupd.conf
... [uefi_capsule] DisableShimForSecureBoot=true
手动
或者,也可以手动签名用于升级的 UEFI 可执行文件,该文件位于 /usr/lib/fwupd/efi/fwupdx64.efi。签名后的 UEFI 可执行文件应放在 /usr/lib/fwupd/efi/fwupdx64.efi.signed。若使用 sbsigntools包,执行以下命令签名:
# sbsign --key 密钥文件 --cert 证书文件 /usr/lib/fwupd/efi/fwupdx64.efi
为了在安装或者升级时自动签名,可使用以下 pacman 钩子:
/etc/pacman.d/hooks/sign-fwupd-secureboot.hook
[Trigger] Operation = Install Operation = Upgrade Type = Path Target = usr/lib/fwupd/efi/fwupdx64.efi [Action] When = PostTransaction Exec = /usr/bin/sbsign --key 密钥文件 --cert 证书文件 /usr/lib/fwupd/efi/fwupdx64.efi Depends = sbsigntools
确保将其中的 密钥文件 和 证书文件 替换为相应路径。
除了使用 pacman 钩子,也可以创建从 /usr/lib/fwupd/efi/fwupdx64.efi 到 /usr/lib/fwupd/efi/fwupdx64.efi.signed 的符号链接,并将文件添加到 /etc/sbupdate.conf 中的 EXTRA_SIGN 列表中。
最后,需要在 /etc/fwupd/fwupd.conf 中设置 DisableShimForSecureBoot 并重新启动 fwupd.service:
/etc/fwupd/fwupd.conf
... [uefi_capsule] DisableShimForSecureBoot=true
- 在 fwupd 1.9 之前,该选项位于
/etc/fwupd/uefi_capsule.conf。 - 在 fwupd 1.4 之前,配置选项的名称不同。
查阅此 GitHub issue 获取更多信息。
故障排除
一直卡在重启
fwupdmgr update 不会报错,但提示重启后卡住,且按住电源按钮也没有反应。
尝试切断电源,或按下复位按钮(在笔记本电脑上,可能是背面的一个小孔)强制重启。
没有错误,但重启后没有升级
状况:fwupdmgr update 未报告任何错误并提示重新启动(例如,在 BIOS 更新中),但系统正常(或卡住后)重启后固件未更新。
可能的原因:必须在 BIOS 设置中允许更改引导顺序。
如果同时进行多个更新,另一种可能解决的办法: 尝试一次更新一个更新包。使用以下命令更新一个更新包:
$ fwupdmgr update 更新_ID
(其中 更新_ID 类似于 f95c9218acd12697af946874bfe4239587209232。)
file system is read-only
如果将 EFI 系统分区 bind 挂载到 /boot,至少 fwupdmgr 1.5.2 会推断出错误的挂载点。因此,它无法将 UEFI 更新文件写入 /boot/EFI/arch/fw(fwupdmgr 本应写入其指向的 esp/EFI/arch/fw 目录)。这会导致一个(误导性的)file system is read-only 错误消息。如果是通过 Discover(或任何其他支持 fwupd 的图形化更新工具)执行更新,则可能不显示任何错误,或显示误导性的错误。
临时解决方法如下:如果之前已将 esp/EFI/arch bind 挂载到 /boot,请先执行 umount /boot,在使用 fwupdmgr update 将 UEFI 更新文件写入 esp/EFI/arch/fw 之后再 mount /boot,最后重启系统以执行 UEFI 更新。
UEFI ESP 分区未检测到或未配置
如果达到 #UEFI 升级设置中的要求后,还是无法检测到 ESP 分区,可以手动指定挂载点:
/etc/fwupd/fwupd.conf
[fwupd] EspLocation=/efi
有关导致该错误的其它可能原因,请参阅 fwupd wiki 的相关文章。
手动指定 ESP 位置可以避免 fwupdx64.efi 安装到其它盘上的 ESP。
MSR 插件加载失败
MSR 插件允许查询 DCI 的状态,DCI 是一种适用于 Intel CPU 的调试接口。根据 fwupd 的文档,应在生产用机器上禁用该接口。
该插件需要加载 msr 内核模块。msr 在所有 Arch Linux 官方内核包中都是内置内核模块,但非官方内核包可能将其作为可加载内核模块。对于后一种情况,需要显式地在启动时加载模块。