diff --git a/pkgs/os-specific/linux/systemd/0001-Start-device-units-for-uninitialised-encrypted-devic.patch b/pkgs/os-specific/linux/systemd/0001-Start-device-units-for-uninitialised-encrypted-devic.patch index dc7f2a2868e6..ac95dc745fe1 100644 --- a/pkgs/os-specific/linux/systemd/0001-Start-device-units-for-uninitialised-encrypted-devic.patch +++ b/pkgs/os-specific/linux/systemd/0001-Start-device-units-for-uninitialised-encrypted-devic.patch @@ -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 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 diff --git a/pkgs/os-specific/linux/systemd/0002-Don-t-try-to-unmount-nix-or-nix-store.patch b/pkgs/os-specific/linux/systemd/0002-Don-t-try-to-unmount-nix-or-nix-store.patch index 51e934ef9831..dd351c001006 100644 --- a/pkgs/os-specific/linux/systemd/0002-Don-t-try-to-unmount-nix-or-nix-store.patch +++ b/pkgs/os-specific/linux/systemd/0002-Don-t-try-to-unmount-nix-or-nix-store.patch @@ -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 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. diff --git a/pkgs/os-specific/linux/systemd/0003-Fix-NixOS-containers.patch b/pkgs/os-specific/linux/systemd/0003-Fix-NixOS-containers.patch index 194b3f5418a9..2dd3d87f6ed2 100644 --- a/pkgs/os-specific/linux/systemd/0003-Fix-NixOS-containers.patch +++ b/pkgs/os-specific/linux/systemd/0003-Fix-NixOS-containers.patch @@ -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 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. diff --git a/pkgs/os-specific/linux/systemd/0004-Look-for-fsck-in-the-right-place.patch b/pkgs/os-specific/linux/systemd/0004-Look-for-fsck-in-the-right-place.patch index 210382d92597..54d9ff93b43b 100644 --- a/pkgs/os-specific/linux/systemd/0004-Look-for-fsck-in-the-right-place.patch +++ b/pkgs/os-specific/linux/systemd/0004-Look-for-fsck-in-the-right-place.patch @@ -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 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 +- diff --git a/pkgs/os-specific/linux/systemd/0005-Add-some-NixOS-specific-unit-directories.patch b/pkgs/os-specific/linux/systemd/0005-Add-some-NixOS-specific-unit-directories.patch index ba105424f6c8..ee878b410f04 100644 --- a/pkgs/os-specific/linux/systemd/0005-Add-some-NixOS-specific-unit-directories.patch +++ b/pkgs/os-specific/linux/systemd/0005-Add-some-NixOS-specific-unit-directories.patch @@ -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 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 diff --git a/pkgs/os-specific/linux/systemd/0006-Get-rid-of-a-useless-message-in-user-sessions.patch b/pkgs/os-specific/linux/systemd/0006-Get-rid-of-a-useless-message-in-user-sessions.patch index c136bd8f4c80..482eeacb0218 100644 --- a/pkgs/os-specific/linux/systemd/0006-Get-rid-of-a-useless-message-in-user-sessions.patch +++ b/pkgs/os-specific/linux/systemd/0006-Get-rid-of-a-useless-message-in-user-sessions.patch @@ -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 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 diff --git a/pkgs/os-specific/linux/systemd/0007-hostnamed-localed-timedated-disable-methods-that-cha.patch b/pkgs/os-specific/linux/systemd/0007-hostnamed-localed-timedated-disable-methods-that-cha.patch index 4f9f98ec8b35..22e4c74d08d7 100644 --- a/pkgs/os-specific/linux/systemd/0007-hostnamed-localed-timedated-disable-methods-that-cha.patch +++ b/pkgs/os-specific/linux/systemd/0007-hostnamed-localed-timedated-disable-methods-that-cha.patch @@ -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 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. --- diff --git a/pkgs/os-specific/linux/systemd/0008-Fix-hwdb-paths.patch b/pkgs/os-specific/linux/systemd/0008-Fix-hwdb-paths.patch index 4ef72f0dccf6..e5a0bf7d97fa 100644 --- a/pkgs/os-specific/linux/systemd/0008-Fix-hwdb-paths.patch +++ b/pkgs/os-specific/linux/systemd/0008-Fix-hwdb-paths.patch @@ -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 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. --- diff --git a/pkgs/os-specific/linux/systemd/0009-Change-usr-share-zoneinfo-to-etc-zoneinfo.patch b/pkgs/os-specific/linux/systemd/0009-Change-usr-share-zoneinfo-to-etc-zoneinfo.patch index 78ebcb50fccd..9e22ea719e35 100644 --- a/pkgs/os-specific/linux/systemd/0009-Change-usr-share-zoneinfo-to-etc-zoneinfo.patch +++ b/pkgs/os-specific/linux/systemd/0009-Change-usr-share-zoneinfo-to-etc-zoneinfo.patch @@ -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 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. --- diff --git a/pkgs/os-specific/linux/systemd/0010-localectl-use-etc-X11-xkb-for-list-x11.patch b/pkgs/os-specific/linux/systemd/0010-localectl-use-etc-X11-xkb-for-list-x11.patch index a956cceff550..ce0ad7e4ddc3 100644 --- a/pkgs/os-specific/linux/systemd/0010-localectl-use-etc-X11-xkb-for-list-x11.patch +++ b/pkgs/os-specific/linux/systemd/0010-localectl-use-etc-X11-xkb-for-list-x11.patch @@ -1,7 +1,7 @@ -From fbb302d00c63dc17a210f83648f24a1da983b2c0 Mon Sep 17 00:00:00 2001 +From 75d12cf65073458f091899d673c613dfc43f60c0 Mon Sep 17 00:00:00 2001 From: Imuli 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. diff --git a/pkgs/os-specific/linux/systemd/0011-build-don-t-create-statedir-and-don-t-touch-prefixdi.patch b/pkgs/os-specific/linux/systemd/0011-build-don-t-create-statedir-and-don-t-touch-prefixdi.patch index 6b482eb8c9d7..a03c5a14ad89 100644 --- a/pkgs/os-specific/linux/systemd/0011-build-don-t-create-statedir-and-don-t-touch-prefixdi.patch +++ b/pkgs/os-specific/linux/systemd/0011-build-don-t-create-statedir-and-don-t-touch-prefixdi.patch @@ -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 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 --- diff --git a/pkgs/os-specific/linux/systemd/0012-inherit-systemd-environment-when-calling-generators.patch b/pkgs/os-specific/linux/systemd/0012-inherit-systemd-environment-when-calling-generators.patch index ffe7b7467f50..0576f7a62f2c 100644 --- a/pkgs/os-specific/linux/systemd/0012-inherit-systemd-environment-when-calling-generators.patch +++ b/pkgs/os-specific/linux/systemd/0012-inherit-systemd-environment-when-calling-generators.patch @@ -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 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 diff --git a/pkgs/os-specific/linux/systemd/0013-add-rootprefix-to-lookup-dir-paths.patch b/pkgs/os-specific/linux/systemd/0013-add-rootprefix-to-lookup-dir-paths.patch index 086a20cabceb..a424cf1061cc 100644 --- a/pkgs/os-specific/linux/systemd/0013-add-rootprefix-to-lookup-dir-paths.patch +++ b/pkgs/os-specific/linux/systemd/0013-add-rootprefix-to-lookup-dir-paths.patch @@ -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 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 diff --git a/pkgs/os-specific/linux/systemd/0014-systemd-shutdown-execute-scripts-in-etc-systemd-syst.patch b/pkgs/os-specific/linux/systemd/0014-systemd-shutdown-execute-scripts-in-etc-systemd-syst.patch index b3fafabb515e..5610d4d3ecc6 100644 --- a/pkgs/os-specific/linux/systemd/0014-systemd-shutdown-execute-scripts-in-etc-systemd-syst.patch +++ b/pkgs/os-specific/linux/systemd/0014-systemd-shutdown-execute-scripts-in-etc-systemd-syst.patch @@ -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 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. diff --git a/pkgs/os-specific/linux/systemd/0015-systemd-sleep-execute-scripts-in-etc-systemd-system-.patch b/pkgs/os-specific/linux/systemd/0015-systemd-sleep-execute-scripts-in-etc-systemd-system-.patch index ac40b8c1e258..11848a623a32 100644 --- a/pkgs/os-specific/linux/systemd/0015-systemd-sleep-execute-scripts-in-etc-systemd-system-.patch +++ b/pkgs/os-specific/linux/systemd/0015-systemd-sleep-execute-scripts-in-etc-systemd-system-.patch @@ -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 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. diff --git a/pkgs/os-specific/linux/systemd/0016-kmod-static-nodes.service-Update-ConditionFileNotEmp.patch b/pkgs/os-specific/linux/systemd/0016-kmod-static-nodes.service-Update-ConditionFileNotEmp.patch index 26e586c00af8..156195d9a900 100644 --- a/pkgs/os-specific/linux/systemd/0016-kmod-static-nodes.service-Update-ConditionFileNotEmp.patch +++ b/pkgs/os-specific/linux/systemd/0016-kmod-static-nodes.service-Update-ConditionFileNotEmp.patch @@ -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 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/. diff --git a/pkgs/os-specific/linux/systemd/0017-path-util.h-add-placeholder-for-DEFAULT_PATH_NORMAL.patch b/pkgs/os-specific/linux/systemd/0017-path-util.h-add-placeholder-for-DEFAULT_PATH_NORMAL.patch index a47c6f51836e..1f21b628e923 100644 --- a/pkgs/os-specific/linux/systemd/0017-path-util.h-add-placeholder-for-DEFAULT_PATH_NORMAL.patch +++ b/pkgs/os-specific/linux/systemd/0017-path-util.h-add-placeholder-for-DEFAULT_PATH_NORMAL.patch @@ -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 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. diff --git a/pkgs/os-specific/linux/systemd/0018-pkg-config-derive-prefix-from-prefix.patch b/pkgs/os-specific/linux/systemd/0018-pkg-config-derive-prefix-from-prefix.patch index 3939a2ba15e0..344b8b3952ff 100644 --- a/pkgs/os-specific/linux/systemd/0018-pkg-config-derive-prefix-from-prefix.patch +++ b/pkgs/os-specific/linux/systemd/0018-pkg-config-derive-prefix-from-prefix.patch @@ -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?= 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 diff --git a/pkgs/os-specific/linux/systemd/0019-core-handle-lookup-paths-being-symlinks.patch b/pkgs/os-specific/linux/systemd/0019-core-handle-lookup-paths-being-symlinks.patch index 5820e7605c45..4f950650d320 100644 --- a/pkgs/os-specific/linux/systemd/0019-core-handle-lookup-paths-being-symlinks.patch +++ b/pkgs/os-specific/linux/systemd/0019-core-handle-lookup-paths-being-symlinks.patch @@ -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 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 diff --git a/pkgs/os-specific/linux/systemd/0020-sd-boot-Unify-error-handling.patch b/pkgs/os-specific/linux/systemd/0020-sd-boot-Unify-error-handling.patch new file mode 100644 index 000000000000..5c82cdbd6fab --- /dev/null +++ b/pkgs/os-specific/linux/systemd/0020-sd-boot-Unify-error-handling.patch @@ -0,0 +1,401 @@ +From 3cf1b5fb6d1dc342e836cf0990df3170d2e9db49 Mon Sep 17 00:00:00 2001 +From: Jan Janssen +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 + diff --git a/pkgs/os-specific/linux/systemd/0021-sd-boot-Rework-console-input-handling.patch b/pkgs/os-specific/linux/systemd/0021-sd-boot-Rework-console-input-handling.patch new file mode 100644 index 000000000000..7cdc2491fa33 --- /dev/null +++ b/pkgs/os-specific/linux/systemd/0021-sd-boot-Rework-console-input-handling.patch @@ -0,0 +1,320 @@ +From 2d9fcfcfa38667ada306e095599944f941576e53 Mon Sep 17 00:00:00 2001 +From: Jan Janssen +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 + diff --git a/pkgs/os-specific/linux/systemd/default.nix b/pkgs/os-specific/linux/systemd/default.nix index 036ea991ef6a..aa106ca1abaa 100644 --- a/pkgs/os-specific/linux/systemd/default.nix +++ b/pkgs/os-specific/linux/systemd/default.nix @@ -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";