mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: fpg@pengutronix.de, chalianis1@gmail.com,
	Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH RFT 3/4] efi: payload: export device tree in barebox-dtb EFI variable
Date: Wed, 26 Aug 2026 14:15:31 +0200	[thread overview]
Message-ID: <20260826121640.2936023-4-a.fatoum@pengutronix.de> (raw)
In-Reply-To: <20260826121640.2936023-1-a.fatoum@pengutronix.de>

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@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




  parent reply	other threads:[~2026-08-26 12:17 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-26 12:15 [PATCH RFT 0/4] efi: payload: allow extension via fragments Ahmad Fatoum
2026-08-26 12:15 ` [PATCH RFT 1/4] efi: payload: ignore ESP state.dtb if device tree is populated Ahmad Fatoum
2026-08-26 12:15 ` [PATCH RFT 2/4] kbuild: dtc: introduce empty fallback device tree Ahmad Fatoum
2026-08-26 12:15 ` Ahmad Fatoum [this message]
2026-08-26 12:15 ` [PATCH RFT 4/4] Documentation: efi: describe device tree handling Ahmad Fatoum
2026-08-26 22:56 ` [PATCH RFT 0/4] efi: payload: allow extension via fragments chalianis1
2026-08-27  7:31   ` Ahmad Fatoum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260826121640.2936023-4-a.fatoum@pengutronix.de \
    --to=a.fatoum@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    --cc=chalianis1@gmail.com \
    --cc=fpg@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox