Skip to content

Commit 02d3755

Browse files
committed
zfsbootmenu/bin/reboot: add reboot-to-uefi functionality
fixes #423
1 parent 3ca7abc commit 02d3755

File tree

4 files changed

+61
-1
lines changed

4 files changed

+61
-1
lines changed

docs/online/recovery-shell.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,7 @@ Common Commands
6363
**reboot**
6464

6565
Reboot the system using a SysRq magic invocation.
66+
67+
**firmware-setup**
68+
69+
Reboot the system into the UEFI Firmware Setup interface (if available).

zfsbootmenu/bin/firmware-setup

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
reboot

zfsbootmenu/bin/reboot

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# shellcheck disable=SC1091
55
sources=(
66
/lib/kmsg-log-lib.sh
7+
/lib/efi-firmware-lib.sh
78
/lib/zfsbootmenu-core.sh
89
)
910

@@ -24,6 +25,13 @@ case "${0##*/}" in
2425
shutdown|poweroff)
2526
trigger="o"
2627
;;
28+
firmware-setup)
29+
if ! check_fw_setup || ! set_fw_setup; then
30+
echo -e "\033[0;31mWARNING: Reboot to UEFI firmware UI unsupported; unable to proceed\033[0m"
31+
exit 1
32+
fi
33+
trigger="b"
34+
;;
2735
*)
2836
exit
2937
;;
@@ -34,7 +42,7 @@ while read -r _pool; do
3442
done <<<"$( zpool list -H -o name )"
3543

3644
sysrq="/proc/sysrq-trigger"
37-
if [ -e "${sysrq}" ] && [ -w "${sysrq}" ]; then
45+
if [ -e "${sysrq}" ] && [ -w "${sysrq}" ]; then
3846
echo "${trigger}" > /proc/sysrq-trigger
3947
else
4048
echo "${sysrq} does not exist, hard reset system"
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/bin/bash
2+
# vim: softtabstop=2 shiftwidth=2 expandtab
3+
4+
source /lib/kmsg-log-lib.sh >/dev/null 2>&1 || exit 1
5+
source /lib/zfsbootmenu-core.sh >/dev/null 2>&1 || exit 1
6+
7+
check_fw_setup() {
8+
local osind_path="/sys/firmware/efi/efivars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c"
9+
local osind_supp_path="/sys/firmware/efi/efivars/OsIndicationsSupported-8be4df61-93ca-11d2-aa0d-00e098032b8c"
10+
if ! is_efi_system; then
11+
zdebug "efivarfs unsupported"
12+
return 1
13+
elif [ ! -r "${osind_supp_path}" ]; then
14+
zdebug "OsIndicationsSupported unsupported"
15+
return 1
16+
elif [ ! -r "${osind_path}" ]; then
17+
zdebug "OsIndications unsupported"
18+
return 1
19+
fi
20+
21+
# Check if the EFI_OS_INDICATIONS_BOOT_TO_FW_UI = 0x01 bit is set
22+
if ! (( $(od -An -t u1 -j4 -N1 "${osind_supp_path}" | tr -dc '0-9') & 1 )); then
23+
zdebug "EFI reboot to firmware setup unsupported"
24+
return 1
25+
fi
26+
}
27+
28+
set_fw_setup() {
29+
local bytes osind_path="/sys/firmware/efi/efivars/OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c"
30+
local -a osindications
31+
32+
mount_efivarfs rw
33+
if [ ! -w "${osind_path}" ]; then
34+
zdebug "OsIndications not writable"
35+
return 1
36+
fi
37+
38+
mapfile -t osindications < <(od -An -t x1 -v -w1 "${osind_path}" | tr -dc '[:alnum:]\n')
39+
40+
# Set the EFI_OS_INDICATIONS_BOOT_TO_FW_UI = 0x01 bit if not already set
41+
if ! (( "${osindications[4]}" & 0x01 )); then
42+
printf -v osindications[4] '%02x' $(( 0x"${osindications[4]}" | 0x01 ))
43+
44+
printf -v bytes '\\x%02x' "${osindications[@]}"
45+
printf '%b' "$bytes" > "${osind_path}"
46+
fi
47+
}

0 commit comments

Comments
 (0)