[PATCH] x86_64: add systemd-boot images

Stefan Hellermann stefan at the2masters.de
Tue Dec 30 12:12:06 PST 2025


Hi,

I integrated this patch into another tree without the packages feed. 
Then I get errors about missing dependencies:

WARNING: Makefile 'package/boot/systemd-boot/Makefile' has a build 
dependency on 'python-pyelftools/host', which does not exist
WARNING: Makefile 'package/boot/systemd-boot/Makefile' has a build 
dependency on 'python-jinja2/host', which does not exist

and later python3 is missing:

make[3]: Entering directory 
'/home/stefan/devel/openwrt2/package/boot/systemd-boot'
systemd-boot fused dependencies: libc, libblkid1
rm -f 
/home/stefan/devel/openwrt2/build_dir/target-x86_64_musl/systemd-boot-259/.configured_*
rm -f 
/home/stefan/devel/openwrt2/staging_dir/target-x86_64_musl/stamp/.systemd-boot_installed
/home/stefan/devel/openwrt2/staging_dir/host/bin/sed -e 
"s|@CC@|'/home/stefan/devel/openwrt2/staging_dir/host/bin/gcc',|" -e 
"s|@CXX@|'/home/stefan/devel/openwrt2/staging_dir/host/bin/g++',|" -e 
"s|@PKGCONFIG@|/home/stefan/devel/openwrt2/staging_dir/host/bin/pkg-config|" 
-e "s|@CMAKE@|/home/stefan/devel/openwrt2/staging_dir/host/bin/cmake|" 
-e 
"s|@PYTHON@|/home/stefan/devel/openwrt2/staging_dir/hostpkg/bin/python3|" 
-e "s|@CFLAGS@|'-O2', 
'-I/home/stefan/devel/openwrt2/staging_dir/host/include', 
'-I/home/stefan/devel/openwrt2/staging_dir/hostpkg/include', 
'-I/home/stefan/devel/openwrt2/staging_dir/target-x86_64_musl/host/include', 
'-I/home/stefan/devel/openwrt2/staging_dir/host/include', 
'-I/home/stefan/devel/openwrt2/staging_dir/hostpkg/include', 
'-I/home/stefan/devel/openwrt2/staging_dir/target-x86_64_musl/host/include',|" 
-e "s|@CXXFLAGS@|'-O2', 
'-I/home/stefan/devel/openwrt2/staging_dir/host/include', 
'-I/home/stefan/devel/openwrt2/staging_dir/hostpkg/include', 
'-I/home/stefan/devel/openwrt2/staging_dir/target-x86_64_musl/host/include', 
'-I/home/stefan/devel/openwrt2/staging_dir/host/include', 
'-I/home/stefan/devel/openwrt2/staging_dir/hostpkg/include', 
'-I/home/stefan/devel/openwrt2/staging_dir/target-x86_64_musl/host/include',|" 
-e "s|@LDFLAGS@|'-L/home/stefan/devel/openwrt2/staging_dir/host/lib', 
'-L/home/stefan/devel/openwrt2/staging_dir/hostpkg/lib', 
'-L/home/stefan/devel/openwrt2/staging_dir/target-x86_64_musl/host/lib',|" 
-e "s|@PREFIX@||" < 
/home/stefan/devel/openwrt2/staging_dir/host/lib/meson/openwrt-native.txt.in 
 > 
