third_party/efistub: update to use PE entry point
The old efistub used the EFI handover mechanism, which only exists for
x86_64. Since Linux 5.8 x86_64 also supports the standard PE entry point
which works the same for all supported architectures. That also has the
benefit of no longer needing a weird hack to switch to SysV ABI to call
into the kernel.
Change-Id: Icd75599758e09d888a31c31f07967dfc78356fca
Reviewed-on: https://review.monogon.dev/c/monogon/+/4213
Tested-by: Jenkins CI
Reviewed-by: Tim Windelschmidt <tim@monogon.tech>
diff --git a/build/bazel/third_party.MODULE.bazel b/build/bazel/third_party.MODULE.bazel
index d218d2f..e58b8f3 100644
--- a/build/bazel/third_party.MODULE.bazel
+++ b/build/bazel/third_party.MODULE.bazel
@@ -279,16 +279,15 @@
# Developed in the systemd monorepo, pinned to master as there have been a bunch of critical fixes for the
# EFI stub since 249.
-EFISTUB_VERSION = "3542da2442d8b29661b47c42ad7e5fa9bc8562ec"
+EFISTUB_VERSION = "927ebebe588970fa2dd082a0daaef246229f009b"
http_archive(
name = "efistub",
build_file = "//third_party/efistub:efistub.bzl",
- integrity = "sha256-AhwTW+45ynNG0fCZI758BEo9NYZv9BGnyWJnAv9MlSM=",
+ integrity = "sha256-Epun4Cq5/ThCDKFoqFZaI+0Xb5wq+B0JMSkx3VsHR+0=",
patch_args = ["-p1"],
patches = [
- "//third_party/efistub/patches:use-sysv-for-kernel.patch",
- "//third_party/efistub/patches:remove-wrong-cmdline-assertion.patch",
+ "//third_party/efistub/patches:use-local-uchar.patch",
"//third_party/efistub/patches:ab-slot-handling.patch",
],
strip_prefix = "systemd-%s" % EFISTUB_VERSION,
diff --git a/third_party/efistub/efistub.bzl b/third_party/efistub/efistub.bzl
index d0e2a2f..5dc9696 100644
--- a/third_party/efistub/efistub.bzl
+++ b/third_party/efistub/efistub.bzl
@@ -8,16 +8,22 @@
"cpio.c",
"disk.c",
"graphics.c",
+ "console.c",
+ "devicetree.c",
"linux.c",
+ "linux_x86.c",
+ "initrd.c",
"measure.c",
+ "ticks.c",
"pe.c",
"secure-boot.c",
"splash.c",
"stub.c",
+ "efi-string.c",
"util.c",
]] + glob(["src/boot/efi/*.h", "src/fundamental/*.c", "src/fundamental/*.h"]),
- includes = ["src/fundamental"],
- copts = ["-std=gnu99", "-DSD_BOOT", "-DGIT_VERSION=\\\"0.0.0-mngn\\\""],
+ includes = ["src/fundamental", "src/boot/efi"],
+ copts = ["-std=gnu11", "-O2", "-DSD_BOOT", "-DGIT_VERSION=\\\"0.0.0-mngn\\\""],
deps = ["@gnuefi//:gnuefi"],
target_compatible_with = [
"@platforms//os:uefi",
diff --git a/third_party/efistub/patches/ab-slot-handling.patch b/third_party/efistub/patches/ab-slot-handling.patch
index 0e5f369..60ee3ef 100644
--- a/third_party/efistub/patches/ab-slot-handling.patch
+++ b/third_party/efistub/patches/ab-slot-handling.patch
@@ -1,38 +1,38 @@
-From a8004bca64e697bf8f39af63c4325fbc9b507e48 Mon Sep 17 00:00:00 2001
+From 24a496c861fff6f8633453eedb92079976d3058f Mon Sep 17 00:00:00 2001
From: Lorenz Brun <lorenz@monogon.tech>
Date: Thu, 29 Jun 2023 03:54:01 +0200
-Subject: [PATCH] Implement filename-based A/B slot handling
+Subject: [PATCH 1/2] Implement filename-based A/B slot handling
---
src/boot/efi/stub.c | 66 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c
-index dad0f61335..88eda7e0e7 100644
+index 841a0e41bd..267ecbcc81 100644
--- a/src/boot/efi/stub.c
+++ b/src/boot/efi/stub.c
-@@ -5,6 +5,8 @@
-
+@@ -6,6 +6,8 @@
#include "cpio.h"
+ #include "devicetree.h"
#include "disk.h"
+#include "efibind.h"
+#include "efidevp.h"
#include "graphics.h"
#include "linux.h"
#include "measure.h"
-@@ -13,6 +15,31 @@
- #include "splash.h"
+@@ -15,6 +17,31 @@
+ #include "tpm-pcr.h"
#include "util.h"
+// From picolibc under BSD-3-Clause (c) 2018 Arm Ltd.
+/* Small and efficient strstr implementation. */
-+char * strstr (const char *hs, const char *ne)
++char16_t * strstr (const char16_t *hs, const char16_t *ne)
+{
+ UINTN i;
+ int c = ne[0];
+
+ if (c == 0)
-+ return (char*)hs;
++ return (char16_t*)hs;
+
+ for ( ; hs[0] != '\0'; hs++)
+ {
@@ -42,7 +42,7 @@
+ if (hs[i] != ne[i])
+ break;
+ if (ne[i] == '\0')
-+ return (char*)hs;
++ return (char16_t*)hs;
+ }
+
+ return NULL;
@@ -50,10 +50,10 @@
+
+
/* magic string to find in the binary image */
- static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-stub " GIT_VERSION " ####";
+ _used_ _section_(".sdmagic") static const char magic[] = "#### LoaderInfo: systemd-stub " GIT_VERSION " ####";
-@@ -180,6 +207,45 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
- cmdline_len = szs[SECTION_CMDLINE];
+@@ -232,6 +259,45 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
+ mangle_stub_cmdline(cmdline);
}
+ /* Extract last FILEPATH element from image path to check file name */
@@ -67,37 +67,37 @@
+ current_path_elem = NextDevicePathNode(current_path_elem);
+ }
+ /* Check slot based on suffix of the last FILE_PATH value */
-+ CHAR8 slot = 'A';
-+ const CHAR16 suffix_a[] = L"boot-a.efi";
-+ const CHAR16 suffix_b[] = L"boot-b.efi";
-+ const UINTN suffix_len = (sizeof(suffix_a)/sizeof(CHAR16))-1;
++ char16_t slot = 'A';
++ const char16_t suffix_a[] = u"boot-a.efi";
++ const char16_t suffix_b[] = u"boot-b.efi";
++ const UINTN suffix_len = (sizeof(suffix_a)/sizeof(char16_t))-1;
+ if (last_file_path != NULL) {
+ UINTN plen = StrLen(last_file_path);
+ if (suffix_len > plen) {
-+ // TODO: Log
-+ } else if (StriCmp(suffix_a, last_file_path + (plen-suffix_len)) == 0) {
++ Print(L"File name too short, blindly booting slot A\n");
++ } else if (StriCmp(suffix_a, &last_file_path[plen-suffix_len]) == 0){
+ slot = 'A';
-+ } else if (StriCmp(suffix_b, last_file_path + (plen-suffix_len)) == 0) {
++ } else if (StriCmp(suffix_b, &last_file_path[plen-suffix_len]) == 0) {
+ slot = 'B';
+ } else {
-+ // TODO: Log
++ Print(L"Unknown file name, blindly booting slot A\n");
+ }
+ }
+ Print(L"Booting into Slot %c\n", slot);
+ /* Replace METROPOLIS-SYSTEM-X with the correct slot */
-+ const char slot_identifier[] = "METROPOLIS-SYSTEM-X";
-+ const UINTN slot_id_len = (sizeof(slot_identifier)/sizeof(char))-1;
++ const char16_t slot_identifier[] = u"METROPOLIS-SYSTEM-X\0";
++ const UINTN slot_id_len = (sizeof(slot_identifier)/sizeof(char16_t))-1;
+ if (cmdline != NULL) {
-+ CHAR8 *rest_ptr = cmdline;
++ char16_t *rest_ptr = cmdline;
+ while((rest_ptr = strstr(rest_ptr, slot_identifier))) {
-+ rest_ptr[slot_id_len-1] = slot;
++ rest_ptr[slot_id_len-2] = slot;
+ rest_ptr += slot_id_len;
-+ }
++ }
+ }
+
- /* if we are not in secure boot mode, or none was provided, accept a custom command line and replace the built-in one */
- if ((!secure_boot_enabled() || cmdline_len == 0) && loaded_image->LoadOptionsSize > 0 &&
- *(CHAR16 *) loaded_image->LoadOptions > 0x1F) {
+ export_variables(loaded_image);
+
+ if (pack_cpio(loaded_image,
--
-2.40.1
+2.47.2
diff --git a/third_party/efistub/patches/use-local-uchar.patch b/third_party/efistub/patches/use-local-uchar.patch
new file mode 100644
index 0000000..a215619
--- /dev/null
+++ b/third_party/efistub/patches/use-local-uchar.patch
@@ -0,0 +1,212 @@
+From e14a6121d78dad23e3826499177353f9596ba0d7 Mon Sep 17 00:00:00 2001
+From: Lorenz Brun <lorenz@brun.one>
+Date: Thu, 22 May 2025 18:22:18 +0200
+Subject: [PATCH 2/2] Use local uchar.h
+
+---
+ src/boot/efi/bcd.h | 2 +-
+ src/boot/efi/cpio.c | 2 ++
+ src/boot/efi/cpio.h | 2 +-
+ src/boot/efi/devicetree.h | 2 +-
+ src/boot/efi/disk.h | 2 +-
+ src/boot/efi/efi-string.h | 2 +-
+ src/boot/efi/linux.h | 3 ++-
+ src/boot/efi/measure.h | 2 +-
+ src/boot/efi/pe.h | 2 +-
+ src/boot/efi/secure-boot.c | 2 +-
+ src/boot/efi/stub.c | 1 +
+ src/boot/efi/uchar.h | 6 ++++++
+ src/boot/efi/util.h | 2 +-
+ src/fundamental/efivars-fundamental.h | 3 +--
+ 14 files changed, 21 insertions(+), 12 deletions(-)
+ create mode 100644 src/boot/efi/uchar.h
+
+diff --git a/src/boot/efi/bcd.h b/src/boot/efi/bcd.h
+index c27af55c1e..17d79caf20 100644
+--- a/src/boot/efi/bcd.h
++++ b/src/boot/efi/bcd.h
+@@ -2,6 +2,6 @@
+ #pragma once
+
+ #include <stdint.h>
+-#include <uchar.h>
++#include "uchar.h"
+
+ char16_t *get_bcd_title(uint8_t *bcd, size_t bcd_len);
+diff --git a/src/boot/efi/cpio.c b/src/boot/efi/cpio.c
+index 76e2cd7f4e..5c2f68c2dc 100644
+--- a/src/boot/efi/cpio.c
++++ b/src/boot/efi/cpio.c
+@@ -1,5 +1,7 @@
+ /* SPDX-License-Identifier: LGPL-2.1-or-later */
+
++#include <stddef.h>
++
+ #include "cpio.h"
+ #include "measure.h"
+ #include "util.h"
+diff --git a/src/boot/efi/cpio.h b/src/boot/efi/cpio.h
+index beebef3d8b..90ed8cd025 100644
+--- a/src/boot/efi/cpio.h
++++ b/src/boot/efi/cpio.h
+@@ -3,7 +3,7 @@
+
+ #include <efi.h>
+ #include <stdbool.h>
+-#include <uchar.h>
++#include "uchar.h"
+
+ EFI_STATUS pack_cpio(
+ EFI_LOADED_IMAGE_PROTOCOL *loaded_image,
+diff --git a/src/boot/efi/devicetree.h b/src/boot/efi/devicetree.h
+index d512cb5037..f3c6de78ba 100644
+--- a/src/boot/efi/devicetree.h
++++ b/src/boot/efi/devicetree.h
+@@ -2,7 +2,7 @@
+ #pragma once
+
+ #include <efi.h>
+-#include <uchar.h>
++#include "uchar.h"
+
+ struct devicetree_state {
+ EFI_PHYSICAL_ADDRESS addr;
+diff --git a/src/boot/efi/disk.h b/src/boot/efi/disk.h
+index 1a5a18733e..6f6b517a16 100644
+--- a/src/boot/efi/disk.h
++++ b/src/boot/efi/disk.h
+@@ -2,6 +2,6 @@
+ #pragma once
+
+ #include <efi.h>
+-#include <uchar.h>
++#include "uchar.h"
+
+ EFI_STATUS disk_get_part_uuid(EFI_HANDLE *handle, char16_t uuid[static 37]);
+diff --git a/src/boot/efi/efi-string.h b/src/boot/efi/efi-string.h
+index e12add0b19..a6c8b0c56a 100644
+--- a/src/boot/efi/efi-string.h
++++ b/src/boot/efi/efi-string.h
+@@ -3,7 +3,7 @@
+
+ #include <stdbool.h>
+ #include <stddef.h>
+-#include <uchar.h>
++#include "uchar.h"
+
+ #include "macro-fundamental.h"
+
+diff --git a/src/boot/efi/linux.h b/src/boot/efi/linux.h
+index f0a6a37ed1..f1b7ff851f 100644
+--- a/src/boot/efi/linux.h
++++ b/src/boot/efi/linux.h
+@@ -2,7 +2,8 @@
+ #pragma once
+
+ #include <efi.h>
+-#include <uchar.h>
++#include "uchar.h"
++#include <stddef.h>
+
+ EFI_STATUS linux_exec(
+ EFI_HANDLE parent,
+diff --git a/src/boot/efi/measure.h b/src/boot/efi/measure.h
+index 19a50f47e7..9db41ab5ce 100644
+--- a/src/boot/efi/measure.h
++++ b/src/boot/efi/measure.h
+@@ -3,7 +3,7 @@
+
+ #include <efi.h>
+ #include <stdbool.h>
+-#include <uchar.h>
++#include "uchar.h"
+
+ #if ENABLE_TPM
+
+diff --git a/src/boot/efi/pe.h b/src/boot/efi/pe.h
+index ff7ff479ec..ef56cbbee9 100644
+--- a/src/boot/efi/pe.h
++++ b/src/boot/efi/pe.h
+@@ -2,7 +2,7 @@
+ #pragma once
+
+ #include <efidef.h>
+-#include <uchar.h>
++#include "uchar.h"
+
+ EFI_STATUS pe_memory_locate_sections(
+ const void *base,
+diff --git a/src/boot/efi/secure-boot.c b/src/boot/efi/secure-boot.c
+index 65457bf423..f65330f396 100644
+--- a/src/boot/efi/secure-boot.c
++++ b/src/boot/efi/secure-boot.c
+@@ -41,7 +41,7 @@ EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path) {
+
+ EFI_STATUS err;
+
+- clear_screen(COLOR_NORMAL);
++ //clear_screen(COLOR_NORMAL);
+
+ Print(L"Enrolling secure boot keys from directory: %s\n"
+ L"Warning: Enrolling custom Secure Boot keys might soft-brick your machine!\n",
+diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c
+index af80f17f81..f6b4cf060c 100644
+--- a/src/boot/efi/stub.c
++++ b/src/boot/efi/stub.c
+@@ -2,6 +2,7 @@
+
+ #include <efi.h>
+ #include <efilib.h>
++#include <stddef.h>
+
+ #include "cpio.h"
+ #include "devicetree.h"
+diff --git a/src/boot/efi/uchar.h b/src/boot/efi/uchar.h
+new file mode 100644
+index 0000000000..e4c0e6836b
+--- /dev/null
++++ b/src/boot/efi/uchar.h
+@@ -0,0 +1,6 @@
++#pragma once
++
++/** The UTF-16 character type. */
++typedef __CHAR16_TYPE__ char16_t;
++/** The UTF-32 character type. */
++typedef __CHAR32_TYPE__ char32_t;
+diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h
+index 08f732f484..a10e74f569 100644
+--- a/src/boot/efi/util.h
++++ b/src/boot/efi/util.h
+@@ -54,7 +54,7 @@ static inline void freep(void *p) {
+
+ #define _cleanup_free_ _cleanup_(freep)
+
+-static __always_inline void erase_obj(void *p) {
++static __attribute__((always_inline)) void erase_obj(void *p) {
+ #ifdef __OPTIMIZE__
+ size_t l;
+ assert_cl(p);
+diff --git a/src/fundamental/efivars-fundamental.h b/src/fundamental/efivars-fundamental.h
+index fe34e6c714..5d0fc701af 100644
+--- a/src/fundamental/efivars-fundamental.h
++++ b/src/fundamental/efivars-fundamental.h
+@@ -1,7 +1,6 @@
+ /* SPDX-License-Identifier: LGPL-2.1-or-later */
+ #pragma once
+
+-#include <errno.h>
+ #include "string-util-fundamental.h"
+
+ /* Features of the loader, i.e. systemd-boot */
+@@ -32,7 +31,7 @@ typedef enum SecureBootMode {
+ SECURE_BOOT_SETUP,
+ SECURE_BOOT_USER,
+ _SECURE_BOOT_MAX,
+- _SECURE_BOOT_INVALID = -EINVAL,
++ _SECURE_BOOT_INVALID = -22,
+ } SecureBootMode;
+
+ const sd_char *secure_boot_mode_to_string(SecureBootMode m);
+--
+2.47.2
+