Re: [PATCH v4] boot/bootfdt: Add smbios3-entrypoint to FDT for non-EFI boots

Heinrich Schuchardt xypron.glpk at gmx.de
Thu Nov 20 07:49:14 CET 2025


Am 19. November 2025 19:46:40 MEZ schrieb Adriana Nicolae <adriana at arista.com>:
>From: adriana <adriana at arista.com>
>
>The Linux kernel can discover SMBIOS tables through two primary methods:
>1. Via EFI tables, when using EFI boot;
>2. Via the 'smbios3-entrypoint' property in the /chosen node of the
>device tree.
>
>When U-Boot boots a Linux kernel using a non-EFI command ("bootm",
>"bootz", or "booti"), the kernel relies on the device tree to detect
>the hardware. If SMBIOS tables are available in U-Boot, they should
>be passed to the kernel via this device tree property.
>
>This patch modifies boot_fdt_prepare(), to inject the SMBIOSv3 table
>address into the device tree if there is a table generated by U-boot.
>The "board_fdt_chosen_smbios" is weak in order to leave the possibilty
>for specific boards to select custom SMBIOS addresses.
>
>The changes in this patch are added in the context of supporting this
>device tree property in linux kernel:
>https://lkml.org/lkml/2025/10/24/1393
>
>Device tree schema was updated to include the "smbios3-entrypoint" node
>in pull request: https://github.com/devicetree-org/dt-schema/pull/177
>
>Signed-off-by: Adriana Nicolae <adriana at arista.com>
>---
>Changes in v4:
>  - Remove weak function board_fdt_chosen_smbios(), replace with
>    gd_smbios_start();
>  - Return -EAGAIN in test if GENERATE_SMBIOS_TABLE is not enabled;
>  - Remove unnecessary fdt cleanup at the end of the test;
>  - Added missing newlines at the end of the modified files.
>
>Changes in v3:
>  - Moved "board_fdt_chosen_smbios" function to lib/smbios.c
>  - Return physical address of smbios entry and use map_sysmem to
>    access the entry point;
>  - Removed check for config enabled and added check for
>    GENERATE_SMBIOS_TABLE;
>  - Add test to check that smbios entry address is added into fdt;
>
>Changes in v2:
>  - Renamed device tree property to "smbios3-entrypoint".
>  - Removed redundant check for CONFIG_SMBIOS.
>---
> boot/fdt_support.c | 19 ++++++++++++++++++
> test/dm/fdtdec.c   | 48 ++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 67 insertions(+)
>
>diff --git a/boot/fdt_support.c b/boot/fdt_support.c
>index 92f2f534ee0..1c215e548db 100644
>--- a/boot/fdt_support.c
>+++ b/boot/fdt_support.c
>@@ -27,6 +27,7 @@
> #include <fdtdec.h>
> #include <version.h>
> #include <video.h>
>+#include <smbios.h>
> 
> DECLARE_GLOBAL_DATA_PTR;
> 
>@@ -333,6 +334,7 @@ int fdt_chosen(void *fdt)
> 	int   nodeoffset;
> 	int   err;
> 	const char *str;		/* used to set string properties */
>+	ulong smbiosaddr;		/* SMBIOS table address */
> 
> 	err = fdt_check_header(fdt);
> 	if (err < 0) {
>@@ -387,6 +389,23 @@ int fdt_chosen(void *fdt)
> 		return err;
> 	}
> 
>+	if (CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) {
>+		/* Inject SMBIOS address when we have a valid address.
>+		* This is useful for systems using booti/bootm instead of bootefi.
>+		* Failure to set this property is non-fatal, we only generate a
>+		* warning.
>+		*/
>+		smbiosaddr = gd_smbios_start();
>+		if (smbiosaddr) {
>+			err = fdt_setprop_u64(fdt, nodeoffset, "smbios3-entrypoint",
>+					smbiosaddr);
>+			if (err < 0) {
>+				printf("WARNING: could not set smbios3-entrypoint %s.\n",
>+				fdt_strerror(err));
>+			}
>+		}
>+	}
>+
> 	return fdt_fixup_stdout(fdt, nodeoffset);
> }
> 
>diff --git a/test/dm/fdtdec.c b/test/dm/fdtdec.c
>index 1f24f1d5dff..1744211d4d1 100644
>--- a/test/dm/fdtdec.c
>+++ b/test/dm/fdtdec.c
>@@ -7,6 +7,9 @@
> #include <asm/global_data.h>
> #include <dm/of_extra.h>
> #include <dm/test.h>
>+#include <fdt_support.h>
>+#include <mapmem.h>
>+#include <smbios.h>
> #include <test/ut.h>
> 
> DECLARE_GLOBAL_DATA_PTR;
>@@ -129,3 +132,48 @@ static int dm_test_fdtdec_add_reserved_memory(struct unit_test_state *uts)
> }
> DM_TEST(dm_test_fdtdec_add_reserved_memory,
> 	UTF_SCAN_PDATA | UTF_SCAN_FDT | UTF_FLAT_TREE);
>+
>+static int dm_test_fdt_chosen_smbios(struct unit_test_state *uts)
>+{
>+	void *blob;
>+	ulong val;
>+	struct smbios3_entry *entry;
>+	int chosen, blob_sz;
>+	const fdt64_t *prop;
>+
>+	if (!CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) {
>+		return -EAGAIN;
>+	}
>+
>+	blob_sz = fdt_totalsize(gd->fdt_blob) + 128;

This is very tight. Depending on the architecture more properties may be injected. 4 KiB is a safe value.

>+	blob = malloc(blob_sz);

Device-trees must be 8 byte aligned.

Please, consider using memalign(blob_sz, 8).

Best regards

Heinrich


>+	ut_assertnonnull(blob);
>+
>+	/* Make a writable copy of the fdt blob */
>+	ut_assertok(fdt_open_into(gd->fdt_blob, blob, blob_sz));
>+
>+	/* Mock SMBIOS table */
>+	entry = map_sysmem(gd->arch.smbios_start, sizeof(struct smbios3_entry));
>+	memcpy(entry->anchor, "_SM3_", 5);
>+	entry->length = sizeof(struct smbios3_entry);
>+	unmap_sysmem(entry);
>+
>+	/* Force fdt_chosen to run */
>+	ut_assertok(fdt_chosen(blob));
>+
>+	chosen = fdt_path_offset(blob, "/chosen");
>+	ut_assert(chosen >= 0);
>+
>+	/* Verify the property exists */
>+	prop = fdt_getprop(blob, chosen, "smbios3-entrypoint", NULL);
>+	ut_assertnonnull(prop);
>+
>+	/* Verify the property matches smbios_start */
>+	val = fdt64_to_cpu(*prop);
>+	ut_asserteq_64(gd->arch.smbios_start, val);
>+
>+	free(blob);
>+
>+	return 0;
>+}
>+DM_TEST(dm_test_fdt_chosen_smbios, UTF_SCAN_PDATA | UTF_SCAN_FDT);



More information about the U-Boot mailing list