This patch adds a new boot package to Buildroot for building the
efibootguard bootloader from the
https://github.com/siemens/efibootguard
repository.
efibootguard can be chainloaded as an EFI application or used as a
standalone bootloader and can be useful when building A/B systems.
Add a recipe to build the EFI bootloader application, user-space
tooling & host tooling (both of which are used to manage efibootguard
configuration).
efibootguard supports multiple architectures, but for now only build
the EFI bootloader for x86_64.
Signed-off-by: Christopher Obbard <
obb...@gmail.com>
---
DEVELOPERS | 3 +
boot/Config.in | 2 +
...e-segfault-when-building-with-busybox-ash.patch | 38 ++++++++++
...-parsing-and-checks-to-also-support-gnu-e.patch | 88 ++++++++++++++++++++++
boot/efibootguard/Config.in | 37 +++++++++
boot/efibootguard/Config.in.host | 8 ++
boot/efibootguard/efibootguard.hash | 3 +
boot/efibootguard/
efibootguard.mk | 60 +++++++++++++++
8 files changed, 239 insertions(+)
diff --git a/DEVELOPERS b/DEVELOPERS
index 1b27df9beb..9b789b3023 100644
--- a/DEVELOPERS
+++ b/DEVELOPERS
@@ -689,6 +689,9 @@ F: package/perl-sys-mmap/
F: package/perl-time-parsedate/
F: package/perl-x10/
+N: Christopher Obbard <
obb...@gmail.com>
+F: boot/efibootguard/
+
N: Clayton Shotwell <
clayton....@collins.com>
F: package/audit/
F: package/checkpolicy/
diff --git a/boot/Config.in b/boot/Config.in
index d3e1b9c055..1aa1a4bfff 100644
--- a/boot/Config.in
+++ b/boot/Config.in
@@ -15,6 +15,8 @@ source "boot/barebox/Config.in"
source "boot/binaries-marvell/Config.in"
source "boot/boot-wrapper-aarch64/Config.in"
source "boot/edk2/Config.in"
+source "boot/efibootguard/Config.in"
+source "boot/efibootguard/Config.in.host"
source "boot/grub2/Config.in"
source "boot/mv-ddr-marvell/Config.in"
source "boot/mxs-bootlets/Config.in"
diff --git a/boot/efibootguard/0001-fix-resolve-segfault-when-building-with-busybox-ash.patch b/boot/efibootguard/0001-fix-resolve-segfault-when-building-with-busybox-ash.patch
new file mode 100644
index 0000000000..db301c8e93
--- /dev/null
+++ b/boot/efibootguard/0001-fix-resolve-segfault-when-building-with-busybox-ash.patch
@@ -0,0 +1,38 @@
+From f094a141df61c960bf7db4a26ab6a461438a2502 Mon Sep 17 00:00:00 2001
+From: Philip Schildkamp <
philip.s...@uni-koeln.de>
+Date: Sun, 28 Sep 2025 13:29:46 +0200
+Subject: [PATCH] fix: resolve segfault when building with busybox/ash
+
+This patch resolves a segmentation fault caused by the configure script,
+when building efibootguard using the BusyBox shell ash. The segmentation
+fault seems to be caused by the BusyBox shell consuming the opening $((
+as the beginning of an arithmetic statement.
+
+To mitigate this, this patch simply inserts one space character between
+the opening double parenthesis, whereby the BusyBox shell no longer
+tries to parse this as an arithmetic expression.
+
+Signed-off-by: Philip Schildkamp <
philip.s...@uni-koeln.de>
+Signed-off-by: Jan Kiszka <
jan.k...@siemens.com>
+
+Upstream: f094a141df61c960bf7db4a26ab6a461438a2502
+Signed-off-by: Christopher Obbard <
obb...@gmail.com>
+---
+
configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/
configure.ac b/
configure.ac
+index 038930b..d1c932b 100644
+--- a/
configure.ac
++++ b/
configure.ac
+@@ -234,7 +234,7 @@ fi
+ # Note: gnu-efi introduced pkg-config with version 3.0.16
+ # GNU_EFI_VERSION resolves to gnu-efi's version without dots, e.g., GNU_EFI_VERSION=3016
+ # gnu-efi versions < 3.0.16 resolve to GNU_EFI_VERSION=0
+-AC_SUBST([GNU_EFI_VERSION], [$(($PKG_CONFIG --modversion "gnu-efi" 2>/dev/null || echo 0) | $TR -d '.' )])
++AC_SUBST([GNU_EFI_VERSION], [$( ($PKG_CONFIG --modversion "gnu-efi" 2>/dev/null || echo 0) | $TR -d '.' )])
+ AC_DEFINE_UNQUOTED([GNU_EFI_VERSION], [${GNU_EFI_VERSION}], [gnu-efi version])
+
+ AC_SUBST([OBJCOPY_HAS_EFI_APP_TARGET], [$($OBJCOPY --info | $GREP -q pei- 2>/dev/null && echo "true")])
+--
+2.51.0
diff --git a/boot/efibootguard/0002-Fix-version-parsing-and-checks-to-also-support-gnu-e.patch b/boot/efibootguard/0002-Fix-version-parsing-and-checks-to-also-support-gnu-e.patch
new file mode 100644
index 0000000000..3cc22db75e
--- /dev/null
+++ b/boot/efibootguard/0002-Fix-version-parsing-and-checks-to-also-support-gnu-e.patch
@@ -0,0 +1,88 @@
+From 933dd15d71205ead6bc017740ad4618ee6c470ae Mon Sep 17 00:00:00 2001
+From: Christian Storm <
christi...@siemens.com>
+Date: Thu, 20 Nov 2025 19:01:37 +0000
+Subject: [PATCH] Fix version parsing and checks to also support gnu-efi >= 4.0
+
+The current mechanism to parse gnu-efi's version is restricted to
+gnu-efi 3.x series. Improve the calculation to also account for
+gnu-efi 4.x series (and beyond).
+
+Reported-by: Andreas Tobler <
andreas...@onway.ch>
+Signed-off-by: Christian Storm <
christi...@siemens.com>
+Signed-off-by: Jan Kiszka <
jan.k...@siemens.com>
+
+Upstream: 933dd15d71205ead6bc017740ad4618ee6c470ae
+Signed-off-by: Christopher Obbard <
obb...@gmail.com>
+---
+
configure.ac | 6 +++---
+ drivers/watchdog/wdfuncs_end.c | 2 +-
+ drivers/watchdog/wdfuncs_start.c | 2 +-
+ main.c | 2 +-
+ 4 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/
configure.ac b/
configure.ac
+index d1c932b..7f22339 100644
+--- a/
configure.ac
++++ b/
configure.ac
+@@ -40,7 +40,7 @@ AC_PROG_CC
+ AC_CHECK_TOOL(LD, ld)
+ AC_CHECK_TOOL(OBJCOPY, objcopy)
+ AC_CHECK_TOOL(GREP, grep)
+-AC_CHECK_TOOL(TR, tr)
++AC_CHECK_TOOL(AWK, awk)
+
+ dnl Dont try to use things like -std=c99 for efi compilation
+ GNUEFI_CC=$CC
+@@ -232,9 +232,9 @@ if test "x$PKG_CONFIG" = "xno"; then
+ fi
+
+ # Note: gnu-efi introduced pkg-config with version 3.0.16
+-# GNU_EFI_VERSION resolves to gnu-efi's version without dots, e.g., GNU_EFI_VERSION=3016
++# GNU_EFI_VERSION resolves to gnu-efi's version without dots, e.g., GNU_EFI_VERSION=3000016
+ # gnu-efi versions < 3.0.16 resolve to GNU_EFI_VERSION=0
+-AC_SUBST([GNU_EFI_VERSION], [$( ($PKG_CONFIG --modversion "gnu-efi" 2>/dev/null || echo 0) | $TR -d '.' )])
++AC_SUBST([GNU_EFI_VERSION], [$( ($PKG_CONFIG --modversion "gnu-efi" 2>/dev/null || echo 0) | $AWK -F. '{print $1*1000000 + $2*1000 + $3}' )])
+ AC_DEFINE_UNQUOTED([GNU_EFI_VERSION], [${GNU_EFI_VERSION}], [gnu-efi version])
+
+ AC_SUBST([OBJCOPY_HAS_EFI_APP_TARGET], [$($OBJCOPY --info | $GREP -q pei- 2>/dev/null && echo "true")])
+diff --git a/drivers/watchdog/wdfuncs_end.c b/drivers/watchdog/wdfuncs_end.c
+index d19a0ab..f90ffc7 100644
+--- a/drivers/watchdog/wdfuncs_end.c
++++ b/drivers/watchdog/wdfuncs_end.c
+@@ -12,7 +12,7 @@
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+-#if GNU_EFI_VERSION < 3016
++#if GNU_EFI_VERSION < 3000016
+
+ #include <efi.h>
+ #include "utils.h"
+diff --git a/drivers/watchdog/wdfuncs_start.c b/drivers/watchdog/wdfuncs_start.c
+index bdf47f5..c627050 100644
+--- a/drivers/watchdog/wdfuncs_start.c
++++ b/drivers/watchdog/wdfuncs_start.c
+@@ -12,7 +12,7 @@
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+-#if GNU_EFI_VERSION < 3016
++#if GNU_EFI_VERSION < 3000016
+
+ #include <efi.h>
+ #include "utils.h"
+diff --git a/main.c b/main.c
+index 5d61385..b1bbc56 100644
+--- a/main.c
++++ b/main.c
+@@ -45,7 +45,7 @@ VOID register_watchdog(WATCHDOG_DRIVER *driver)
+
+ static EFI_STATUS probe_watchdogs(UINTN timeout)
+ {
+-#if GNU_EFI_VERSION < 3016
++#if GNU_EFI_VERSION < 3000016
+ const unsigned long *entry = wdfuncs_start;
+ for (entry++; entry < wdfuncs_end; entry++) {
+ ((void (*)(void))*entry)();
+--
+2.51.0
diff --git a/boot/efibootguard/Config.in b/boot/efibootguard/Config.in
new file mode 100644
index 0000000000..47fd478e8b
--- /dev/null
+++ b/boot/efibootguard/Config.in
@@ -0,0 +1,37 @@
+config BR2_TARGET_EFIBOOTGUARD_ARCH_SUPPORTS
+ bool
+ default y if BR2_x86_64
+ depends on BR2_USE_MMU
+
+config BR2_TARGET_EFIBOOTGUARD
+ bool "efibootguard"
+ depends on BR2_TARGET_EFIBOOTGUARD_ARCH_SUPPORTS
+ depends on BR2_USE_WCHAR
+ select BR2_PACKAGE_GNU_EFI
+ select BR2_PACKAGE_PCIUTILS if BR2_TARGET_EFIBOOTGUARD_INSTALL_TOOLS
+ help
+ EFI Boot Guard is a UEFI bootloader intended for robust
+ A/B style updates. It arms a hardware watchdog before
+ handing over control to the OS and supports a fail-safe
+ boot mechanism to roll back if a boot attempt fails.
+
+
https://github.com/siemens/efibootguard
+
+if BR2_TARGET_EFIBOOTGUARD
+
+config BR2_TARGET_EFIBOOTGUARD_X86_64
+ bool "x86-64"
+ depends on BR2_x86_64
+ help
+ Select this option if the platform you're targeting has a
+ 64 bits EFI BIOS.
+
+config BR2_TARGET_EFIBOOTGUARD_INSTALL_TOOLS
+ bool "install tools"
+ help
+ Install the efibootguard user-space tools (e.g.
+ bg_printenv and bg_setenv) on the target. These tools
+ allow reading and updating efibootguard's configuration
+ in user-space.
+
+endif # BR2_TARGET_EFIBOOTGUARD
diff --git a/boot/efibootguard/Config.in.host b/boot/efibootguard/Config.in.host
new file mode 100644
index 0000000000..845c14c079
--- /dev/null
+++ b/boot/efibootguard/Config.in.host
@@ -0,0 +1,8 @@
+config BR2_TARGET_HOST_EFIBOOTGUARD
+ bool "host efibootguard"
+ help
+ Build efibootguard companion tools for the host. These
+ can be used during image creation to inspect and
+ modify the efibootguard configuration data.
+
+
https://github.com/siemens/efibootguard
diff --git a/boot/efibootguard/efibootguard.hash b/boot/efibootguard/efibootguard.hash
new file mode 100644
index 0000000000..48e03496ff
--- /dev/null
+++ b/boot/efibootguard/efibootguard.hash
@@ -0,0 +1,3 @@
+# Locally calculated
+sha256 f252e87b6acc74df34a0d894f2b5188fe797c2a2b7a14a231b9f224ad9b9de20 efibootguard-0.21.tar.gz
+sha256 8177f97513213526df2cf6184d8ff986c675afb514d4e68a404010521b880643 COPYING
diff --git a/boot/efibootguard/
efibootguard.mk b/boot/efibootguard/
efibootguard.mk
new file mode 100644
index 0000000000..9fe8ff63a7
--- /dev/null
+++ b/boot/efibootguard/
efibootguard.mk
@@ -0,0 +1,60 @@
+################################################################################
+#
+# efibootguard
+#
+################################################################################
+
+EFIBOOTGUARD_VERSION = 0.21
+EFIBOOTGUARD_SITE = $(call github,siemens,efibootguard,refs/tags/v$(EFIBOOTGUARD_VERSION))
+EFIBOOTGUARD_LICENSE = GPL-2.0-only
+EFIBOOTGUARD_LICENSE_FILES = COPYING
+
+EFIBOOTGUARD_DEPENDENCIES = \
+ gnu-efi \
+ host-autoconf-archive
+
+ifeq ($(BR2_TARGET_EFIBOOTGUARD_INSTALL_TOOLS),y)
+EFIBOOTGUARD_DEPENDENCIES += pciutils
+EFIBOOTGUARD_INSTALL_TARGET = YES
+else
+EFIBOOTGUARD_INSTALL_TARGET = NO
+endif
+
+EFIBOOTGUARD_INSTALL_IMAGES = YES
+
+EFIBOOTGUARD_AUTORECONF = YES
+
+EFIBOOTGUARD_AUTORECONF_OPTS = \
+ -I $(HOST_DIR)/share/autoconf-archive
+
+EFIBOOTGUARD_CONF_OPTS = \
+ --with-gnuefi-sys-dir=$(STAGING_DIR) \
+ --with-gnuefi-include-dir=$(STAGING_DIR)/usr/include/efi \
+ --with-gnuefi-lib-dir=$(STAGING_DIR)/usr/lib \
+ --disable-completion \
+ --disable-tests
+
+# TODO: Perhaps take inspiration from Debian patch
https://salsa.debian.org/debian/efibootguard/-/blob/master/debian/patches/always-override-stack-protector-variables-in-EFI-bui.patch?ref_type=heads
+EFIBOOTGUARD_CONF_ENV = \
+ LDFLAGS="$(LDFLAGS) -no-pie"
+
+define EFIBOOTGUARD_INSTALL_IMAGES_CMDS
+ $(INSTALL) -d $(BINARIES_DIR)/efibootguard
+ $(INSTALL) -m 0644 $(@D)/efibootguardx64.efi $(BINARIES_DIR)/efibootguard/
+endef
+
+HOST_EFIBOOTGUARD_DEPENDENCIES = \
+ host-autoconf-archive
+
+HOST_EFIBOOTGUARD_AUTORECONF = YES
+
+HOST_EFIBOOTGUARD_AUTORECONF_OPTS = \
+ -I $(HOST_DIR)/share/autoconf-archive
+
+HOST_EFIBOOTGUARD_CONF_OPTS = \
+ --disable-bootloader \
+ --disable-completion \
+ --disable-tests
+
+$(eval $(autotools-package))
+$(eval $(host-autotools-package))
--
2.51.0