Skip to content

feature request: option to reboot into efi firmware setup #423

@DvdGiessen

Description

@DvdGiessen

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions