-
Notifications
You must be signed in to change notification settings - Fork 95
Description
Use case: You want to go to the BIOS/EFI setup menu. But for example didn't press the key in time, or perhaps don't know which key to press for this particular motherboard, etc. What if you could just press a simple hotkey, for example "Ctrl-F" for firmware, and let ZBM reboot into it?
Similar features exist for example in GRUB, the Windows bootloader, systemd (systemctl reboot --firmware-setup).
Looks like it should be fairly straightforward to implement, just set a value in the efivarfs and reboot. We can detect if it is supported before showing the hotkey option at all. A quickly thrown together example:
#!/bin/bash
# args: none
# prints: nothing
# returns: 0 if reboot to EFI firmware UI is supported, 1 if not
efi_supports_reboot_to_fw_ui() {
if ! is_efi_system ; then
zdebug "efivarfs unsupported"
return 1
elif [ ! -r /sys/firmware/efi/efivars/OsIndicationsSupported-8be4df61-93ca-11d2-aa0d-00e098032b8c ] ; then
zdebug "OsIndicationsSupported unsupported"
return 1
elif [ ! -r /sys/firmware/efi/efivars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c ] ; then
zdebug "OsIndications unsupported"
return 1
fi
# Check if the EFI_OS_INDICATIONS_BOOT_TO_FW_UI = 0x01 bit is set
perl -e 'exit !(unpack("x4Q<", <STDIN>) & 1)' \
< /sys/firmware/efi/efivars/OsIndicationsSupported-8be4df61-93ca-11d2-aa0d-00e098032b8c
}
# args: none
# prints: nothing
# returns: 1 on error, 2 if unsupported, otherwise does not return
efi_reboot_to_fw_ui() {
if ! efi_supports_reboot_to_fw_ui ; then
zdebug "efi reboot to fw unsupported"
return 2
fi
# Remount efivarfs to be writable
mount_efivarfs rw
if [ ! -w /sys/firmware/efi/efivars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c ] ; then
zdebug "OsIndications not writable"
return 1
fi
# Set the EFI_OS_INDICATIONS_BOOT_TO_FW_UI = 0x01 bit,
# with required flags set:
# EFI_VARIABLE_NON_VOLATILE = 0x01
# EFI_VARIABLE_BOOTSERVICE_ACCESS = 0x02
# EFI_VARIABLE_RUNTIME_ACCESS = 0x04
perl -e 'print pack("(LQ)<", 1|2|4, unpack("x4Q<", <STDIN>) | 1)' \
< /sys/firmware/efi/efivars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c \
| sponge /sys/firmware/efi/efivars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c
reboot
}This example depends on perl (for the unsigned 64 bit LE integers) and sponge (from moreutils), but it can probably be done in pure Bash as well.