[RFC v2] bootstd: firmware-owned OS devicetree for EBBR / SystemReady IR

Ilias Apalodimas ilias.apalodimas at linaro.org
Fri Jul 3 13:48:55 CEST 2026


Hi Carlo,

On Fri, 3 Jul 2026 at 12:40, Carlo Caione <ccaione at baylibre.com> wrote:
>
> Hi all,
>
> This is v2 of a design RFC, not a patch series. v1 [1] proposed a mechanism
> for sourcing the OS devicetree from a firmware-owned partition; v2 refines the
> same design. The main change is that the devicetree set is now described by a
> firmware-owned FIT manifest carried on that partition, instead of by environment
> variables.
>
> This text is self-contained; you do not need to have read v1.
>
> A working implementation exists, with sandbox tests, and has been validated end
> to end on hardware in both the plain and the secure (signed) setup.
>
> 1. The problem
> ==============
>
> Platforms that follow EBBR / Arm SystemReady IR treat the OS devicetree as part

Not the OS devicetree. The devicetree. It should be a single entity
consumed by the firmware, os etc.

> of the firmware rather than part of the OS: the base DTB and its overlays live
> on a firmware-owned partition and are updated independently of the operating
> system, instead of being shipped in the OS image or on the EFI System Partition
> (ESP). The firmware is expected to load that devicetree and hand it to the OS
> (via the EFI configuration table).
>
> U-Boot today can source the OS devicetree from its own control DT, from the ESP,
> or from an EFI Boot#### load option, but it has no generic way to assemble it
> from a firmware-owned partition. As a result vendors carry out-of-tree machinery
> for exactly this.
>
> For example, MediaTek ships downstream 'dtbprobe' (assemble the DT from a
> partition) and 'fdt authndtb' (authenticate it) commands. The goal of this
> work is to provide one reusable, vendor-neutral mechanism in mainline so those
> downstream commands can be dropped.
>
>
> 2. What a solution has to do
> ============================
>
>   - Assemble the OS devicetree (a base DTB plus a list of overlays) from a
>     firmware-owned partition and install it for the OS.
>   - Install it on *every* EFI launch path, not just one. SystemReady IR boots
>     through the UEFI boot manager, which in U-Boot does not go through the
>     per-device EFI bootmeth, so a per-device-only hook is not enough.

This should be happening already
commit 7e624377e99 has some info

>   - Support secure boot: when the firmware devicetree is signed, verify it, and
>     never silently fall back to an unverified devicetree.
>   - Support A/B firmware partitions and per-SKU devicetree variants.
>
>
> 3. Proposed design
> ==================
>
> A bootstd helper, firmware_fdt_load() (CONFIG_BOOTSTD_FIRMWARE_FDT), assembles
> the devicetree from a FIT manifest on the firmware partition and returns it;
> the EFI launch paths install the result via efi_install_fdt(), exactly like any
> other devicetree source.
>
> 3.1 The manifest: describe and carry in one artefact
> ----------------------------------------------------
>
> The partition carries one FIT image (by default 'fdt.itb'). Its images hold
> the base DTB and the overlays; each of its configurations names one bootable
> combination through the standard 'fdt' property:
>
>         /dts-v1/;
>         / {
>                 description = "Firmware-owned OS devicetree";
>                 #address-cells = <1>;
>
>                 images {
>                         fdt-base {
>                                 data = /incbin/("board.dtb");
>                                 type = "flat_dt";
>                                 arch = "arm64";
>                                 compression = "none";
>                                 hash-1 { algo = "sha256"; };
>                         };
>                         fdt-panel {
>                                 data = /incbin/("panel.dtbo");
>                                 type = "flat_dt";
>                                 arch = "arm64";
>                                 compression = "none";
>                                 hash-1 { algo = "sha256"; };
>                         };
>                 };
>
>                 configurations {
>                         default = "conf-panel";
>                         conf-panel {
>                                 fdt = "fdt-base", "fdt-panel";
>                         };
>                         conf-base {
>                                 fdt = "fdt-base";
>                         };
>                 };
>         };
>
> The helper selects a configuration, verifies it, and assembles the devicetree
> by reusing boot_get_fdt_fit(), the same code path bootm already uses for
> FIT-carried devicetrees: multi-configuration selection, per-image verification,
> overlay application in the listed order, and packing of the result. No new
> format, parser, or crypto is introduced.
>
> The manifest must be self-contained: images must be 'flat_dt' with embedded
> data (external-data FITs are rejected) and must not carry a 'load' property
> (rejected, so a misbuilt manifest cannot overwrite arbitrary memory).
>
> 3.2 Where the partition is described (new binding)
> --------------------------------------------------
>
> The *location* is described in the control devicetree. The bootstd node carries
> a 'firmware-fdt-source' phandle to a node that is a child of the media device
> that owns the partition:

A lot of boards are building with  CONFIG_OF_UPSTREAM. Is this
something that wil be injected in the DT during build?

>
>         bootstd {
>                 compatible = "u-boot,boot-std";
>                 firmware-fdt-source = <&fw_fdt>;
>         };
>
>         &mmc0 {
>                 fw_fdt: firmware-fdt {
>                         compatible = "u-boot,firmware-fdt-block";
>                         partition-type-uuid = "....";   /* GPT type UUID */
>                         partition-name = "firmware";    /* optional */
>                         filename = "fdt.itb";           /* optional, the default */
>                 };
>         };
>
> The '-block' suffix names the backend: a block device with a GPT partition
> holding a filesystem. It leaves room for sibling backends later, e.g. an UBI/MTD
> variant for NOR-based boards.
>
> The partition is matched by GPT type UUID and/or name; when both are configured,
> both must match, so a misprovisioned disk fails instead of silently selecting
> whichever same-type (A/B) partition comes first.
>
> 3.3 Configuration selection: by compatible, not by filename
> -----------------------------------------------------------
>
> The primary selection mechanism is the compatible string, the way the
> FDT spec intends: with FIT_BEST_MATCH, the configuration whose devicetree
> best matches the compatible of U-Boot's control devicetree is chosen
> (fit_conf_find_compat()), falling back to the manifest's 'default'
> configuration. No filename names a devicetree anywhere; the only filename in
> the design is the manifest container itself, a fixed convention in the same way
> EFI/BOOT/BOOTAA64.EFI is.
>
> On top of that, two optional environment variables can override the choice:
>
>   - 'fw_fdt_config' names a specific FIT configuration (SKU selection);
>   - 'boot_dtb' pins a partition number, for A/B firmware partitions.
>
> All selection paths only choose among combinations the firmware author
> shipped; with signed configurations, a tampered value cannot select an unsigned
> combination. There is no other environment dependency: the description lives
> in the manifest and is updated atomically with the devicetrees it describes, so
> 'env default -a' cannot break the boot.
>
> 3.4 Where it is installed (every EFI launch path)
> -------------------------------------------------
>
> The helper is consumed by:
>
>   - the per-device EFI bootmeth (bootmeth_efi), on both its disk and its
>     network (PXE/DHCP) bootflow paths, so a TFTP server cannot substitute the OS
>     devicetree either; and
>   - the EFI boot manager (efi_bootmgr_run()), where the firmware devicetree is
>     tried first and outranks a Boot#### load-option FDT, so a stale or broken
>     load option can neither replace nor block it. An FDT explicitly passed on
>     the command line still wins.
>
> Each path installs the result through efi_install_fdt(), the convergence
> point all EFI launches pass through, so the firmware devicetree is installed
> regardless of how the EFI application is started, including the boot-manager
> autoboot path that SystemReady IR uses.

That path should be fine since it applies the local fixups before installing it.

> This is transparent to the EFI application: the devicetree sits in the EFI
> configuration table before the application starts. In particular, booting GRUB
> works unchanged: GRUB does not touch the table entry and the kernel's EFI stub
> consumes it.
>
> The assembled firmware devicetree is complete and authoritative: no other
> devicetree source is layered on top of it. In particular, extension-board
> (extension_scan()) overlays are intentionally not applied, since modifying
> the assembled (and, in secure mode, signed) devicetree would defeat the
> authenticated-combination model; such combinations should be shipped as manifest
> configurations instead.
>
> 3.5 Fail-closed error semantics
> -------------------------------
>
> Once a source is configured (the node is present), the result is deterministic.
> -ENOENT means *only* that no source is configured, in which case the caller
> falls back to its normal devicetree. Any other failure to assemble a configured
> source (unresolvable device, no matching partition, read error, invalid
> manifest, missing configuration, failed signature) is fatal for that EFI launch
> path: a missing or bad firmware devicetree is never silently replaced by another
> source. Error codes from inner layers that happen to be -ENOENT (for example
> a missing FIT configuration) are remapped before returning, so the fallback
> sentinel stays unambiguous.
>
> 3.6 Secure boot
> ---------------
>
> Signing a FIT configuration authenticates the whole combination: the base, the
> overlay set and its ordering are the signed unit. With FIT_SIGNATURE enabled
> and a required key in U-Boot's control devicetree, verification is enforced
> by the existing FIT policy code: an unsigned or tampered manifest is rejected,
> and because a configured source never falls back, the boot fails closed. There
> is no separate Kconfig option for this: FIT is the mechanism, and the usual
> verified-boot configuration turns enforcement on.
>
> Thanks for any feedback. I will follow up with the patch series once the
> binding and approach are agreed (or in a few days anyway :)
>
> Cheers,
>
> [1] https://lists.denx.de/pipermail/u-boot/2026-June/623429.html
>
>> Carlo Caione
>

Thanks
/Ilias


More information about the U-Boot mailing list