[PATCH v2 3/4] efi: payload: export device tree in barebox-dtb EFI variable
Ahmad Fatoum
a.fatoum at pengutronix.de
Thu Oct 15 02:23:29 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.
Any existing barebox-dtb variable is deleted first: SetVariable()
refuses to rewrite a variable with different attributes, so a
non-volatile one created via efivarfs would otherwise survive and be
read in place of the exported device tree.
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 | 31 +++++++++++++++++++++++++++++++
efi/payload/handover.c | 2 ++
efi/payload/image.c | 2 ++
include/efi/payload.h | 6 ++++++
4 files changed, 41 insertions(+)
diff --git a/efi/payload/fdt.c b/efi/payload/fdt.c
index f98fd86bfbd6..f3e659052dc2 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,33 @@ 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;
+
+ /* SetVariable() won't change attributes, so drop any existing variable */
+ efi_set_variable("barebox-dtb", &efi_barebox_vendor_guid, 0, NULL, 0);
+
+ 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 445eaaa587d9..e553c4573ebe 100644
--- a/efi/payload/image.c
+++ b/efi/payload/image.c
@@ -117,6 +117,8 @@ int efi_execute_image(efi_handle_t handle,
*/
no_return = is_bootm || filetype_is_linux_efi_image(filetype);
+ efi_export_dtb();
+
if (options && *options) {
load_options = xstrdup_char_to_wchar(options);
loaded_image->load_options = load_options;
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