![如何从命令行写入/编辑/更新 OsInductions efi 变量?](https://linux22.com/image/54698/%E5%A6%82%E4%BD%95%E4%BB%8E%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%86%99%E5%85%A5%2F%E7%BC%96%E8%BE%91%2F%E6%9B%B4%E6%96%B0%20OsInductions%20efi%20%E5%8F%98%E9%87%8F%EF%BC%9F.png)
在使用超快速启动时需要进入 UEFI 固件设置实用程序(POST 期间不加载键盘驱动程序),我希望写入“Os Inspirations”efi 变量。我的操作系统是 Ubuntu 14.04 内核 3.13.0-35-generic。
OsIndications
变量返回 UINT64 位掩码
OsIndicationsSupported
变量返回 UINT64 位掩码
EFI_OS_INDICATIONS_BOOT_TO_FW_UI
如果固件支持 OS 请求在固件用户界面停止,则固件可以在 OsInductionsSupported 变量中设置该位。EFI_OS_INDICATIONS_BOOT_TO_FW_UI
如果操作系统希望固件在下次启动时停止在固件用户界面上,则操作系统可以在 OsIndicates 变量中设置该位。
EFI_OS_INDICATIONS_BOOT_TO_FW_UI
=0x0000000000000001
-UEFI 规范 2.3.1C 第 312 页
我的固件能够在下次启动时进入固件设置实用程序:
$ hexdump /sys/firmware/efi/vars/OsIndicationsSupported-8be4df61-93ca-11d2-aa0d-00e098032b8c/data
0000000 0001 0000 0000 0000
0000008
我可以/sys/firmware/efi/efivars
使用 创建一个新变量
$ printf\x07\x00\x00\x00\x00" > myvar-12345678-1234-1234-1234-123456789abc
然而,写入 efi 变量OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c
会导致各种结果write error: Invalid argument
:
使用新的 efivafs
# printf "x00\x00\x00\x01" > /sys/firmware/efi/efivars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c
-bash: printf: write error: Invalid argument
# printf "x00\x00\x00\x01" > /sys/firmware/efi/efivars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c
-bash: printf: write error: Invalid argument
# printf "\x01" > /sys/firmware/efi/efivars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c
-bash: printf: write error: Invalid argument
# cat enter-uefi-fw > /sys/firmware/efi/efivars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c
cat: write error: Invalid argument
使用旧的 1024 字节最大 sysfs-efivars
# cat enter-uefi-fw > /sys/firmware/efi/vars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c/raw_var
cat: write error: Input/output error
# cat enter-uefi-fw > /sys/firmware/efi/vars/new_var
cat: write error: Invalid argument
# echo 'enter-uefi-fw' > /sys/firmware/efi/vars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c/raw_var
-bash: echo: write error: Invalid argument
# printf "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" > /sys/firmware/efi/vars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c/raw_var
-bash: printf: write error: Invalid argument
检查 UEFI 变量支持正常工作的要求
- EFI 运行时服务支持应该出现在内核
$ cat /boot/config-$(uname -r) | grep CONFIG_EFI=y
返回中CONFIG_EFI=y
- 内核处理器位数/架构和 EFI 处理器位数/架构应该匹配吗
? - 内核应在 EFI 模式下启动
CSM 在固件设置实用程序/BIOS 中被禁用 - 不应通过内核命令行禁用内核中的 EFI 运行时服务,即不应使用 noefi 内核参数。
cat /proc/cmdline | grep EFI
什么也不返回 - efivarfs 文件系统应安装在 /sys/firmware/efi/efivars
mount | grep efivars
返回none on /sys/firmware/efi/efivars type efivarfs (rw)
efivar -l
应该列出 EFI 变量,没有任何错误
该命令列出 82 行,没有错误。- 检查 /sys/firmware/efi/efivars/dump-* 文件是否存在。
那里不存在转储文件。
根据https://ask.fedoraproject.org/en/question/8264/after-installing-fedora-i-cant-open-biosefi-setup/?answer=16402#post-id-16402该cat enter-uefi-fw > /sys/firmware/efi/vars/new_var
命令应该可以在 Fedora 17 中运行。
首先删除 OsInductions 并没有改善
# rm -rv /sys/firmware/efi/efivars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c
removed '/sys/firmware/efi/efivars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c'
# ls -l enter-uefi-fw
-rw-r--r-- 1 root root 2084 Aug 25 20:23 enter-uefi-fw
# cat enter-uefi-fw > /sys/firmware/efi/vars/new_var
cat: write error: Invalid argument
如何从命令行更新 Ubuntu 14.04(可信)中已有的 OsInductions efi 变量?
答案1
由于存在大量固件错误,删除非标准 UEFI 变量会导致系统固件无法开机自检, 埃菲瓦夫斯不是众所周知的标准化变量的文件将被创建为不可变文件。
https://www.kernel.org/doc/Documentation/filesystems/efivarfs.txt
这可以通过以下命令进行验证和更改lsattr和查特尔命令。
例如:
root@hi12:/tmp/test# hexdump -C out
00000000 07 00 00 00 10 00 00 00 |........|
00000008
root@hi12:/tmp/test# cp out /sys/firmware/efi/efivars/BootSelectVariable-944fb13b-773f-4cbb-9c6f-326cebde4c23
cp: cannot create regular file '/sys/firmware/efi/efivars/BootSelectVariable-944fb13b-773f-4cbb-9c6f-326cebde4c23': Operation not permitted
root@hi12:/tmp/test# lsattr /sys/firmware/efi/efivars/BootSelectVariable-944fb13b-773f-4cbb-9c6f-326cebde4c23
----i-------------- /sys/firmware/efi/efivars/BootSelectVariable-944fb13b-773f-4cbb-9c6f-326cebde4c23
root@hi12:/tmp/test# chattr -i /sys/firmware/efi/efivars/BootSelectVariable-944fb13b-773f-4cbb-9c6f-326cebde4c23
root@hi12:/tmp/test# lsattr /sys/firmware/efi/efivars/BootSelectVariable-944fb13b-773f-4cbb-9c6f-326cebde4c23
------------------- /sys/firmware/efi/efivars/BootSelectVariable-944fb13b-773f-4cbb-9c6f-326cebde4c23
root@hi12:/tmp/test# cp out /sys/firmware/efi/efivars/BootSelectVariable-944fb13b-773f-4cbb-9c6f-326cebde4c23
root@hi12:/tmp/test# chattr +i /sys/firmware/efi/efivars/BootSelectVariable-944fb13b-773f-4cbb-9c6f-326cebde4c23
root@hi12:/tmp/test# lsattr /sys/firmware/efi/efivars/BootSelectVariable-944fb13b-773f-4cbb-9c6f-326cebde4c23
----i-------------- /sys/firmware/efi/efivars/BootSelectVariable-944fb13b-773f-4cbb-9c6f-326cebde4c23
root@hi12:/tmp/test#
答案2
这里相关的 64 位掩码是:
#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001
可以使用以下命令将其生成为小端(Intel)格式字符串:
str='\x01\x00\x00\x00\x00\x00\x00\x00'; printf "$str"
上面的输出printf "$str"
需要进入数据内容efivarfs 变量文件的$var
,其中
var='/sys/firmware/efi/efivars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c'
但是,每个文件都/sys/firmware/efi/efivars
以4字节头然后是其数据内容。因此,printf "$str"
在我们将其写入 efivarfs 变量文件之前,需要以 4 字节标头作为输出的前缀$var
。如上所述,使用$str
和可以完成此操作,例如使用:$var
{ head -c 4 "$var"; printf "$str"; } > "$var"
答案3
尝试使用echo
而不是cat
.
# echo 'enter-uefi-fw' > /sys/firmware/efi/vars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c/raw_var