[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