From: Tom Rini <trini@konsulko.com>
To: Carlo Caione <ccaione@baylibre.com>, Ahmad Fatoum <a.fatoum@barebox.org>
Cc: u-boot@lists.denx.de, sjg@chromium.org, xypron.glpk@gmx.de,
ilias.apalodimas@linaro.org, dlechner@baylibre.com,
jstephan@baylibre.com, baylibre-upstreaming@groups.io
Subject: Re: [RFC] bootstd: firmware-owned OS devicetree for EBBR / SystemReady IR
Date: Tue, 30 Jun 2026 16:41:37 -0600 [thread overview]
Message-ID: <20260630224137.GF749385@bill-the-cat> (raw)
In-Reply-To: <205BD474-178D-4E91-8C41-33C46E1CCFBB@baylibre.com>
[-- Attachment #1: Type: text/plain, Size: 9461 bytes --]
On Tue, Jun 30, 2026 at 09:20:13PM +0200, Carlo Caione wrote:
> Hi all,
>
> This is a design RFC, not a patch series. I would like to agree the approach
> and the devicetree binding on the list before posting code, because the
> mechanism touches both bootstd and the EFI loader and introduces a new binding.
>
> A working implementation exists and has been validated on hardware (details at
> the end); I will post it as patches once the design here is acceptable.
>
>
> 1. The problem
> ==============
>
> Platforms that follow EBBR / Arm SystemReady IR treat the OS devicetree as part
> 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.
> - 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.
>
>
> 3. Proposed design
> ===================
>
> A new bootstd helper, `firmware_fdt_load()` (`CONFIG_BOOTSTD_FIRMWARE_FDT`),
> assembles the devicetree and returns it; the EFI launch paths install it via
> `efi_install_fdt()`, exactly like any other devicetree source.
>
> 3.1 Where the source 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, and identifies the partition by GPT type UUID and/or
> name:
>
> 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 */
> extra-size = <0x3000>; /* overlay headroom */
> };
> };
>
> 3.2 The dynamic parameters (environment) and board defaults
> -----------------------------------------------------------
>
> The source and its partition policy stay in the control devicetree (section
> 3.1). The values that change with the OS image rather than with the hardware are
> layered:
>
> - the control DT describes the source and the partition policy;
> - the board default environment carries factory defaults for the static values
> (`fdtfile` and `dtb_path` for the base DTB, and the `fdt_addr_r` /
> `fdtoverlay_addr_r` working addresses), so a from-source build boots and
> `env default` restores a loadable configuration;
> - the (firmware-owned) stored environment overrides those at runtime, and
> carries the genuinely dynamic values: the overlay list (`list_dtbo`) and the
> A/B partition pin (`boot_dtb`).
>
> As an alternative, the stable defaults (`fdtfile` and the path) could instead be
> expressed as optional properties on the source node, keeping them in the control
> devicetree rather than in the board default environment. See the open questions.
>
> 3.3 Where it is installed (both EFI paths)
> ------------------------------------------
>
> The helper is consumed by both:
>
> - the per-device EFI bootmeth (`bootmeth_efi`), and
> - the EFI boot manager (`efi_bootmgr_run()`),
>
> each installing the result through `efi_install_fdt()`. That is the convergence
> point all EFI launches pass through, so the firmware devicetree is installed
> regardless of how the EFI application was started, including the boot-manager
> autoboot path that SystemReady IR uses.
>
> 3.4 Fail-closed error semantics
> -------------------------------
>
> Once a source is configured (the node is present), the result must be
> 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 blob, failed signature) is fatal for that EFI launch path: a
> missing or bad firmware devicetree is never silently replaced by another source.
> Missing environment metadata for a configured source is treated as a
> configuration error (fail closed, or satisfied from the board default), never as
> "no source".
>
> 3.5 Optional secure boot
> ------------------------
>
> With `CONFIG_BOOTSTD_FIRMWARE_FDT_FIT` the base DTB and overlays are signed FIT
> images. Each is verified by reusing U-Boot's existing verified-boot policy
> (`fit_image_load()` with verification enabled and a required key in the control
> FDT), and the verified flat devicetree is extracted in place. A non-FIT file is
> rejected so an unsigned devicetree cannot be installed. This reuses the existing
> trust model rather than adding new crypto, and replaces the downstream
> `fdt authndtb`.
>
>
> 4. Why these choices
> ====================
>
> - Describing the source in the control DT, as a child of the media device,
> follows the existing bootstd guidance ("if a bootdev needs configuration,
> add it to the DT as a child of the media device") and the VBE precedent. It
> keeps the mechanism generic: no GPT UUID or board constant in the C code.
> - Splitting identity (control DT) from dynamic values (environment) and static
> defaults (board default env) keeps the firmware in control of what changes
> per OS image, while still letting a plain `make <board>_defconfig` build
> boot.
> - Installing at `efi_install_fdt()` rather than in one bootmeth is what makes
> this SystemReady-IR-grade: the boot-manager path carries the firmware
> devicetree too. A per-device-only hook leaves the autoboot path on the
> control DT.
> - Fail-closed is required for secure boot: there must be no path where a
> configured, signed devicetree silently degrades to an unverified one.
> - Reusing `fit_image_load()` keeps a single, reviewed verified-boot path.
>
>
> 5. Alternatives considered
> ==========================
>
> - A global bootmeth ordered ahead of the EFI boot manager (a structure used in
> an earlier proof of concept). It works for autoboot but does not converge
> all launch paths; `efi_install_fdt()` is the real single point.
> - A per-device bootmeth hook only. Simpler, but misses the boot-manager
> autoboot path, which is the one SystemReady IR uses.
> - Keeping the mechanism vendor-specific (the status quo). Does not help anyone
> else and keeps the command out of tree.
>
>
> 6. Open questions for the list
> ==============================
>
> 1. Binding naming: are `firmware-fdt-source` and the `u-boot,firmware-fdt-block`
> compatible acceptable, and is the control-DT-described-source shape the one
> you want?
It probably shouldn't be "u-boot," because it's a more generic thing.
> 2. The configuration boundary. The proposal keeps the source and partition
> policy in the control DT, puts factory defaults for the filenames and the
> working addresses in the board default environment, and lets the
> firmware-owned stored environment override at runtime (and hold the dynamic
> `list_dtbo` / `boot_dtb`). An alternative is to express the stable defaults
> (`fdtfile`, a path) as optional properties on the source node, so they live
> in the control DT rather than the board environment. Which does the project
> prefer?
> 3. The `efi_bootmgr_run()` hook: is installing the firmware devicetree on the
> boot-manager path acceptable to the EFI maintainers, and is that the right
> place?
> 4. The fail-closed semantics: a configured source that cannot be assembled is
> fatal; only an absent source falls back. Agree?
> 5. Should the signed-FIT verification be part of this series or a follow-up?
>
> Thanks for any feedback. I will follow up with the patch series once the binding
> and approach are agreed.
I've added in Ahmad Fatoum from the barebox side, as this is a problem
that while the implementation will be bootloader specific, the details
will be generic.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
next prev parent reply other threads:[~2026-06-30 22:41 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-30 19:20 [RFC] bootstd: firmware-owned OS devicetree for EBBR / SystemReady IR Carlo Caione
2026-06-30 22:41 ` Tom Rini [this message]
2026-07-02 13:09 ` Simon Glass
2026-07-02 14:27 ` Carlo Caione
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=20260630224137.GF749385@bill-the-cat \
--to=trini@konsulko.com \
--cc=a.fatoum@barebox.org \
--cc=baylibre-upstreaming@groups.io \
--cc=ccaione@baylibre.com \
--cc=dlechner@baylibre.com \
--cc=ilias.apalodimas@linaro.org \
--cc=jstephan@baylibre.com \
--cc=sjg@chromium.org \
--cc=u-boot@lists.denx.de \
--cc=xypron.glpk@gmx.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