/home/stefan/devel/openwrt2/build_dir/target-x86_64_musl/systemd-boot-259/openwrt-native.txt
/home/stefan/devel/openwrt2/staging_dir/host/bin/sed -e 
"s|@CC@|'x86_64-openwrt-linux-musl-gcc',|" -e 
"s|@CXX@|'x86_64-openwrt-linux-musl-g++',|" -e "s|@LD@|'bfd',|" -e 
"s|@AR@|x86_64-openwrt-linux-musl-gcc-ar|" -e 
"s|@STRIP@|x86_64-openwrt-linux-musl-strip|" -e 
"s|@NM@|x86_64-openwrt-linux-musl-gcc-nm|" -e 
"s|@PKGCONFIG@|/home/stefan/devel/openwrt2/staging_dir/host/bin/pkg-config|" 
-e "s|@CMAKE@|/home/stefan/devel/openwrt2/staging_dir/host/bin/cmake|" 
-e 
"s|@PYTHON@|/home/stefan/devel/openwrt2/staging_dir/hostpkg/bin/python3|" 
-e "s|@CFLAGS@|'-Os', '-pipe', '-fno-caller-saves', '-fno-plt', 
'-fhonour-copts', 
'-fmacro-prefix-map=/home/stefan/devel/openwrt2/build_dir/target-x86_64_musl/systemd-boot-259=systemd-boot-259', 
'-Wformat', '-Werror=format-security', '-fstack-protector', 
'-D_FORTIFY_SOURCE=1', '-Wl,-z,now', '-Wl,-z,relro', 
'-Wl,-z,pack-relative-relocs', 
'-I/home/stefan/devel/openwrt2/staging_dir/toolchain-x86_64_gcc-14.3.0_musl/usr/include', 
'-I/home/stefan/devel/openwrt2/staging_dir/toolchain-x86_64_gcc-14.3.0_musl/include', 
'-I/home/stefan/devel/openwrt2/staging_dir/toolchain-x86_64_gcc-14.3.0_musl/include/fortify',|" 
-e "s|@CXXFLAGS@|'-Os', '-pipe', '-fno-caller-saves', '-fno-plt', 
'-fhonour-copts', 
'-fmacro-prefix-map=/home/stefan/devel/openwrt2/build_dir/target-x86_64_musl/systemd-boot-259=systemd-boot-259', 
'-Wformat', '-Werror=format-security', '-fstack-protector', 
'-D_FORTIFY_SOURCE=1', '-Wl,-z,now', '-Wl,-z,relro', 
'-Wl,-z,pack-relative-relocs', 
'-I/home/stefan/devel/openwrt2/staging_dir/toolchain-x86_64_gcc-14.3.0_musl/usr/include', 
'-I/home/stefan/devel/openwrt2/staging_dir/toolchain-x86_64_gcc-14.3.0_musl/include', 
'-I/home/stefan/devel/openwrt2/staging_dir/toolchain-x86_64_gcc-14.3.0_musl/include/fortify',|" 
-e 
"s|@LDFLAGS@|'-L/home/stefan/devel/openwrt2/staging_dir/toolchain-x86_64_gcc-14.3.0_musl/usr/lib', 
'-L/home/stefan/devel/openwrt2/staging_dir/toolchain-x86_64_gcc-14.3.0_musl/lib', 
'-fuse-ld=bfd', '-znow', '-zrelro', '-zpack-relative-relocs',|" -e 
"s|@ARCH@|"x86_64"|" -e "s|@CPU@|"generic"|" -e "s|@ENDIAN@|little|" < 
/home/stefan/devel/openwrt2/staging_dir/host/lib/meson/openwrt-cross.txt.in 
 > 
/home/stefan/devel/openwrt2/build_dir/target-x86_64_musl/systemd-boot-259/openwrt-cross.txt
/home/stefan/devel/openwrt2/staging_dir/hostpkg/bin/python3 
/home/stefan/devel/openwrt2/staging_dir/host/bin/meson.py  setup 
--buildtype plain --native-file 
/home/stefan/devel/openwrt2/build_dir/target-x86_64_musl/systemd-boot-259/openwrt-native.txt 
--cross-file 
/home/stefan/devel/openwrt2/build_dir/target-x86_64_musl/systemd-boot-259/openwrt-cross.txt 
-Ddefault_library=both -Dmode=release -Dlibc=musl -Dbootloader=enabled 
--auto-features=disabled 
/home/stefan/devel/openwrt2/build_dir/target-x86_64_musl/systemd-boot-259/openwrt-build 
/home/stefan/devel/openwrt2/build_dir/target-x86_64_musl/systemd-boot-259/openwrt-build/..
bash: line 1: 
/home/stefan/devel/openwrt2/staging_dir/hostpkg/bin/python3: No such 
file or directory
make[3]: *** [Makefile:62: 
/home/stefan/devel/openwrt2/build_dir/target-x86_64_musl/systemd-boot-259/.configured_68b329da9893e34099c7d8ad5cb9c940] 
Error 127
make[3]: Leaving directory 
'/home/stefan/devel/openwrt2/package/boot/systemd-boot'
time: package/boot/systemd-boot/compile#0.10#0.11#0.20
     ERROR: package/boot/systemd-boot failed to build.
