systemd: fix systemd-boot keyboard handling lockup
In v248 compiler weirdness and refactoring lead to the bootloader erroring out handling keyboard input on some systems. See https://github.com/systemd/systemd/issues/19191 This should be redundant in v249.6 when it officially gets tagged in systemd-stable. Closes https://github.com/NixOS/nixpkgs/issues/143847
This commit is contained in:
parent
9a96e0ec8c
commit
d216b21513
@ -1,7 +1,7 @@
|
||||
From 06a8dbb65584b6f705fee8a486f32dab12f72082 Mon Sep 17 00:00:00 2001
|
||||
From d4ea219a35a09fe02bc9e47e8530644cb4fc4146 Mon Sep 17 00:00:00 2001
|
||||
From: Eelco Dolstra <eelco.dolstra@logicblox.com>
|
||||
Date: Tue, 8 Jan 2013 15:46:30 +0100
|
||||
Subject: [PATCH 01/19] Start device units for uninitialised encrypted devices
|
||||
Subject: [PATCH 01/21] Start device units for uninitialised encrypted devices
|
||||
|
||||
This is necessary because the NixOS service that initialises the
|
||||
filesystem depends on the appearance of the device unit. Also, this
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 2c98ff115f7027bebde14cf3e74f2c51b343874c Mon Sep 17 00:00:00 2001
|
||||
From 67abd8f22f70d9348bc9d8e0e93dde4d325627ba Mon Sep 17 00:00:00 2001
|
||||
From: Eelco Dolstra <eelco.dolstra@logicblox.com>
|
||||
Date: Fri, 12 Apr 2013 13:16:57 +0200
|
||||
Subject: [PATCH 02/19] Don't try to unmount /nix or /nix/store
|
||||
Subject: [PATCH 02/21] Don't try to unmount /nix or /nix/store
|
||||
|
||||
They'll still be remounted read-only.
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 16f441b6495ff4c4d1d0b71a7f1650505147173d Mon Sep 17 00:00:00 2001
|
||||
From 37c9471f59bd57223014a4a645b5f96a71d78787 Mon Sep 17 00:00:00 2001
|
||||
From: Eelco Dolstra <eelco.dolstra@logicblox.com>
|
||||
Date: Wed, 16 Apr 2014 10:59:28 +0200
|
||||
Subject: [PATCH 03/19] Fix NixOS containers
|
||||
Subject: [PATCH 03/21] Fix NixOS containers
|
||||
|
||||
In NixOS containers, the init script is bind-mounted into the
|
||||
container, so checking early whether it exists will fail.
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 261423bc039378115ad9223c2b6ede9c395847b2 Mon Sep 17 00:00:00 2001
|
||||
From 987d6f94dac8e1a75615fd9ddcfb0eb1c2c4c349 Mon Sep 17 00:00:00 2001
|
||||
From: Eelco Dolstra <eelco.dolstra@logicblox.com>
|
||||
Date: Thu, 1 May 2014 14:10:10 +0200
|
||||
Subject: [PATCH 04/19] Look for fsck in the right place
|
||||
Subject: [PATCH 04/21] Look for fsck in the right place
|
||||
|
||||
---
|
||||
src/fsck/fsck.c | 2 +-
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 18b45c20499747bcc66714ee87edf34d4f6e3dca Mon Sep 17 00:00:00 2001
|
||||
From da4f855044b2babe052ce303cca1de736cf952cd Mon Sep 17 00:00:00 2001
|
||||
From: Eelco Dolstra <eelco.dolstra@logicblox.com>
|
||||
Date: Fri, 19 Dec 2014 14:46:17 +0100
|
||||
Subject: [PATCH 05/19] Add some NixOS-specific unit directories
|
||||
Subject: [PATCH 05/21] Add some NixOS-specific unit directories
|
||||
|
||||
Look in `/nix/var/nix/profiles/default/lib/systemd/{system,user}` for
|
||||
units provided by packages installed into the default profile via
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 8b8f4168828a12cac17c3e8803cacebf31608c68 Mon Sep 17 00:00:00 2001
|
||||
From c06abdb631527f56a626b739340d1b275349612c Mon Sep 17 00:00:00 2001
|
||||
From: Eelco Dolstra <eelco.dolstra@logicblox.com>
|
||||
Date: Mon, 11 May 2015 15:39:38 +0200
|
||||
Subject: [PATCH 06/19] Get rid of a useless message in user sessions
|
||||
Subject: [PATCH 06/21] Get rid of a useless message in user sessions
|
||||
|
||||
Namely lots of variants of
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From e147e9defaf2bb5e8040566537661d90b4008daf Mon Sep 17 00:00:00 2001
|
||||
From 207c69466cdd164c42ed1901deb06f57b12f4363 Mon Sep 17 00:00:00 2001
|
||||
From: Gabriel Ebner <gebner@gebner.org>
|
||||
Date: Sun, 6 Dec 2015 14:26:36 +0100
|
||||
Subject: [PATCH 07/19] hostnamed, localed, timedated: disable methods that
|
||||
Subject: [PATCH 07/21] hostnamed, localed, timedated: disable methods that
|
||||
change system settings.
|
||||
|
||||
---
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 992d0e6abb09aacceee2f8646c4bcdacf7277dc7 Mon Sep 17 00:00:00 2001
|
||||
From 3ca3855259c3015615983587063fa159cfa7e93c Mon Sep 17 00:00:00 2001
|
||||
From: Nikolay Amiantov <ab@fmap.me>
|
||||
Date: Thu, 7 Jul 2016 02:47:13 +0300
|
||||
Subject: [PATCH 08/19] Fix hwdb paths
|
||||
Subject: [PATCH 08/21] Fix hwdb paths
|
||||
|
||||
Patch by vcunat.
|
||||
---
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 462bc01b3a38468fd617066a3d7f27b1acca9e0a Mon Sep 17 00:00:00 2001
|
||||
From 717226ad0dc37ceb6c667c1f56396848978b6e83 Mon Sep 17 00:00:00 2001
|
||||
From: Nikolay Amiantov <ab@fmap.me>
|
||||
Date: Tue, 11 Oct 2016 13:12:08 +0300
|
||||
Subject: [PATCH 09/19] Change /usr/share/zoneinfo to /etc/zoneinfo
|
||||
Subject: [PATCH 09/21] Change /usr/share/zoneinfo to /etc/zoneinfo
|
||||
|
||||
NixOS uses this path.
|
||||
---
|
||||
|
@ -1,7 +1,7 @@
|
||||
From fbb302d00c63dc17a210f83648f24a1da983b2c0 Mon Sep 17 00:00:00 2001
|
||||
From 75d12cf65073458f091899d673c613dfc43f60c0 Mon Sep 17 00:00:00 2001
|
||||
From: Imuli <i@imu.li>
|
||||
Date: Wed, 19 Oct 2016 08:46:47 -0400
|
||||
Subject: [PATCH 10/19] localectl: use /etc/X11/xkb for list-x11-*
|
||||
Subject: [PATCH 10/21] localectl: use /etc/X11/xkb for list-x11-*
|
||||
|
||||
NixOS has an option to link the xkb data files to /etc/X11, but not to
|
||||
/usr/share/X11.
|
||||
|
@ -1,7 +1,7 @@
|
||||
From b850dae349de8ac6906d4f920a21ef275cecb2de Mon Sep 17 00:00:00 2001
|
||||
From bce75eb4cdeb0b86df6b0a577e886c49a88303f6 Mon Sep 17 00:00:00 2001
|
||||
From: Franz Pletz <fpletz@fnordicwalking.de>
|
||||
Date: Sun, 11 Feb 2018 04:37:44 +0100
|
||||
Subject: [PATCH 11/19] build: don't create statedir and don't touch prefixdir
|
||||
Subject: [PATCH 11/21] build: don't create statedir and don't touch prefixdir
|
||||
|
||||
---
|
||||
meson.build | 3 ---
|
||||
|
@ -1,7 +1,7 @@
|
||||
From beefb6d381286769cc47c71c82b831a37a405d90 Mon Sep 17 00:00:00 2001
|
||||
From ecdf0c5d9f88f526521f093cc9ee85f43efab4b7 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Rammhold <andreas@rammhold.de>
|
||||
Date: Fri, 2 Nov 2018 21:15:42 +0100
|
||||
Subject: [PATCH 12/19] inherit systemd environment when calling generators.
|
||||
Subject: [PATCH 12/21] inherit systemd environment when calling generators.
|
||||
|
||||
Systemd generators need access to the environment configured in
|
||||
stage-2-init.sh since it schedules fsck and mkfs executions based on
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 146b79d55cc4fdfdb5fd4978e68b21f5c1df1679 Mon Sep 17 00:00:00 2001
|
||||
From 39969a1b01d6c223a21c770093209b7f4047aaa4 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Rammhold <andreas@rammhold.de>
|
||||
Date: Thu, 9 May 2019 11:15:22 +0200
|
||||
Subject: [PATCH 13/19] add rootprefix to lookup dir paths
|
||||
Subject: [PATCH 13/21] add rootprefix to lookup dir paths
|
||||
|
||||
systemd does not longer use the UDEVLIBEXEC directory as root for
|
||||
discovery default udev rules. By adding `$out/lib` to the lookup paths
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 8edd810e74e2308f34eba6e8072e559e69307830 Mon Sep 17 00:00:00 2001
|
||||
From e7c960789b0ca97b24a66e9eeaa56ea645d9c66b Mon Sep 17 00:00:00 2001
|
||||
From: Nikolay Amiantov <ab@fmap.me>
|
||||
Date: Thu, 25 Jul 2019 20:45:55 +0300
|
||||
Subject: [PATCH 14/19] systemd-shutdown: execute scripts in
|
||||
Subject: [PATCH 14/21] systemd-shutdown: execute scripts in
|
||||
/etc/systemd/system-shutdown
|
||||
|
||||
This is needed for NixOS to use such scripts as systemd directory is immutable.
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 9ed24199dd3ce91d3f7fbfbdf823312c124aba56 Mon Sep 17 00:00:00 2001
|
||||
From 6124720aa2b9dbc07f2fb898f0db150a44a86041 Mon Sep 17 00:00:00 2001
|
||||
From: Nikolay Amiantov <ab@fmap.me>
|
||||
Date: Thu, 25 Jul 2019 20:46:58 +0300
|
||||
Subject: [PATCH 15/19] systemd-sleep: execute scripts in
|
||||
Subject: [PATCH 15/21] systemd-sleep: execute scripts in
|
||||
/etc/systemd/system-sleep
|
||||
|
||||
This is needed for NixOS to use such scripts as systemd directory is immutable.
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 6db7ad4d5526a82e4ed9b135daf1054a8b71e1c7 Mon Sep 17 00:00:00 2001
|
||||
From bee1d855d4fb7f2d6f6b9beb1dfd14b1dea31887 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Klink <flokli@flokli.de>
|
||||
Date: Sat, 7 Mar 2020 22:40:27 +0100
|
||||
Subject: [PATCH 16/19] kmod-static-nodes.service: Update ConditionFileNotEmpty
|
||||
Subject: [PATCH 16/21] kmod-static-nodes.service: Update ConditionFileNotEmpty
|
||||
|
||||
On NixOS, kernel modules of the currently booted systems are located at
|
||||
/run/booted-system/kernel-modules/lib/modules/%v/, not /lib/modules/%v/.
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 160d32c336c96744bbfb618eae4c12cb90138644 Mon Sep 17 00:00:00 2001
|
||||
From 62198599bbc559eeb8e2a3caebce7b9135085270 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Klink <flokli@flokli.de>
|
||||
Date: Sun, 8 Mar 2020 01:05:54 +0100
|
||||
Subject: [PATCH 17/19] path-util.h: add placeholder for DEFAULT_PATH_NORMAL
|
||||
Subject: [PATCH 17/21] path-util.h: add placeholder for DEFAULT_PATH_NORMAL
|
||||
|
||||
This will be the $PATH used to lookup ExecStart= etc. options, which
|
||||
systemd itself uses extensively.
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 777d61550f95b1dcf253e1d2132f9db7010a18f3 Mon Sep 17 00:00:00 2001
|
||||
From 7654964344ba083529cb232ab229db7c0888f782 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= <joerg@thalheim.io>
|
||||
Date: Sun, 6 Dec 2020 08:34:19 +0100
|
||||
Subject: [PATCH 18/19] pkg-config: derive prefix from --prefix
|
||||
Subject: [PATCH 18/21] pkg-config: derive prefix from --prefix
|
||||
|
||||
Point prefix to the one configured, instead of `/usr` `systemd` has limited
|
||||
support for making the pkgconfig prefix overridable, and interpolates those
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 273e706ff561f2164b84c714148346ac92dd8846 Mon Sep 17 00:00:00 2001
|
||||
From 4e9b4aa87d299be08cffc77a86d6f473a7a4109a Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Rammhold <andreas@rammhold.de>
|
||||
Date: Wed, 18 Aug 2021 19:10:08 +0200
|
||||
Subject: [PATCH 19/19] core: handle lookup paths being symlinks
|
||||
Subject: [PATCH 19/21] core: handle lookup paths being symlinks
|
||||
|
||||
With a recent change paths leaving the statically known lookup paths
|
||||
would be treated differently then those that remained within those. That
|
||||
|
@ -0,0 +1,401 @@
|
||||
From 3cf1b5fb6d1dc342e836cf0990df3170d2e9db49 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Janssen <medhefgo@web.de>
|
||||
Date: Wed, 11 Aug 2021 14:59:46 +0200
|
||||
Subject: [PATCH 20/21] sd-boot: Unify error handling
|
||||
|
||||
log_error_stall() and log_error_status_stall() will ensure the user has
|
||||
a chance to catch an error message by stalling and also forcing a
|
||||
lightred/black color on it. Also, convert several Print() calls to it
|
||||
since they are actually error messages.
|
||||
|
||||
(cherry picked from commit 8aba0eec499b762657f528988c2f093ac490620d)
|
||||
---
|
||||
src/boot/efi/boot.c | 62 ++++++++++----------------------
|
||||
src/boot/efi/random-seed.c | 73 +++++++++++++-------------------------
|
||||
src/boot/efi/stub.c | 24 ++++---------
|
||||
src/boot/efi/util.c | 17 +++++++--
|
||||
src/boot/efi/util.h | 9 +++++
|
||||
5 files changed, 75 insertions(+), 110 deletions(-)
|
||||
|
||||
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
|
||||
index 13940a6df7..54d704f0d1 100644
|
||||
--- a/src/boot/efi/boot.c
|
||||
+++ b/src/boot/efi/boot.c
|
||||
@@ -527,7 +527,7 @@ static BOOLEAN menu_run(
|
||||
err = console_set_mode(&config->console_mode, config->console_mode_change);
|
||||
if (EFI_ERROR(err)) {
|
||||
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||||
- Print(L"Error switching console mode to %ld: %r.\r", (UINT64)config->console_mode, err);
|
||||
+ log_error_stall(L"Error switching console mode to %lu: %r", (UINT64)config->console_mode, err);
|
||||
}
|
||||
} else
|
||||
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||||
@@ -1221,8 +1221,7 @@ static VOID config_entry_bump_counters(
|
||||
break;
|
||||
|
||||
if (r != EFI_BUFFER_TOO_SMALL || file_info_size * 2 < file_info_size) {
|
||||
- Print(L"\nFailed to get file info for '%s': %r\n", old_path, r);
|
||||
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
+ log_error_stall(L"Failed to get file info for '%s': %r", old_path, r);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1234,8 +1233,7 @@ static VOID config_entry_bump_counters(
|
||||
StrCpy(file_info->FileName, entry->next_name);
|
||||
r = uefi_call_wrapper(handle->SetInfo, 4, handle, &EfiFileInfoGuid, file_info_size, file_info);
|
||||
if (EFI_ERROR(r)) {
|
||||
- Print(L"\nFailed to rename '%s' to '%s', ignoring: %r\n", old_path, entry->next_name, r);
|
||||
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
+ log_error_stall(L"Failed to rename '%s' to '%s', ignoring: %r", old_path, entry->next_name, r);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2165,18 +2163,12 @@ static EFI_STATUS image_start(
|
||||
EFI_STATUS err;
|
||||
|
||||
path = FileDevicePath(entry->device, entry->loader);
|
||||
- if (!path) {
|
||||
- Print(L"Error getting device path.");
|
||||
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
- return EFI_INVALID_PARAMETER;
|
||||
- }
|
||||
+ if (!path)
|
||||
+ return log_error_status_stall(EFI_INVALID_PARAMETER, L"Error getting device path.");
|
||||
|
||||
err = uefi_call_wrapper(BS->LoadImage, 6, FALSE, parent_image, path, NULL, 0, &image);
|
||||
- if (EFI_ERROR(err)) {
|
||||
- Print(L"Error loading %s: %r", entry->loader, err);
|
||||
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
- return err;
|
||||
- }
|
||||
+ if (EFI_ERROR(err))
|
||||
+ return log_error_status_stall(err, L"Error loading %s: %r", entry->loader, err);
|
||||
|
||||
if (config->options_edit)
|
||||
options = config->options_edit;
|
||||
@@ -2190,8 +2182,7 @@ static EFI_STATUS image_start(
|
||||
err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image,
|
||||
parent_image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (EFI_ERROR(err)) {
|
||||
- Print(L"Error getting LoadedImageProtocol handle: %r", err);
|
||||
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
+ log_error_stall(L"Error getting LoadedImageProtocol handle: %r", err);
|
||||
goto out_unload;
|
||||
}
|
||||
loaded_image->LoadOptions = options;
|
||||
@@ -2202,10 +2193,8 @@ static EFI_STATUS image_start(
|
||||
err = tpm_log_event(SD_TPM_PCR,
|
||||
(EFI_PHYSICAL_ADDRESS) (UINTN) loaded_image->LoadOptions,
|
||||
loaded_image->LoadOptionsSize, loaded_image->LoadOptions);
|
||||
- if (EFI_ERROR(err)) {
|
||||
- Print(L"Unable to add image options measurement: %r", err);
|
||||
- uefi_call_wrapper(BS->Stall, 1, 200 * 1000);
|
||||
- }
|
||||
+ if (EFI_ERROR(err))
|
||||
+ log_error_stall(L"Unable to add image options measurement: %r", err);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2231,9 +2220,7 @@ static EFI_STATUS reboot_into_firmware(VOID) {
|
||||
return err;
|
||||
|
||||
err = uefi_call_wrapper(RT->ResetSystem, 4, EfiResetCold, EFI_SUCCESS, 0, NULL);
|
||||
- Print(L"Error calling ResetSystem: %r", err);
|
||||
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
- return err;
|
||||
+ return log_error_status_stall(err, L"Error calling ResetSystem: %r", err);
|
||||
}
|
||||
|
||||
static VOID config_free(Config *config) {
|
||||
@@ -2305,30 +2292,21 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
|
||||
err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image,
|
||||
image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
- if (EFI_ERROR(err)) {
|
||||
- Print(L"Error getting a LoadedImageProtocol handle: %r", err);
|
||||
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
- return err;
|
||||
- }
|
||||
+ if (EFI_ERROR(err))
|
||||
+ return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err);
|
||||
|
||||
/* export the device path this image is started from */
|
||||
if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == EFI_SUCCESS)
|
||||
efivar_set(LOADER_GUID, L"LoaderDevicePartUUID", uuid, 0);
|
||||
|
||||
root_dir = LibOpenRoot(loaded_image->DeviceHandle);
|
||||
- if (!root_dir) {
|
||||
- Print(L"Unable to open root directory.");
|
||||
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
- return EFI_LOAD_ERROR;
|
||||
- }
|
||||
+ if (!root_dir)
|
||||
+ return log_error_status_stall(EFI_LOAD_ERROR, L"Unable to open root directory.", EFI_LOAD_ERROR);
|
||||
|
||||
if (secure_boot_enabled() && shim_loaded()) {
|
||||
err = security_policy_install();
|
||||
- if (EFI_ERROR(err)) {
|
||||
- Print(L"Error installing security policy: %r ", err);
|
||||
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
- return err;
|
||||
- }
|
||||
+ if (EFI_ERROR(err))
|
||||
+ return log_error_status_stall(err, L"Error installing security policy: %r", err);
|
||||
}
|
||||
|
||||
/* the filesystem path to this image, to prevent adding ourselves to the menu */
|
||||
@@ -2367,8 +2345,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
}
|
||||
|
||||
if (config.entry_count == 0) {
|
||||
- Print(L"No loader found. Configuration files in \\loader\\entries\\*.conf are needed.");
|
||||
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
+ log_error_stall(L"No loader found. Configuration files in \\loader\\entries\\*.conf are needed.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -2440,8 +2417,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
err = image_start(image, &config, entry);
|
||||
if (EFI_ERROR(err)) {
|
||||
graphics_mode(FALSE);
|
||||
- Print(L"\nFailed to execute %s (%s): %r\n", entry->title, entry->loader, err);
|
||||
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
+ log_error_stall(L"Failed to execute %s (%s): %r", entry->title, entry->loader, err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
diff --git a/src/boot/efi/random-seed.c b/src/boot/efi/random-seed.c
|
||||
index 3e179851b0..939daf3e41 100644
|
||||
--- a/src/boot/efi/random-seed.c
|
||||
+++ b/src/boot/efi/random-seed.c
|
||||
@@ -35,10 +35,8 @@ static EFI_STATUS acquire_rng(UINTN size, VOID **ret) {
|
||||
return log_oom();
|
||||
|
||||
err = uefi_call_wrapper(rng->GetRNG, 3, rng, NULL, size, data);
|
||||
- if (EFI_ERROR(err)) {
|
||||
- Print(L"Failed to acquire RNG data: %r\n", err);
|
||||
- return err;
|
||||
- }
|
||||
+ if (EFI_ERROR(err))
|
||||
+ return log_error_status_stall(err, L"Failed to acquire RNG data: %r", err);
|
||||
|
||||
*ret = TAKE_PTR(data);
|
||||
return EFI_SUCCESS;
|
||||
@@ -149,14 +147,12 @@ static EFI_STATUS acquire_system_token(VOID **ret, UINTN *ret_size) {
|
||||
err = efivar_get_raw(LOADER_GUID, L"LoaderSystemToken", &data, &size);
|
||||
if (EFI_ERROR(err)) {
|
||||
if (err != EFI_NOT_FOUND)
|
||||
- Print(L"Failed to read LoaderSystemToken EFI variable: %r", err);
|
||||
+ log_error_stall(L"Failed to read LoaderSystemToken EFI variable: %r", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
- if (size <= 0) {
|
||||
- Print(L"System token too short, ignoring.");
|
||||
- return EFI_NOT_FOUND;
|
||||
- }
|
||||
+ if (size <= 0)
|
||||
+ return log_error_status_stall(EFI_NOT_FOUND, L"System token too short, ignoring.");
|
||||
|
||||
*ret = TAKE_PTR(data);
|
||||
*ret_size = size;
|
||||
@@ -209,8 +205,7 @@ static VOID validate_sha256(void) {
|
||||
sha256_finish_ctx(&hash, result);
|
||||
|
||||
if (CompareMem(result, array[i].hash, HASH_VALUE_SIZE) != 0) {
|
||||
- Print(L"SHA256 failed validation.\n");
|
||||
- uefi_call_wrapper(BS->Stall, 1, 120 * 1000 * 1000);
|
||||
+ log_error_stall(L"SHA256 failed validation.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -246,7 +241,7 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
|
||||
err = uefi_call_wrapper(root_dir->Open, 5, root_dir, &handle, (CHAR16*) L"\\loader\\random-seed", EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0ULL);
|
||||
if (EFI_ERROR(err)) {
|
||||
if (err != EFI_NOT_FOUND && err != EFI_WRITE_PROTECTED)
|
||||
- Print(L"Failed to open random seed file: %r\n", err);
|
||||
+ log_error_stall(L"Failed to open random seed file: %r", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -255,15 +250,11 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
|
||||
return log_oom();
|
||||
|
||||
size = info->FileSize;
|
||||
- if (size < RANDOM_MAX_SIZE_MIN) {
|
||||
- Print(L"Random seed file is too short?\n");
|
||||
- return EFI_INVALID_PARAMETER;
|
||||
- }
|
||||
+ if (size < RANDOM_MAX_SIZE_MIN)
|
||||
+ return log_error_status_stall(EFI_INVALID_PARAMETER, L"Random seed file is too short.");
|
||||
|
||||
- if (size > RANDOM_MAX_SIZE_MAX) {
|
||||
- Print(L"Random seed file is too large?\n");
|
||||
- return EFI_INVALID_PARAMETER;
|
||||
- }
|
||||
+ if (size > RANDOM_MAX_SIZE_MAX)
|
||||
+ return log_error_status_stall(EFI_INVALID_PARAMETER, L"Random seed file is too large.");
|
||||
|
||||
seed = AllocatePool(size);
|
||||
if (!seed)
|
||||
@@ -271,20 +262,14 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
|
||||
|
||||
rsize = size;
|
||||
err = uefi_call_wrapper(handle->Read, 3, handle, &rsize, seed);
|
||||
- if (EFI_ERROR(err)) {
|
||||
- Print(L"Failed to read random seed file: %r\n", err);
|
||||
- return err;
|
||||
- }
|
||||
- if (rsize != size) {
|
||||
- Print(L"Short read on random seed file\n");
|
||||
- return EFI_PROTOCOL_ERROR;
|
||||
- }
|
||||
+ if (EFI_ERROR(err))
|
||||
+ return log_error_status_stall(err, L"Failed to read random seed file: %r", err);
|
||||
+ if (rsize != size)
|
||||
+ return log_error_status_stall(EFI_PROTOCOL_ERROR, L"Short read on random seed file.");
|
||||
|
||||
err = uefi_call_wrapper(handle->SetPosition, 2, handle, 0);
|
||||
- if (EFI_ERROR(err)) {
|
||||
- Print(L"Failed to seek to beginning of random seed file: %r\n", err);
|
||||
- return err;
|
||||
- }
|
||||
+ if (EFI_ERROR(err))
|
||||
+ return log_error_status_stall(err, L"Failed to seek to beginning of random seed file: %r", err);
|
||||
|
||||
/* Request some random data from the UEFI RNG. We don't need this to work safely, but it's a good
|
||||
* idea to use it because it helps us for cases where users mistakenly include a random seed in
|
||||
@@ -299,27 +284,19 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
|
||||
/* Update the random seed on disk before we use it */
|
||||
wsize = size;
|
||||
err = uefi_call_wrapper(handle->Write, 3, handle, &wsize, new_seed);
|
||||
- if (EFI_ERROR(err)) {
|
||||
- Print(L"Failed to write random seed file: %r\n", err);
|
||||
- return err;
|
||||
- }
|
||||
- if (wsize != size) {
|
||||
- Print(L"Short write on random seed file\n");
|
||||
- return EFI_PROTOCOL_ERROR;
|
||||
- }
|
||||
+ if (EFI_ERROR(err))
|
||||
+ return log_error_status_stall(err, L"Failed to write random seed file: %r", err);
|
||||
+ if (wsize != size)
|
||||
+ return log_error_status_stall(EFI_PROTOCOL_ERROR, L"Short write on random seed file.");
|
||||
|
||||
err = uefi_call_wrapper(handle->Flush, 1, handle);
|
||||
- if (EFI_ERROR(err)) {
|
||||
- Print(L"Failed to flush random seed file: %r\n");
|
||||
- return err;
|
||||
- }
|
||||
+ if (EFI_ERROR(err))
|
||||
+ return log_error_status_stall(err, L"Failed to flush random seed file: %r", err);
|
||||
|
||||
/* We are good to go */
|
||||
err = efivar_set_raw(LOADER_GUID, L"LoaderRandomSeed", for_kernel, size, 0);
|
||||
- if (EFI_ERROR(err)) {
|
||||
- Print(L"Failed to write random seed to EFI variable: %r\n", err);
|
||||
- return err;
|
||||
- }
|
||||
+ if (EFI_ERROR(err))
|
||||
+ return log_error_status_stall(err, L"Failed to write random seed to EFI variable: %r", err);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c
|
||||
index 082fe91c9e..82da1d3ec4 100644
|
||||
--- a/src/boot/efi/stub.c
|
||||
+++ b/src/boot/efi/stub.c
|
||||
@@ -36,18 +36,12 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
|
||||
err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image,
|
||||
image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
- if (EFI_ERROR(err)) {
|
||||
- Print(L"Error getting a LoadedImageProtocol handle: %r ", err);
|
||||
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
- return err;
|
||||
- }
|
||||
+ if (EFI_ERROR(err))
|
||||
+ return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err);
|
||||
|
||||
err = pe_memory_locate_sections(loaded_image->ImageBase, sections, addrs, offs, szs);
|
||||
- if (EFI_ERROR(err)) {
|
||||
- Print(L"Unable to locate embedded .linux section: %r ", err);
|
||||
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
- return err;
|
||||
- }
|
||||
+ if (EFI_ERROR(err))
|
||||
+ return log_error_status_stall(err, L"Unable to locate embedded .linux section: %r", err);
|
||||
|
||||
if (szs[0] > 0)
|
||||
cmdline = (CHAR8 *)(loaded_image->ImageBase) + addrs[0];
|
||||
@@ -72,10 +66,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
err = tpm_log_event(SD_TPM_PCR,
|
||||
(EFI_PHYSICAL_ADDRESS) (UINTN) loaded_image->LoadOptions,
|
||||
loaded_image->LoadOptionsSize, loaded_image->LoadOptions);
|
||||
- if (EFI_ERROR(err)) {
|
||||
- Print(L"Unable to add image options measurement: %r", err);
|
||||
- uefi_call_wrapper(BS->Stall, 1, 200 * 1000);
|
||||
- }
|
||||
+ if (EFI_ERROR(err))
|
||||
+ log_error_stall(L"Unable to add image options measurement: %r", err);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -126,7 +118,5 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
(UINTN)loaded_image->ImageBase + addrs[2], szs[2]);
|
||||
|
||||
graphics_mode(FALSE);
|
||||
- Print(L"Execution of embedded linux image failed: %r\n", err);
|
||||
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
- return err;
|
||||
+ return log_error_status_stall(err, L"Execution of embedded linux image failed: %r", err);
|
||||
}
|
||||
diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c
|
||||
index 6f4e5933d3..aee076060b 100644
|
||||
--- a/src/boot/efi/util.c
|
||||
+++ b/src/boot/efi/util.c
|
||||
@@ -411,8 +411,21 @@ EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN s
|
||||
return err;
|
||||
}
|
||||
|
||||
+VOID log_error_stall(const CHAR16 *fmt, ...) {
|
||||
+ va_list args;
|
||||
+
|
||||
+ uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, EFI_LIGHTRED|EFI_BACKGROUND_BLACK);
|
||||
+
|
||||
+ Print(L"\n");
|
||||
+ va_start(args, fmt);
|
||||
+ VPrint(fmt, args);
|
||||
+ va_end(args);
|
||||
+ Print(L"\n");
|
||||
+
|
||||
+ uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
+}
|
||||
+
|
||||
EFI_STATUS log_oom(void) {
|
||||
- Print(L"Out of memory.");
|
||||
- (void) uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
+ log_error_stall(L"Out of memory.");
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h
|
||||
index 1a42b01033..d3bf848a95 100644
|
||||
--- a/src/boot/efi/util.h
|
||||
+++ b/src/boot/efi/util.h
|
||||
@@ -74,4 +74,13 @@ static inline void FileHandleClosep(EFI_FILE_HANDLE *handle) {
|
||||
#define UINT64_MAX ((UINT64) -1)
|
||||
#endif
|
||||
|
||||
+VOID log_error_stall(const CHAR16 *fmt, ...);
|
||||
EFI_STATUS log_oom(void);
|
||||
+
|
||||
+/* This works just like log_error_errno() from userspace, but requires you
|
||||
+ * to provide err a second time if you want to use %r in the message! */
|
||||
+#define log_error_status_stall(err, fmt, ...) \
|
||||
+ ({ \
|
||||
+ log_error_stall(fmt, ##__VA_ARGS__); \
|
||||
+ err; \
|
||||
+ })
|
||||
--
|
||||
2.33.0
|
||||
|
@ -0,0 +1,320 @@
|
||||
From 2d9fcfcfa38667ada306e095599944f941576e53 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Janssen <medhefgo@web.de>
|
||||
Date: Wed, 11 Aug 2021 14:59:46 +0200
|
||||
Subject: [PATCH 21/21] sd-boot: Rework console input handling
|
||||
|
||||
Fixes: #15847
|
||||
Probably fixes: #19191
|
||||
|
||||
(cherry picked from commit e98d271e57f3d0356e444b6ea2d48836ee2769b0)
|
||||
---
|
||||
src/boot/efi/boot.c | 55 +++++++---------------
|
||||
src/boot/efi/console.c | 102 +++++++++++++++++++++++++++++------------
|
||||
src/boot/efi/console.h | 2 +-
|
||||
3 files changed, 91 insertions(+), 68 deletions(-)
|
||||
|
||||
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
|
||||
index 54d704f0d1..b4f3b9605a 100644
|
||||
--- a/src/boot/efi/boot.c
|
||||
+++ b/src/boot/efi/boot.c
|
||||
@@ -134,7 +134,7 @@ static BOOLEAN line_edit(
|
||||
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, print);
|
||||
uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, cursor, y_pos);
|
||||
|
||||
- err = console_key_read(&key, TRUE);
|
||||
+ err = console_key_read(&key, 0);
|
||||
if (EFI_ERROR(err))
|
||||
continue;
|
||||
|
||||
@@ -387,7 +387,7 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
|
||||
Print(L"OsIndicationsSupported: %d\n", indvar);
|
||||
|
||||
Print(L"\n--- press key ---\n\n");
|
||||
- console_key_read(&key, TRUE);
|
||||
+ console_key_read(&key, 0);
|
||||
|
||||
Print(L"timeout: %u\n", config->timeout_sec);
|
||||
if (config->timeout_sec_efivar >= 0)
|
||||
@@ -432,7 +432,7 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
|
||||
Print(L"LoaderEntryDefault: %s\n", defaultstr);
|
||||
|
||||
Print(L"\n--- press key ---\n\n");
|
||||
- console_key_read(&key, TRUE);
|
||||
+ console_key_read(&key, 0);
|
||||
|
||||
for (UINTN i = 0; i < config->entry_count; i++) {
|
||||
ConfigEntry *entry;
|
||||
@@ -482,7 +482,7 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
|
||||
entry->path, entry->next_name);
|
||||
|
||||
Print(L"\n--- press key ---\n\n");
|
||||
- console_key_read(&key, TRUE);
|
||||
+ console_key_read(&key, 0);
|
||||
}
|
||||
|
||||
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||||
@@ -509,11 +509,10 @@ static BOOLEAN menu_run(
|
||||
UINTN y_max;
|
||||
CHAR16 *status;
|
||||
CHAR16 *clearline;
|
||||
- INTN timeout_remain;
|
||||
+ UINTN timeout_remain = config->timeout_sec;
|
||||
INT16 idx;
|
||||
BOOLEAN exit = FALSE;
|
||||
BOOLEAN run = TRUE;
|
||||
- BOOLEAN wait = FALSE;
|
||||
|
||||
graphics_mode(FALSE);
|
||||
uefi_call_wrapper(ST->ConIn->Reset, 2, ST->ConIn, FALSE);
|
||||
@@ -538,12 +537,6 @@ static BOOLEAN menu_run(
|
||||
y_max = 25;
|
||||
}
|
||||
|
||||
- /* we check 10 times per second for a keystroke */
|
||||
- if (config->timeout_sec > 0)
|
||||
- timeout_remain = config->timeout_sec * 10;
|
||||
- else
|
||||
- timeout_remain = -1;
|
||||
-
|
||||
idx_highlight = config->idx_default;
|
||||
idx_highlight_prev = 0;
|
||||
|
||||
@@ -643,7 +636,7 @@ static BOOLEAN menu_run(
|
||||
|
||||
if (timeout_remain > 0) {
|
||||
FreePool(status);
|
||||
- status = PoolPrint(L"Boot in %d sec.", (timeout_remain + 5) / 10);
|
||||
+ status = PoolPrint(L"Boot in %d s.", timeout_remain);
|
||||
}
|
||||
|
||||
/* print status at last line of screen */
|
||||
@@ -664,27 +657,18 @@ static BOOLEAN menu_run(
|
||||
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, clearline+1 + x + len);
|
||||
}
|
||||
|
||||
- err = console_key_read(&key, wait);
|
||||
- if (EFI_ERROR(err)) {
|
||||
- /* timeout reached */
|
||||
+ err = console_key_read(&key, timeout_remain > 0 ? 1000 * 1000 : 0);
|
||||
+ if (err == EFI_TIMEOUT) {
|
||||
+ timeout_remain--;
|
||||
if (timeout_remain == 0) {
|
||||
exit = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
- /* sleep and update status */
|
||||
- if (timeout_remain > 0) {
|
||||
- uefi_call_wrapper(BS->Stall, 1, 100 * 1000);
|
||||
- timeout_remain--;
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- /* timeout disabled, wait for next key */
|
||||
- wait = TRUE;
|
||||
+ /* update status */
|
||||
continue;
|
||||
- }
|
||||
-
|
||||
- timeout_remain = -1;
|
||||
+ } else
|
||||
+ timeout_remain = 0;
|
||||
|
||||
/* clear status after keystroke */
|
||||
if (status) {
|
||||
@@ -787,7 +771,7 @@ static BOOLEAN menu_run(
|
||||
config->timeout_sec_efivar,
|
||||
EFI_VARIABLE_NON_VOLATILE);
|
||||
if (config->timeout_sec_efivar > 0)
|
||||
- status = PoolPrint(L"Menu timeout set to %d sec.", config->timeout_sec_efivar);
|
||||
+ status = PoolPrint(L"Menu timeout set to %d s.", config->timeout_sec_efivar);
|
||||
else
|
||||
status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
|
||||
} else if (config->timeout_sec_efivar <= 0){
|
||||
@@ -795,7 +779,7 @@ static BOOLEAN menu_run(
|
||||
efivar_set(
|
||||
LOADER_GUID, L"LoaderConfigTimeout", NULL, EFI_VARIABLE_NON_VOLATILE);
|
||||
if (config->timeout_sec_config > 0)
|
||||
- status = PoolPrint(L"Menu timeout of %d sec is defined by configuration file.",
|
||||
+ status = PoolPrint(L"Menu timeout of %d s is defined by configuration file.",
|
||||
config->timeout_sec_config);
|
||||
else
|
||||
status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
|
||||
@@ -813,7 +797,7 @@ static BOOLEAN menu_run(
|
||||
config->timeout_sec_efivar,
|
||||
EFI_VARIABLE_NON_VOLATILE);
|
||||
if (config->timeout_sec_efivar > 0)
|
||||
- status = PoolPrint(L"Menu timeout set to %d sec.",
|
||||
+ status = PoolPrint(L"Menu timeout set to %d s.",
|
||||
config->timeout_sec_efivar);
|
||||
else
|
||||
status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
|
||||
@@ -2369,13 +2353,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
else {
|
||||
UINT64 key;
|
||||
|
||||
- err = console_key_read(&key, FALSE);
|
||||
-
|
||||
- if (err == EFI_NOT_READY) {
|
||||
- uefi_call_wrapper(BS->Stall, 1, 100 * 1000);
|
||||
- err = console_key_read(&key, FALSE);
|
||||
- }
|
||||
-
|
||||
+ /* Block up to 100ms to give firmware time to get input working. */
|
||||
+ err = console_key_read(&key, 100 * 1000);
|
||||
if (!EFI_ERROR(err)) {
|
||||
INT16 idx;
|
||||
|
||||
diff --git a/src/boot/efi/console.c b/src/boot/efi/console.c
|
||||
index 83619d2147..369c549daf 100644
|
||||
--- a/src/boot/efi/console.c
|
||||
+++ b/src/boot/efi/console.c
|
||||
@@ -11,61 +11,105 @@
|
||||
|
||||
#define EFI_SIMPLE_TEXT_INPUT_EX_GUID &(EFI_GUID) EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID
|
||||
|
||||
-EFI_STATUS console_key_read(UINT64 *key, BOOLEAN wait) {
|
||||
+static inline void EventClosep(EFI_EVENT *event) {
|
||||
+ if (!*event)
|
||||
+ return;
|
||||
+
|
||||
+ uefi_call_wrapper(BS->CloseEvent, 1, *event);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Reading input from the console sounds like an easy task to do, but thanks to broken
|
||||
+ * firmware it is actually a nightmare.
|
||||
+ *
|
||||
+ * There is a ConIn and TextInputEx API for this. Ideally we want to use TextInputEx,
|
||||
+ * because that gives us Ctrl/Alt/Shift key state information. Unfortunately, it is not
|
||||
+ * always available and sometimes just non-functional.
|
||||
+ *
|
||||
+ * On the other hand we have ConIn, where some firmware likes to just freeze on us
|
||||
+ * if we call ReadKeyStroke on it.
|
||||
+ *
|
||||
+ * Therefore, we use WaitForEvent on both ConIn and TextInputEx (if available) along
|
||||
+ * with a timer event. The timer ensures there is no need to call into functions
|
||||
+ * that might freeze on us, while still allowing us to show a timeout counter.
|
||||
+ */
|
||||
+EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) {
|
||||
static EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInputEx;
|
||||
static BOOLEAN checked;
|
||||
UINTN index;
|
||||
EFI_INPUT_KEY k;
|
||||
EFI_STATUS err;
|
||||
+ _cleanup_(EventClosep) EFI_EVENT timer = NULL;
|
||||
+ EFI_EVENT events[3] = { ST->ConIn->WaitForKey };
|
||||
+ UINTN n_events = 1;
|
||||
|
||||
if (!checked) {
|
||||
err = LibLocateProtocol(EFI_SIMPLE_TEXT_INPUT_EX_GUID, (VOID **)&TextInputEx);
|
||||
- if (EFI_ERROR(err))
|
||||
+ if (EFI_ERROR(err) ||
|
||||
+ uefi_call_wrapper(BS->CheckEvent, 1, TextInputEx->WaitForKeyEx) == EFI_INVALID_PARAMETER)
|
||||
+ /* If WaitForKeyEx fails here, the firmware pretends it talks this
|
||||
+ * protocol, but it really doesn't. */
|
||||
TextInputEx = NULL;
|
||||
+ else
|
||||
+ events[n_events++] = TextInputEx->WaitForKeyEx;
|
||||
|
||||
checked = TRUE;
|
||||
}
|
||||
|
||||
- /* wait until key is pressed */
|
||||
- if (wait)
|
||||
- uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &index);
|
||||
+ if (timeout_usec > 0) {
|
||||
+ err = uefi_call_wrapper(BS->CreateEvent, 5, EVT_TIMER, 0, NULL, NULL, &timer);
|
||||
+ if (EFI_ERROR(err))
|
||||
+ return log_error_status_stall(err, L"Error creating timer event: %r", err);
|
||||
+
|
||||
+ /* SetTimer expects 100ns units for some reason. */
|
||||
+ err = uefi_call_wrapper(BS->SetTimer, 3, timer, TimerRelative, timeout_usec * 10);
|
||||
+ if (EFI_ERROR(err))
|
||||
+ return log_error_status_stall(err, L"Error arming timer event: %r", err);
|
||||
|
||||
- if (TextInputEx) {
|
||||
+ events[n_events++] = timer;
|
||||
+ }
|
||||
+
|
||||
+ err = uefi_call_wrapper(BS->WaitForEvent, 3, n_events, events, &index);
|
||||
+ if (EFI_ERROR(err))
|
||||
+ return log_error_status_stall(err, L"Error waiting for events: %r", err);
|
||||
+
|
||||
+ if (timeout_usec > 0 && timer == events[index])
|
||||
+ return EFI_TIMEOUT;
|
||||
+
|
||||
+ /* TextInputEx might be ready too even if ConIn got to signal first. */
|
||||
+ if (TextInputEx && !EFI_ERROR(uefi_call_wrapper(BS->CheckEvent, 1, TextInputEx->WaitForKeyEx))) {
|
||||
EFI_KEY_DATA keydata;
|
||||
UINT64 keypress;
|
||||
+ UINT32 shift = 0;
|
||||
|
||||
err = uefi_call_wrapper(TextInputEx->ReadKeyStrokeEx, 2, TextInputEx, &keydata);
|
||||
- if (!EFI_ERROR(err)) {
|
||||
- UINT32 shift = 0;
|
||||
-
|
||||
- /* do not distinguish between left and right keys */
|
||||
- if (keydata.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) {
|
||||
- if (keydata.KeyState.KeyShiftState & (EFI_RIGHT_CONTROL_PRESSED|EFI_LEFT_CONTROL_PRESSED))
|
||||
- shift |= EFI_CONTROL_PRESSED;
|
||||
- if (keydata.KeyState.KeyShiftState & (EFI_RIGHT_ALT_PRESSED|EFI_LEFT_ALT_PRESSED))
|
||||
- shift |= EFI_ALT_PRESSED;
|
||||
- };
|
||||
-
|
||||
- /* 32 bit modifier keys + 16 bit scan code + 16 bit unicode */
|
||||
- keypress = KEYPRESS(shift, keydata.Key.ScanCode, keydata.Key.UnicodeChar);
|
||||
- if (keypress > 0) {
|
||||
- *key = keypress;
|
||||
- return 0;
|
||||
- }
|
||||
+ if (EFI_ERROR(err))
|
||||
+ return err;
|
||||
+
|
||||
+ /* do not distinguish between left and right keys */
|
||||
+ if (keydata.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) {
|
||||
+ if (keydata.KeyState.KeyShiftState & (EFI_RIGHT_CONTROL_PRESSED|EFI_LEFT_CONTROL_PRESSED))
|
||||
+ shift |= EFI_CONTROL_PRESSED;
|
||||
+ if (keydata.KeyState.KeyShiftState & (EFI_RIGHT_ALT_PRESSED|EFI_LEFT_ALT_PRESSED))
|
||||
+ shift |= EFI_ALT_PRESSED;
|
||||
+ };
|
||||
+
|
||||
+ /* 32 bit modifier keys + 16 bit scan code + 16 bit unicode */
|
||||
+ keypress = KEYPRESS(shift, keydata.Key.ScanCode, keydata.Key.UnicodeChar);
|
||||
+ if (keypress > 0) {
|
||||
+ *key = keypress;
|
||||
+ return EFI_SUCCESS;
|
||||
}
|
||||
+
|
||||
+ return EFI_NOT_READY;
|
||||
}
|
||||
|
||||
- /* fallback for firmware which does not support SimpleTextInputExProtocol
|
||||
- *
|
||||
- * This is also called in case ReadKeyStrokeEx did not return a key, because
|
||||
- * some broken firmwares offer SimpleTextInputExProtocol, but never actually
|
||||
- * handle any key. */
|
||||
err = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &k);
|
||||
if (EFI_ERROR(err))
|
||||
return err;
|
||||
|
||||
*key = KEYPRESS(0, k.ScanCode, k.UnicodeChar);
|
||||
- return 0;
|
||||
+ return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static EFI_STATUS change_mode(UINTN mode) {
|
||||
diff --git a/src/boot/efi/console.h b/src/boot/efi/console.h
|
||||
index 2c69af552a..23848a9c58 100644
|
||||
--- a/src/boot/efi/console.h
|
||||
+++ b/src/boot/efi/console.h
|
||||
@@ -16,5 +16,5 @@ enum console_mode_change_type {
|
||||
CONSOLE_MODE_MAX,
|
||||
};
|
||||
|
||||
-EFI_STATUS console_key_read(UINT64 *key, BOOLEAN wait);
|
||||
+EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec);
|
||||
EFI_STATUS console_set_mode(UINTN *mode, enum console_mode_change_type how);
|
||||
--
|
||||
2.33.0
|
||||
|
@ -164,6 +164,14 @@ stdenv.mkDerivation {
|
||||
# all our root unit dirs if they are symlinks. This does exactly what we
|
||||
# need (AFAICT).
|
||||
./0019-core-handle-lookup-paths-being-symlinks.patch
|
||||
|
||||
# In v248 compiler weirdness and refactoring lead to the bootloader
|
||||
# erroring out handling keyboard input on some systems. See
|
||||
# https://github.com/systemd/systemd/issues/19191
|
||||
# This should be redundant in v249.6 when it offically gets tagged in
|
||||
# systemd-stable
|
||||
./0020-sd-boot-Unify-error-handling.patch
|
||||
./0021-sd-boot-Rework-console-input-handling.patch
|
||||
] ++ lib.optional stdenv.hostPlatform.isMusl (let
|
||||
oe-core = fetchzip {
|
||||
url = "https://git.openembedded.org/openembedded-core/snapshot/openembedded-core-14c6e5a4b72d0e4665279158a0740dd1dc21f72f.tar.bz2";
|
||||
|
Loading…
Reference in New Issue
Block a user