[PATCH RFT 3/4] efi: payload: export device tree in barebox-dtb EFI variable

Ahmad Fatoum a.fatoum at pengutronix.de
Wed Aug 26 05:15:31 PDT 2026


An operating system booted by barebox on an EFI system doesn't
necessarily have a device tree, so we elected so far to provide a
state.dtb file on the ESP.

This is cumbersome and, in a secure-booting system, has the state DT
parser process untrusted input, which on all other platforms is not
case: The data itself may be untrusted, but the layout description is
verified as part of barebox and passed along.

To allow the same in the EFI payload case, export barebox' device tree
in flattened form in the barebox-dtb EFI variable under the barebox
vendor GUID, next to the bootloader interface variables barebox sets
already.

Under Linux, it can be read out of efivarfs. The variable is volatile
like the others, so it always describes the barebox instance that
booted the system.

The export happens right before control is handed over to the next image,
same as LoaderTimeExecUSec, so the only consumer, which runs after the
handover, sees the final device tree, including a state description read
from the EFI system partition at late init. Exporting before every
StartImage also covers chainloaded EFI bootloaders.

Assisted-by: Claude:opus-5
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 efi/payload/fdt.c      | 28 ++++++++++++++++++++++++++++
 efi/payload/handover.c |  2 ++
 efi/payload/image.c    |  2 ++
 include/efi/payload.h  |  6 ++++++
 4 files changed, 38 insertions(+)

diff --git a/efi/payload/fdt.c b/efi/payload/fdt.c
index f98fd86bfbd6..4ab8c197af2b 100644
--- a/efi/payload/fdt.c
+++ b/efi/payload/fdt.c
@@ -9,6 +9,7 @@
 #include <efi/payload.h>
 #include <efi/payload/init.h>
 #include <efi/guid.h>
+#include <efi/variable.h>
 
 extern char __dtb_fallback_start[];
 
@@ -67,3 +68,30 @@ static int efi_fdt_probe(void)
 	return 0;
 }
 late_efi_initcall(efi_fdt_probe);
+
+/*
+ * Export barebox' device tree, so the OS can learn about barebox-specific
+ * configuration like the state partition layout. Called just before handing
+ * over control, so the variable describes the final device tree.
+ */
+void efi_export_dtb(void)
+{
+	struct fdt_header *fdt;
+	int ret;
+
+	if (!of_get_root_node())
+		return;
+
+	fdt = of_get_flattened_tree(NULL, false);
+	if (!fdt)
+		return;
+
+	ret = efi_set_variable("barebox-dtb", &efi_barebox_vendor_guid,
+			       EFI_VARIABLE_BOOTSERVICE_ACCESS |
+			       EFI_VARIABLE_RUNTIME_ACCESS,
+			       fdt, fdt32_to_cpu(fdt->totalsize));
+	if (ret)
+		pr_warn("Cannot export device tree: %pe\n", ERR_PTR(ret));
+
+	free(fdt);
+}
diff --git a/efi/payload/handover.c b/efi/payload/handover.c
index 544fdfb3c6ad..669d88c722b6 100644
--- a/efi/payload/handover.c
+++ b/efi/payload/handover.c
@@ -183,6 +183,8 @@ static int do_bootm_efi(struct image_data *data)
 		goto err_free;
 	}
 
+	efi_export_dtb();
+
 	efi_set_variable_usec("LoaderTimeExecUSec", &efi_systemd_vendor_guid,
 			      ktime_to_us(ktime_get()));
 
diff --git a/efi/payload/image.c b/efi/payload/image.c
index 378709b6de95..6485bc2f2d68 100644
--- a/efi/payload/image.c
+++ b/efi/payload/image.c
@@ -109,6 +109,8 @@ int efi_execute_image(efi_handle_t handle,
 	is_driver = (loaded_image->image_code_type == EFI_BOOT_SERVICES_CODE) ||
 		(loaded_image->image_code_type == EFI_RUNTIME_SERVICES_CODE);
 
+	efi_export_dtb();
+
 	if (filetype_is_linux_efi_image(filetype)) {
 		options = linux_bootargs_get();
 		printf("Booting kernel via StartImage");
diff --git a/include/efi/payload.h b/include/efi/payload.h
index 381598ba59f2..9e4e8c5ce0ae 100644
--- a/include/efi/payload.h
+++ b/include/efi/payload.h
@@ -27,6 +27,12 @@ extern struct efi_loaded_image *efi_loaded_image;
 void *efi_earlymem_alloc(const struct efi_system_table *sys_table,
 			 size_t memsize, enum efi_memory_type mem_type);
 
+#ifdef CONFIG_OFTREE
+void efi_export_dtb(void);
+#else
+static inline void efi_export_dtb(void) {}
+#endif
+
 __attribute__((noreturn)) void efi_main(efi_handle_t, struct efi_system_table *);
 
 #define for_each_efi_config_table(t) \
-- 
2.47.3




More information about the barebox mailing list