9

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 bitmask

The 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

$ printf\x07\x00\x00\x00\x00" > 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 "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

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 "\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

Checked the requirements for UEFI variables support to work properly

  1. EFI Runtime Services support should be present in the kernel
    $ cat /boot/config-$(uname -r) | grep CONFIG_EFI=y returns CONFIG_EFI=y
  2. Kernel processor bitness/arch and EFI processor bitness/arch should match
    ?
  3. Kernel should be booted in EFI mode
    CSM is disabled in Firmware setup utility/BIOS
  4. 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
  5. efivarfs filesystem should be mounted at /sys/firmware/efi/efivars
    mount | grep efivars returns none on /sys/firmware/efi/efivars type efivarfs (rw)
  6. efivar -l should list the EFI Variables without any error
    The command lists 82 lines and no errors.
  7. 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?

Pro Backup
  • 4,686
  • 12
  • 50
  • 82

3 Answers3

2

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='\x01\x00\x00\x00\x00\x00\x00\x00'; 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"
adgadg
  • 69
  • 7
2

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# 
-1

Try using echo instead of cat.

# echo 'enter-uefi-fw' > /sys/firmware/efi/vars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c/raw_var
fragmede
  • 94
  • 3
  • kernel 3.13.0-35-generic and 3.17.0-031700rc7-generic output: `-bash: echo: write error: Invalid argument` – Pro Backup Oct 03 '14 at 13:03
  • Looking more carefully at the list of things you tried, have you tried: `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` ? note the leading '\' in printf '\x' that you omitted, the fact that we're filling in the entire value, and the raw_var at the end of the path. – fragmede Oct 03 '14 at 19:15
  • `# 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` results in `-bash: printf: write error: Invalid argument` – Pro Backup Oct 03 '14 at 20:30
  • Did you download http://pjones.fedorapeople.org/enter-uefi-fw before running the `cat` command? – fragmede Oct 03 '14 at 20:51
  • Yes, I did download the enter-uefi-fw data file, and that file is in my current working directory: `# ls -l enter-uefi-fw` returns `-rw-r--r-- 1 root root 2084 Aug 25 20:23 enter-uefi-fw`. – Pro Backup Oct 03 '14 at 21:18
  • The issue for creating a new OsIndications UEFI variable might be that it is already there: `# ls -l /sys/firmware/efi/efivars/OsIndications-*` returns `-rw-r--r-- 1 root root 12 Oct 3 22:39 /sys/firmware/efi/efivars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c` – Pro Backup Oct 03 '14 at 21:22