make[2]: *** [package/Makefile:187: package/boot/systemd-boot/compile] 
Error 1
make[2]: Leaving directory '/home/stefan/devel/openwrt2'
make[1]: *** [package/Makefile:181: 
/home/stefan/devel/openwrt2/staging_dir/target-x86_64_musl/stamp/.package_compile] 
Error 2
make[1]: Leaving directory '/home/stefan/devel/openwrt2'
make: *** [/home/stefan/devel/openwrt2/include/toplevel.mk:233: world] 
Fehler 2

No easy fix :-) I think it will be difficult to integrate all the 
dependencies into openwrt in order to compile the entire systemd with it...

Have you thought about integrating the boot cmdline into the kernel 
(CONFIG_CMDLINE) and just put the kernel to /boot/efi/boot/bootx64.efi ? 
Or the new UKI-Format?

Best regards,
Stefan



Am 30.12.25 um 12:54 schrieb Jonas Lochmann:
> grub2 has many features, including different implementations for loading
> the linux kernel. At one machine, the "linux" command cannot start
> OpenWrt while the "chainloader" command for the same kernel file works.
>
> Both commands use the same UEFI API, but the surrounding steps are
> slightly different. An UEFI native bootloader seems to be similar to
> "chainloader" in grub while avoiding a ton of extra features. One of
> those bootloaders is systemd-boot, formerly known as gummiboot.
> While it contains the name "systemd" and is part of the systemd
> codebase, the resulting efi executable can be used independent of
> systemd. systemd contains bootctl for managing a systemd-boot
> installation, but systemd-boot uses simple text configuration files
> so that this is not needed at all.
>
> Signed-off-by: Jonas Lochmann <openwrt at jonaslochmann.de>
> ---
>   config/Config-images.in                       | 18 ++++--
>   package/boot/systemd-boot/Makefile            | 55 +++++++++++++++++++
>   .../x86/base-files/lib/upgrade/platform.sh    |  1 +
>   target/linux/x86/image/Makefile               | 28 ++++++++++
>   target/linux/x86/image/systemdboot-entry.cfg  |  4 ++
>   .../linux/x86/image/systemdboot-loader.conf   |  1 +
>   6 files changed, 101 insertions(+), 6 deletions(-)
>   create mode 100644 package/boot/systemd-boot/Makefile
>   create mode 100644 target/linux/x86/image/systemdboot-entry.cfg
>   create mode 100644 target/linux/x86/image/systemdboot-loader.conf
>
> diff --git a/config/Config-images.in b/config/Config-images.in
> index fcc5fa52cb..ff93990834 100644
> --- a/config/Config-images.in
> +++ b/config/Config-images.in
> @@ -229,6 +229,12 @@ menu "Target Images"
>   			prompt "journal size" if TARGET_ROOTFS_UBIFS
>   			default ""
>   
> +	config SYSTEMDBOOT_IMAGES
> +		bool "Build systemd-boot images (EFI x86_64 targets only)"
> +		depends on TARGET_x86_64
> +		depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS || TARGET_ROOTFS_EROFS
> +		select PACKAGE_systemd-boot
> +
>   	config GRUB_IMAGES
>   		bool "Build GRUB images (Linux x86 or x86_64 host only)"
>   		depends on TARGET_x86
> @@ -251,23 +257,23 @@ menu "Target Images"
>   
>   	config GRUB_CONSOLE
>   		bool "Use Console Terminal (in addition to Serial)"
> -		depends on GRUB_IMAGES || GRUB_EFI_IMAGES
> +		depends on GRUB_IMAGES || GRUB_EFI_IMAGES || SYSTEMDBOOT_IMAGES
>   		default y
>   
>   	config GRUB_BAUDRATE
>   		int "Serial port baud rate"
> -		depends on GRUB_IMAGES || GRUB_EFI_IMAGES
> +		depends on GRUB_IMAGES || GRUB_EFI_IMAGES || SYSTEMDBOOT_IMAGES
>   		default 38400 if TARGET_x86_generic
>   		default 115200
>   
>   	config GRUB_FLOWCONTROL
>   		bool "Use RTE/CTS on serial console"
> -		depends on GRUB_IMAGES || GRUB_EFI_IMAGES
> +		depends on GRUB_IMAGES || GRUB_EFI_IMAGES || SYSTEMDBOOT_IMAGES
>   		depends on TARGET_SERIAL != ""
>   
>   	config GRUB_BOOTOPTS
>   		string "Extra kernel boot options"
> -		depends on GRUB_IMAGES || GRUB_EFI_IMAGES
> +		depends on GRUB_IMAGES || GRUB_EFI_IMAGES || SYSTEMDBOOT_IMAGES
>   		help
>   		  If you don't know, just leave it blank.
>   
> @@ -279,8 +285,8 @@ menu "Target Images"
>   		  If you don't know, 5 seconds is a reasonable default.
>   
>   	config GRUB_TITLE
> -		string "Title for the menu entry in GRUB"
> -		depends on GRUB_IMAGES || GRUB_EFI_IMAGES
> +		string "Title for the menu entry in GRUB and systemd-boot"
> +		depends on GRUB_IMAGES || GRUB_EFI_IMAGES || SYSTEMDBOOT_IMAGES
>   		default "OpenWrt"
>   		help
>   		  This is the title of the GRUB menu entry.
> diff --git a/package/boot/systemd-boot/Makefile b/package/boot/systemd-boot/Makefile
> new file mode 100644
> index 0000000000..425f53561d
> --- /dev/null
> +++ b/package/boot/systemd-boot/Makefile
> @@ -0,0 +1,55 @@
> +#
> +# This is free software, licensed under the GNU General Public License v2.
> +# See /LICENSE for more information.
> +#
> +
> +include $(TOPDIR)/rules.mk
> +
> +PKG_NAME:=systemd-boot
> +PKG_VERSION:=259
> +PKG_RELEASE:=1
> +
> +PKG_SOURCE_PROTO:=git
> +PKG_SOURCE_URL:=https://github.com/systemd/systemd.git
> +PKG_MIRROR_HASH:=1671487dc511d60d3c50070e8f5c6dec228a1d97cdedd7f5508a966bb06ba614
> +PKG_SOURCE_DATE:=2025-12-17
> +PKG_SOURCE_VERSION:=9ca433482f2281d71718718705ca8cd3bf562ad6
> +PKG_CPE_ID:=cpe:/a:systemd_project:systemd:259:-
> +
> +PKG_LICENSE:=LGPL-2.1-or-later
> +PKG_LICENSE_FILES:=LICENSES/README.md
> +PKG_BUILD_DEPENDS:=python-pyelftools/host python-jinja2/host gperf/host
> +PKG_INSTALL:=1
> +
> +MESON_USE_STAGING_PYTHON:=1
> +
> +include $(INCLUDE_DIR)/package.mk
> +include $(INCLUDE_DIR)/meson.mk
> +
> +define Package/systemd-boot
> +  SECTION:=boot
> +  CATEGORY:=Boot Loaders
> +  TITLE:=Simple UEFI boot manager
> +  DEPENDS:=@TARGET_x86_64 +libblkid
> +  URL:=https://github.com/systemd/systemd/tree/main/src/boot
> +endef
> +
> +define Package/systemd-boot/description
> +  systemd-boot Simple UEFI boot manager
> +
> +  systemd-boot executes EFI images. The default entry is selected by a configured
> +  pattern (glob) or an on-screen menu.
> +endef
> +
> +MESON_ARGS += \
> +	-Dmode=release \
> +	-Dlibc=musl \
> +	-Dbootloader=enabled \
> +	--auto-features=disabled
> +
> +define Package/systemd-boot/install
> +	$(INSTALL_DIR) $(1)/usr/sbin $(1)/usr/lib/systemd-boot
> +	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/systemd/boot/efi/systemd-bootx64.efi $(1)/usr/lib/systemd-boot/
> +endef
> +
> +$(eval $(call BuildPackage,systemd-boot))
> diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh
> index 5dad7a538a..bca3d0426f 100644
> --- a/target/linux/x86/base-files/lib/upgrade/platform.sh
> +++ b/target/linux/x86/base-files/lib/upgrade/platform.sh
> @@ -125,6 +125,7 @@ platform_do_upgrade() {
>   		mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
>   		set -- $(dd if="/dev/$diskdev" bs=1 skip=1168 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"')
>   		sed -i "s/\(PARTUUID=\)[a-f0-9-]\+/\1$4$3$2$1-$6$5-$8$7-$9/ig" /mnt/boot/grub/grub.cfg
> +		sed -i "s/\(PARTUUID=\)[a-f0-9-]\+/\1$4$3$2$1-$6$5-$8$7-$9/ig" /mnt/loader/entries/main.conf
>   		umount /mnt
>   	fi
>   }
> diff --git a/target/linux/x86/image/Makefile b/target/linux/x86/image/Makefile
> index 29bebeb748..6f11712e87 100644
> --- a/target/linux/x86/image/Makefile
> +++ b/target/linux/x86/image/Makefile
> @@ -52,6 +52,30 @@ define Build/combined
>   		256
>   endef
>   
> +define Build/systemd-boot
> +	rm -fR $@.boot
> +	$(INSTALL_DIR) $@.boot/boot $@.boot/efi/boot $@.boot/loader/entries
> +
> +	$(CP) $(KDIR)/$(KERNEL_NAME) $@.boot/boot/vmlinuz
> +	-$(CP) $(STAGING_DIR_ROOT)/boot/. $@.boot/boot/
> +	$(CP) $(STAGING_DIR_ROOT)/usr/lib/systemd-boot/systemd-bootx64.efi $@.boot/efi/boot/bootx64.efi
> +
> +	sed \
> +		-e 's#@GPT_ROOTPART@#root=$(GPT_ROOTPART) rootwait#g' \
> +		-e 's#@CMDLINE@#$(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE)#g' \
> +		-e 's#@TITLE@#$(GRUB_TITLE)#g' \
> +		./systemdboot-entry.cfg > $@.boot/loader/entries/main.conf
> +
> +	$(CP) ./systemdboot-loader.conf $@.boot/loader/loader.conf
> +
> +	PADDING="1" SIGNATURE="$(IMG_PART_SIGNATURE)" \
> +		GUID="$(IMG_PART_DISKGUID)" $(SCRIPT_DIR)/gen_image_generic.sh \
> +		$@ \
> +		$(CONFIG_TARGET_KERNEL_PARTSIZE) $@.boot \
> +		$(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) \
> +		256
> +endef
> +
>   define Build/grub-config
>   	rm -fR $@.boot
>   	$(INSTALL_DIR) $@.boot/boot/grub
> @@ -114,14 +138,18 @@ define Device/Default
>     IMAGE/combined-efi.vdi := grub-config efi | combined efi | grub-install efi | qemu-image vdi
>     IMAGE/combined-efi.vmdk := grub-config efi | combined efi | grub-install efi | qemu-image vmdk
>     IMAGE/combined-efi.vhdx := grub-config efi | combined efi | grub-install efi | qemu-image vhdx -o subformat=dynamic
> +  IMAGE/systemd-boot.img := systemd-boot | append-metadata
> +  IMAGE/systemd-boot.img.gz := systemd-boot | gzip | append-metadata
>     ifeq ($(CONFIG_TARGET_IMAGES_GZIP),y)
>       IMAGES-y := rootfs.img.gz
>       IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.img.gz
>       IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.img.gz
> +    IMAGES-$$(CONFIG_SYSTEMDBOOT_IMAGES) += systemd-boot.img.gz
>     else
>       IMAGES-y := rootfs.img
>       IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.img
>       IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.img
> +    IMAGES-$$(CONFIG_SYSTEMDBOOT_IMAGES) += systemd-boot.img
>     endif
>     KERNEL := kernel-bin
>     KERNEL_INSTALL := 1
> diff --git a/target/linux/x86/image/systemdboot-entry.cfg b/target/linux/x86/image/systemdboot-entry.cfg
> new file mode 100644
> index 0000000000..cf6bc659d0
> --- /dev/null
> +++ b/target/linux/x86/image/systemdboot-entry.cfg
> @@ -0,0 +1,4 @@
> +title @TITLE@
> +linux /boot/vmlinuz
> +options @GPT_ROOTPART@ @CMDLINE@ noinitrd
> +architecture x64
> diff --git a/target/linux/x86/image/systemdboot-loader.conf b/target/linux/x86/image/systemdboot-loader.conf
> new file mode 100644
> index 0000000000..533d233153
> --- /dev/null
> +++ b/target/linux/x86/image/systemdboot-loader.conf
> @@ -0,0 +1 @@
> +timeout menu-disabled



More information about the openwrt-devel mailing list