How to write/edit/update the OsIndications efi variable from command line?
In the need to enter the UEFI firmware setup utility while using ultra fast boot (keyboard drivers are not loaded during POST), I wish to write to the “Os Indications” efi variable. My OS is Ubuntu 14.04 kernel 3.13.0-35-generic.
OsIndications
variable returns a UINT64 bitmask
OsIndicationsSupported
variable returns a UINT64 bitmaskThe
EFI_OS_INDICATIONS_BOOT_TO_FW_UI
bit can be set in the
OsIndicationsSupported variable by the firmware, if the firmware
supports OS requests to stop at a firmware user interface. The
EFI_OS_INDICATIONS_BOOT_TO_FW_UI
bit can be set by the OS in the
OsIndications variable, if the OS desires for the firmware to stop at
a firmware user interface on the next boot.
EFI_OS_INDICATIONS_BOOT_TO_FW_UI
=0x0000000000000001
– Page 312 of UEFI spec
2.3.1C
My firmware has the ability to enter the firmware setup utility at next boot:
$ hexdump /sys/firmware/efi/vars/OsIndicationsSupported-8be4df61-93ca-11d2-aa0d-00e098032b8c/data
0000000 0001 0000 0000 0000
0000008
I can create a new variable on /sys/firmware/efi/efivars
using
$ printfx07x00x00x00x00" > myvar-12345678-1234-1234-1234-123456789abc
However writing to the efi variable OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c
results in all sorts of write error: Invalid argument
:
Using new efivarfs
# printf "x00x00x00x01" > /sys/firmware/efi/efivars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c
-bash: printf: write error: Invalid argument
# printf "x00x00x00x01" > /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
Using old 1024 byte maximum 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 "x00x00x00x01x00x00x00x00x00x00x00x00x00x00x00x00" > /sys/firmware/efi/vars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c/raw_var
-bash: printf: write error: Invalid argument
Checked the requirements for UEFI variables support to work properly
- EFI Runtime Services support should be present in the kernel
$ cat /boot/config-$(uname -r) | grep CONFIG_EFI=y
returnsCONFIG_EFI=y
- Kernel processor bitness/arch and EFI processor bitness/arch should match
? - Kernel should be booted in EFI mode
CSM is disabled in Firmware setup utility/BIOS - EFI runtime services in the kernel should not be disabled via kernel cmdline, i.e. noefi kernel parameter should not be used.
cat /proc/cmdline | grep EFI
returns nothing - efivarfs filesystem should be mounted at /sys/firmware/efi/efivars
mount | grep efivars
returnsnone on /sys/firmware/efi/efivars type efivarfs (rw)
efivar -l
should list the EFI Variables without any error
The command lists 82 lines and no errors.- Check for existence of /sys/firmware/efi/efivars/dump-* files.
No dump- files exist there.
According to https://ask.fedoraproject.org/en/question/8264/after-installing-fedora-i-cant-open-biosefi-setup/?answer=16402#post-id-16402 the cat enter-uefi-fw > /sys/firmware/efi/vars/new_var
command should work in Fedora 17.
First deleting OsIndications doesn’t improve
# 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
How can I update the already existing OsIndications efi variable in Ubuntu 14.04 (trusty) from the command-line?
Try using echo
instead of cat
.
# echo 'enter-uefi-fw' > /sys/firmware/efi/vars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c/raw_var
The relevant 64-bit mask here is:
#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001
This can be produced as a little-endian (Intel) format string using:
str='x01x00x00x00x00x00x00x00'; printf "$str"
The output of printf "$str"
above needs to go into the data contents of the efivarfs variable file $var
, where
var='/sys/firmware/efi/efivars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c'
However, each file in /sys/firmware/efi/efivars
begins with a 4-byte header and is then followed by its data contents. Therefore, the output of printf "$str"
needs to prefixed with the 4-byte header before we can write it onto the efivarfs variable file $var
. With $str
and $var
as above, this can be done, e.g., using:
{ head -c 4 "$var"; printf "$str"; } > "$var"
Due to the presence of numerous firmware bugs where removing
non-standard UEFI variables causes the system firmware to fail to POST,
efivarfs files that are not well-known standardized variables are
created as immutable files.
https://www.kernel.org/doc/Documentation/filesystems/efivarfs.txt
This can be verified and changed with the lsattr and chattr commands.
For example:
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#