我正在一台新机器上安装 Arch Linux,并且已经到了需要配置引导加载程序的地步,但是失败了:
# bootctl install
Failed to create EFI Boot variable entry: No space left on device
查看变量,我可以看到问题:
# ls -la /sys/firmware/efi/efivars --sort=size --reverse
...
-rw-r--r-- 1 root root 6 May 17 17:50 BootCurrent-8be4df61-93ca-11d2-aa0d-00e098032b8c
-rw-r--r-- 1 root root 12 May 17 17:50 334-71db7b7e-4165-48fa-ac9d-f9af4cefc534
-rw-r--r-- 1 root root 36 May 17 17:50 2151678337-417acee0-6fa9-4a82-99d7-f9b1dd271e48
-rw-r--r-- 1 root root 124 May 17 17:50 Boot0000-8be4df61-93ca-11d2-aa0d-00e098032b8c
-rw-r--r-- 1 root root 2.3K May 17 17:50 2151678336-417acee0-6fa9-4a82-99d7-f9b1dd271e48
那里有一个非常大的文件占据了所有空间。有一个同名文件夹,/boot
日期为几分钟前,因此显然我的一次失败bootctl
尝试以某种方式创建了这个巨大的 UEFI 变量,占用了所有空间。删除它似乎可以释放足够的空间来正确设置启动变量,但不幸的是这是不可能的:
# rm 2151678336-417acee0-6fa9-4a82-99d7-f9b1dd271e48
rm: cannot remove '2151678336-417acee0-6fa9-4a82-99d7-f9b1dd271e48': Operation not permitted
即使我以 root 身份执行此操作,也无法删除该文件。我已经能够删除一些其他变量,但我无法删除任何我想要的变量,而且我根本无法添加任何变量,即使在删除了我可以删除的所有内容之后。
如何删除这个伪造的 UEFI 变量以释放 NVRAM 空间?
答案1
好吧,原来是为了防止误删除UEFI变量,默认只允许删除白名单的变量。其他被标记为不可变,以防止它们被意外删除:
# lsattr
-------------------- ./BootCurrent-8be4df61-93ca-11d2-aa0d-00e098032b8c
----i--------------- ./334-71db7b7e-4165-48fa-ac9d-f9af4cefc534
----i--------------- ./2151678337-417acee0-6fa9-4a82-99d7-f9b1dd271e48
-------------------- ./Boot0000-8be4df61-93ca-11d2-aa0d-00e098032b8c
----i--------------- ./2151678336-417acee0-6fa9-4a82-99d7-f9b1dd271e48
这样做是为了运行时rm -rf /
不会清除未知的 UEFI 变量,这些变量被发现会导致一些有缺陷的固件实现无法启动。 (规范规定系统必须在删除所有 UEFI 变量的情况下正常启动,但有些机器不兼容,可能会以这种方式变砖。)
必须首先删除不可变属性:
# chattr -i 2151678336-417acee0-6fa9-4a82-99d7-f9b1dd271e48
这仍然不允许我删除或覆盖变量,但它确实允许我删除另一个变量。我仍然无法添加任何新变量,但重新启动后 Linux 获得了额外的空间并bootctl install
最终成功了。
与另一台相同的机器相比,事实证明这个巨大的 UEFI 变量实际上是应该存在的!因此,在这些装有 Linux 的机器上,您最终只会获得少量的可用存储空间用于启动变量(因为如果可用空间少于 50%,Linux 显然将拒绝写入任何 UEFI 变量)。
编辑:您还可以使用参数启动内核efi_no_storage_paranoia
来禁用此限制并访问完整的 EFI 存储区域,只要您确定您的固件不是一旦空闲 EFI 就无法启动的早期固件之一可变空间下降到 50% 以下。