[PATCH v2] boot/bootfdt: Add smbios3-entrypoint to FDT for non-EFI boots
Heinrich Schuchardt
xypron.glpk at gmx.de
Sun Nov 16 09:56:41 CET 2025
On 11/15/25 12:15, Adriana Nicolae wrote:
> 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 v2:
> - Renamed device tree property to "smbios3-entrypoint".
> - Removed redundant check for CONFIG_SMBIOS, ifdef is needed as
> "smbios_start" is not compiled on some platforms if !CONFIG_SMBIOS.
> ---
> boot/fdt_support.c | 57 +++++++++++++++++++++++++++++++++++++++++++
> include/fdt_support.h | 10 ++++++++
Please, add a test.
> 2 files changed, 67 insertions(+)
>
> diff --git a/boot/fdt_support.c b/boot/fdt_support.c
> index 92f2f534ee0..f3b8d6fc389 100644
> --- a/boot/fdt_support.c
> +++ b/boot/fdt_support.c
> @@ -327,12 +327,54 @@ __weak const char *board_fdt_chosen_bootargs(const struct fdt_property *fdt_ba)
> return env_get("bootargs");
> }
>
> +/**
> + * board_fdt_chosen_smbios - boards may override this function to provide
> + * specific SMBIOS address
> + */
> +__weak phys_addr_t board_fdt_chosen_smbios(void)
Consider moving this function to lib/smbios.c. Then it will only be
compiled if CONFIG_GENERATE_SMBIOS_TABLE=y.
> +{
> + phys_addr_t ret = 0;
Addresses in the device-tree must be usable as pointers.
Using the virtual address space of the sandbox is incorrect.
> + const struct smbios3_entry *entry;
> +
> + /* Only provide SMBIOS address if EFI is not enabled */
> + if (IS_ENABLED(CONFIG_EFI_LOADER))
> + return 0;
This check looks conceptually wrong:
If CONFIG_EFI_LOADER=y, we could still boot via the booti command
bypassing EFI. In this case we want to provide the SMBIOS address via
the /chosen node.
> +
> + /* Only proceed if SMBIOS support is compiled in */
> +#ifdef CONFIG_GENERATE_SMBIOS_TABLE
> + ret = gd->arch.smbios_start;
Here you need map_sysmem() to get the pointer to the entry point.
> + if (!ret)
> + return 0;
> +
> + /* Verify this is SMBIOS 3 */
> + entry = (struct smbios3_entry *)(uintptr_t)ret;
> +
> + /* Check for "_SM3_" signature */
> + if (memcmp(entry->anchor, "_SM3_", 5) != 0) {
> + printf("SMBIOS: Not version 3, skipping DTB injection\n");
> + return 0;
> + }
> +
> + /* Verify entry point length and version */
> + if (entry->length < sizeof(struct smbios3_entry)) {
> + printf("SMBIOS: Invalid entry length %d\n", entry->length);
> + return 0;
> + }
> +
> + printf("SMBIOS: Found version %d.%d at 0x%llx\n",
> + entry->major_ver, entry->minor_ver, (u64)ret);
> +#endif /* CONFIG_GENERATE_SMBIOS_TABLE */
> +
> + return ret;
> +}
> +
> int fdt_chosen(void *fdt)
> {
> struct abuf buf = {};
> int nodeoffset;
> int err;
> const char *str; /* used to set string properties */
> + phys_addr_t smbiosaddr; /* SMBIOS table address */
>
> err = fdt_check_header(fdt);
> if (err < 0) {
> @@ -387,6 +429,21 @@ int fdt_chosen(void *fdt)
> return err;
> }
>
> + /* 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.
> + */
Please, add
if (CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE))
to minimize the code size.
Best regards
Heinrich
> + smbiosaddr = board_fdt_chosen_smbios();
> + 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/include/fdt_support.h b/include/fdt_support.h
> index 47b8b63d13d..ddb8a36cc71 100644
> --- a/include/fdt_support.h
> +++ b/include/fdt_support.h
> @@ -240,6 +240,16 @@ int board_rng_seed(struct abuf *buf);
> */
> const char *board_fdt_chosen_bootargs(const struct fdt_property *fdt_ba);
>
> +/**
> + * board_fdt_chosen_smbios() - Provide SMBIOS address for /chosen node
> + *
> + * This function is called by fdt_chosen() to get the SMBIOS table address
> + * that should be added to the /chosen node for non-UEFI boot scenarios.
> + *
> + * Return: Physical address of SMBIOS table, or 0 if not available
> + */
> +phys_addr_t board_fdt_chosen_smbios(void);
> +
> /**
> * ft_board_setup_ex() - Latest board-specific FDT changes
> *
More information about the U-Boot
mailing list