如何从命令行编写/编辑/更新 OsIndications efi 变量?

Pro*_*kup 9 command-line ubuntu firmware uefi

在使用超快速启动时需要进入 UEFI 固件设置实用程序(POST 期间未加载键盘驱动程序),我希望写入“Os Indications”efi 变量。我的操作系统是 Ubuntu 14.04 内核 3.13.0-35-generic。

OsIndications 变量返回一个 UINT64 位掩码

OsIndicationsSupported 变量返回一个 UINT64 位掩码

EFI_OS_INDICATIONS_BOOT_TO_FW_UI如果固件支持 OS 请求在固件用户界面上停止,固件可以在 OsIndicationsSupported 变量中设置该位。该 EFI_OS_INDICATIONS_BOOT_TO_FW_UI位可由操作系统在 OsIndications 变量中设置,如果操作系统希望固件在下次启动时停止在固件用户界面。

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
Run Code Online (Sandbox Code Playgroud)

我可以在/sys/firmware/efi/efivars使用时 创建一个新变量

$ printf\x07\x00\x00\x00\x00" > myvar-12345678-1234-1234-1234-123456789abc
Run Code Online (Sandbox Code Playgroud)

然而,写入 efi 变量会OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c导致各种write error: Invalid argument

使用新的 efivarfs

# 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
Run Code Online (Sandbox Code Playgroud)

使用旧的 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
Run Code Online (Sandbox Code Playgroud)

检查 UEFI 变量支持正常工作的要求

  1. EFI 运行时服务支持应存在于内核
    $ cat /boot/config-$(uname -r) | grep CONFIG_EFI=y返回中CONFIG_EFI=y
  2. 内核处理器位数/架构和 EFI 处理器位数/架构应该匹配
    吗?
  3. 内核应该在 EFI 模式下启动
    CSM 在固件设置实用程序/BIOS 中被禁用
  4. 不应通过内核 cmdline 禁用内核中的 EFI 运行时服务,即不应使用 noefi 内核参数。
    cat /proc/cmdline | grep EFI什么都不返回
  5. efivarfs 文件系统应该挂载在 /sys/firmware/efi/efivars
    mount | grep efivars返回none on /sys/firmware/efi/efivars type efivarfs (rw)
  6. efivar -l应该列出没有任何错误的 EFI 变量
    命令列出了 82 行并且没有错误。
  7. 检查 /sys/firmware/efi/efivars/dump-* 文件是否存在。
    那里不存在转储文件。

根据https://ask.fedoraproject.org/en/question/8264/after-installing-fedora-i-cant-open-biosefi-setup/?answer=16402#post-id-16402cat enter-uefi-fw > /sys/firmware/efi/vars/new_var命令应该在 Fedora 中工作17.

首先删除 OsIndications 并没有改善

# 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
Run Code Online (Sandbox Code Playgroud)

如何从命令行更新 Ubuntu 14.04 (trusty) 中已经存在的 OsIndications efi 变量?

小智 2

由于存在大量固件错误,删除非标准 UEFI 变量会导致系统固件无法进行 POST,因此 非众所周知的标准化变量的efivarfs文件将被创建为不可变文件。

https://www.kernel.org/doc/Documentation/filesystems/efivarfs.txt

这可以使用lsattrchattr命令进行验证和更改。

例如:

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# 
Run Code Online (Sandbox Code Playgroud)