All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] bootstd: firmware-owned OS devicetree for EBBR / SystemReady IR
@ 2026-06-30 19:20 Carlo Caione
  2026-06-30 22:41 ` Tom Rini
  2026-07-02 13:09 ` Simon Glass
  0 siblings, 2 replies; 7+ messages in thread
From: Carlo Caione @ 2026-06-30 19:20 UTC (permalink / raw)
  To: u-boot
  Cc: sjg, xypron.glpk, ilias.apalodimas, trini, dlechner, jstephan,
	baylibre-upstreaming

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?
  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.

Cheers,

—
Carlo Caione


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] bootstd: firmware-owned OS devicetree for EBBR / SystemReady IR
  2026-06-30 19:20 [RFC] bootstd: firmware-owned OS devicetree for EBBR / SystemReady IR Carlo Caione
@ 2026-06-30 22:41 ` Tom Rini
  2026-07-02 13:09 ` Simon Glass
  1 sibling, 0 replies; 7+ messages in thread
From: Tom Rini @ 2026-06-30 22:41 UTC (permalink / raw)
  To: Carlo Caione, Ahmad Fatoum
  Cc: u-boot, sjg, xypron.glpk, ilias.apalodimas, dlechner, jstephan,
	baylibre-upstreaming

[-- 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 --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] bootstd: firmware-owned OS devicetree for EBBR / SystemReady IR
  2026-06-30 19:20 [RFC] bootstd: firmware-owned OS devicetree for EBBR / SystemReady IR Carlo Caione
  2026-06-30 22:41 ` Tom Rini
@ 2026-07-02 13:09 ` Simon Glass
  2026-07-02 14:27   ` Carlo Caione
  1 sibling, 1 reply; 7+ messages in thread
From: Simon Glass @ 2026-07-02 13:09 UTC (permalink / raw)
  To: Carlo Caione
  Cc: u-boot, xypron.glpk, ilias.apalodimas, trini, dlechner, jstephan,
	baylibre-upstreaming

Hi Carlo,

On Tue, 30 Jun 2026 at 20:20, Carlo Caione <ccaione@baylibre.com> 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.
>

For Mediatek specifically, I am hoping to eventually upstream support
for a load-only FIT (the spec supports it) so that you can load the DT
from a firmware partition, then still boot the OS (without a DT). This
works with FIT, but would need adjustment if the OS is actually an EFI
app.

I wrote a post about this challenge:

https://www-concept.deinde.dev/blog/devicetree-in-firmware-or-packaged-with-the-os/

>
> 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.

This sounds reasonable to me.

>
> 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";

Does the -block suffix indicate that it is a block device, rather than
a filesystem? How does this cope with the fast where multiple DTs are
provided for different models?

>                         partition-type-uuid = "....";   /* GPT type UUID */
>                         partition-name = "firmware";    /* optional */
>                         extra-size = <0x3000>;          /* overlay headroom */

This seems like a parameter which would be better handled by U-Boot itself?

>                 };
>         };
>
> 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;

I wish we could move away from filenames and use compatible strings
instead, as FIT does - this is how the FDT spec is written.

>   - 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.

What if you run GRUB?

>
> 3.4 Fail-closed error semantics
> -------------------------------
>
> Once a source is configured (the node is present), the result must be
> deterministic.

Yes, this is very important.

 `-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`.

OK.

>
>
> 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.

Agreed on all of these.

>
>
> 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?

Seems OK.

>   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?

See above...better to store a compatible string than a filename.

>   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?

Yes

>   5. Should the signed-FIT verification be part of this series or a follow-up?

You likely get this for free, so I suggest including it.

>
> Thanks for any feedback. I will follow up with the patch series once the binding
> and approach are agreed.

Regards,
Simon

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] bootstd: firmware-owned OS devicetree for EBBR / SystemReady IR
  2026-07-02 13:09 ` Simon Glass
@ 2026-07-02 14:27   ` Carlo Caione
  2026-07-09 19:15     ` Simon Glass
  0 siblings, 1 reply; 7+ messages in thread
From: Carlo Caione @ 2026-07-02 14:27 UTC (permalink / raw)
  To: Simon Glass
  Cc: u-boot, xypron.glpk, ilias.apalodimas, trini, dlechner, jstephan,
	baylibre-upstreaming

On Thu, Jul 2, 2026 at 3:09 PM Simon Glass <sjg@chromium.org> wrote:

> For Mediatek specifically, I am hoping to eventually upstream support
> for a load-only FIT (the spec supports it) so that you can load the DT
> from a firmware partition, then still boot the OS (without a DT). This
> works with FIT, but would need adjustment if the OS is actually an EFI
> app.
>
> I wrote a post about this challenge:
>
> https://www-concept.deinde.dev/blog/devicetree-in-firmware-or-packaged-with-the-os/

Well, this is convenient because your suggestion converges nicely with
where this work has gone since I posted the RFC (I was ready to send
out a V2 soon-ish).

v2 of this design replaces the environment-described file set with a
FIT manifest carried on the firmware partition itself: the FIT images
hold the base DTB and the overlays, and each FIT configuration names
one bootable combination through the standard 'fdt' property.

Not exactly sure what you mean with “load-only” but there no kernel in
it, the assembled devicetree is handed to the EFI app via the
configuration table.

v2 is implemented and validated on (my) hardware; I will post the
updated RFC shortly. Some of your comments below are already addressed
by it, noted inline.

> > 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";
>
> Does the -block suffix indicate that it is a block device, rather than
> a filesystem? How does this cope with the fast where multiple DTs are
> provided for different models?

The suffix names the backend: this one is 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, which some
MediaTek platforms would need. I will spell that out in the binding
text.

Multiple models are the manifest's job in v2: one FIT configuration
per model/SKU, so the per-model knowledge lives with the devicetrees
it describes and is updated atomically with them.

> >                         partition-type-uuid = "....";   /* GPT type UUID */
> >                         partition-name = "firmware";    /* optional */
> >                         extra-size = <0x3000>;          /* overlay headroom */
>
> This seems like a parameter which would be better handled by U-Boot itself?

Yup, and it is gone in v2.

> >   - 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;
>
> I wish we could move away from filenames and use compatible strings
> instead, as FIT does - this is how the FDT spec is written.

v2 does this. 'fdtfile' and 'dtb_path' are gone leveraging
FIT_BEST_MATCH. The only filename left is the manifest container
itself (fdt.itb by default), which is a fixed convention (we can
change it of course, I don't have a strong imagination).

> > 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.
>
> What if you run GRUB?

Not sure I 100% got this objection but it is not very special I guess,
the firmware devicetree is installed into the EFI configuration table
before the EFI app starts, GRUB does not touch it, and the kernel's
EFI stub picks it up
from the table (as long as GRUB does not install a different DTB at that point).

> >   5. Should the signed-FIT verification be part of this series or a follow-up?
>
> You likely get this for free, so I suggest including it.

Indeed, since now the manifest is a FIT.

I will post the v2 RFC as a follow-up to this thread.

thanks for the review,

--
Carlo Caione

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] bootstd: firmware-owned OS devicetree for EBBR / SystemReady IR
  2026-07-02 14:27   ` Carlo Caione
@ 2026-07-09 19:15     ` Simon Glass
  2026-07-10 10:51       ` Carlo Caione
  0 siblings, 1 reply; 7+ messages in thread
From: Simon Glass @ 2026-07-09 19:15 UTC (permalink / raw)
  To: Carlo Caione
  Cc: u-boot, xypron.glpk, ilias.apalodimas, trini, dlechner, jstephan,
	baylibre-upstreaming

Hi Carlo,

On Thu, 2 Jul 2026 at 08:27, Carlo Caione <ccaione@baylibre.com> wrote:
>
> On Thu, Jul 2, 2026 at 3:09 PM Simon Glass <sjg@chromium.org> wrote:
>
> > For Mediatek specifically, I am hoping to eventually upstream support
> > for a load-only FIT (the spec supports it) so that you can load the DT
> > from a firmware partition, then still boot the OS (without a DT). This
> > works with FIT, but would need adjustment if the OS is actually an EFI
> > app.
> >
> > I wrote a post about this challenge:
> >
> > https://www-concept.deinde.dev/blog/devicetree-in-firmware-or-packaged-with-the-os/
>
> Well, this is convenient because your suggestion converges nicely with
> where this work has gone since I posted the RFC (I was ready to send
> out a V2 soon-ish).
>
> v2 of this design replaces the environment-described file set with a
> FIT manifest carried on the firmware partition itself: the FIT images
> hold the base DTB and the overlays, and each FIT configuration names
> one bootable combination through the standard 'fdt' property.
>
> Not exactly sure what you mean with “load-only” but there no kernel in
> it, the assembled devicetree is handed to the EFI app via the
> configuration table.
>
> v2 is implemented and validated on (my) hardware; I will post the
> updated RFC shortly. Some of your comments below are already addressed
> by it, noted inline.
>
> > > 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";
> >
> > Does the -block suffix indicate that it is a block device, rather than
> > a filesystem? How does this cope with the fast where multiple DTs are
> > provided for different models?
>
> The suffix names the backend: this one is 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, which some
> MediaTek platforms would need. I will spell that out in the binding
> text.
>
> Multiple models are the manifest's job in v2: one FIT configuration
> per model/SKU, so the per-model knowledge lives with the devicetrees
> it describes and is updated atomically with them.
>
> > >                         partition-type-uuid = "....";   /* GPT type UUID */
> > >                         partition-name = "firmware";    /* optional */
> > >                         extra-size = <0x3000>;          /* overlay headroom */
> >
> > This seems like a parameter which would be better handled by U-Boot itself?
>
> Yup, and it is gone in v2.
>
> > >   - 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;
> >
> > I wish we could move away from filenames and use compatible strings
> > instead, as FIT does - this is how the FDT spec is written.
>
> v2 does this. 'fdtfile' and 'dtb_path' are gone leveraging
> FIT_BEST_MATCH. The only filename left is the manifest container
> itself (fdt.itb by default), which is a fixed convention (we can
> change it of course, I don't have a strong imagination).
>
> > > 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.
> >
> > What if you run GRUB?
>
> Not sure I 100% got this objection but it is not very special I guess,
> the firmware devicetree is installed into the EFI configuration table
> before the EFI app starts, GRUB does not touch it, and the kernel's
> EFI stub picks it up
> from the table (as long as GRUB does not install a different DTB at that point).

Just on this point, the question is really whether GRUB does not touch
it. My understand is that it actually loads the FDT from a file (Ilias
is the expert here) and that is why we have an EFI fix-up protocol to
send that loaded FDT back to U-Boot to be fixed up before booting.

>
> > >   5. Should the signed-FIT verification be part of this series or a follow-up?
> >
> > You likely get this for free, so I suggest including it.
>
> Indeed, since now the manifest is a FIT.
>
> I will post the v2 RFC as a follow-up to this thread.
>
> thanks for the review,
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] bootstd: firmware-owned OS devicetree for EBBR / SystemReady IR
  2026-07-09 19:15     ` Simon Glass
@ 2026-07-10 10:51       ` Carlo Caione
  2026-07-13 13:14         ` Simon Glass
  0 siblings, 1 reply; 7+ messages in thread
From: Carlo Caione @ 2026-07-10 10:51 UTC (permalink / raw)
  To: Simon Glass
  Cc: u-boot, xypron.glpk, ilias.apalodimas, trini, dlechner, jstephan,
	baylibre-upstreaming

On Thu, Jul 9, 2026 at 9:16 PM Simon Glass <sjg@chromium.org> wrote:

> Just on this point, the question is really whether GRUB does not touch
> it. My understand is that it actually loads the FDT from a file (Ilias
> is the expert here) and that is why we have an EFI fix-up protocol to
> send that loaded FDT back to U-Boot to be fixed up before booting.

Oh, ok, good point. Now, there are two cases:

1. If grub.cfg does not execute the `devicetree` command, GRUB uses
the firmware-provided FDT from the EFI configuration table. This is
the path I tested (most common in stock distro images?)
2. If grub.cfg executes `devicetree <file>`, GRUB loads that FDT and
can replace the configuration-table entry before starting Linux.
Debian/Ubuntu GRUB also carries the EFI_DT_FIXUP_PROTOCOL support, so
the loaded FDT is passed back to U-Boot before GRUB installs it.

The mechanism proposed in this RFC (V2) guarantees that the selected
and verified firmware FDT is the one presented to the initial EFI
application. It does not make that configuration-table entry immutable
after the EFI application starts. After all an EFI application can use
InstallConfigurationTable() directly, so trying to enforce
immutability in the firmware-FDT loader would not be sufficient in any
case.

BTW this also means that authentication of the firmware FIT covers the
DT provided by firmware, but not a later DT deliberately loaded by the
EFI boot manager (we cannot do much about that). The good news on this
front is that (AFAICT) in a Secure Boot configuration GRUB's
`devicetree` command is normally lockdown-restricted (but again that
is a policy enforced by GRUB rather than by this mechanism).

In general I think that is correct rather than a hole: same precedence
as passing a DT to bootefi, an explicit devicetree beats the firmware
default, and firmware cannot stop a loaded image from installing a
configuration table anyway.

Hope this works, cheers.

--
Carlo Caione

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] bootstd: firmware-owned OS devicetree for EBBR / SystemReady IR
  2026-07-10 10:51       ` Carlo Caione
@ 2026-07-13 13:14         ` Simon Glass
  0 siblings, 0 replies; 7+ messages in thread
From: Simon Glass @ 2026-07-13 13:14 UTC (permalink / raw)
  To: Carlo Caione
  Cc: u-boot, xypron.glpk, ilias.apalodimas, trini, dlechner, jstephan,
	baylibre-upstreaming

Hi Carlo,

On Fri, 10 Jul 2026 at 04:51, Carlo Caione <ccaione@baylibre.com> wrote:
>
> On Thu, Jul 9, 2026 at 9:16 PM Simon Glass <sjg@chromium.org> wrote:
>
> > Just on this point, the question is really whether GRUB does not touch
> > it. My understand is that it actually loads the FDT from a file (Ilias
> > is the expert here) and that is why we have an EFI fix-up protocol to
> > send that loaded FDT back to U-Boot to be fixed up before booting.
>
> Oh, ok, good point. Now, there are two cases:
>
> 1. If grub.cfg does not execute the `devicetree` command, GRUB uses
> the firmware-provided FDT from the EFI configuration table. This is
> the path I tested (most common in stock distro images?)
> 2. If grub.cfg executes `devicetree <file>`, GRUB loads that FDT and
> can replace the configuration-table entry before starting Linux.
> Debian/Ubuntu GRUB also carries the EFI_DT_FIXUP_PROTOCOL support, so
> the loaded FDT is passed back to U-Boot before GRUB installs it.
>
> The mechanism proposed in this RFC (V2) guarantees that the selected
> and verified firmware FDT is the one presented to the initial EFI
> application. It does not make that configuration-table entry immutable
> after the EFI application starts. After all an EFI application can use
> InstallConfigurationTable() directly, so trying to enforce
> immutability in the firmware-FDT loader would not be sufficient in any
> case.
>
> BTW this also means that authentication of the firmware FIT covers the
> DT provided by firmware, but not a later DT deliberately loaded by the
> EFI boot manager (we cannot do much about that). The good news on this
> front is that (AFAICT) in a Secure Boot configuration GRUB's
> `devicetree` command is normally lockdown-restricted (but again that
> is a policy enforced by GRUB rather than by this mechanism).
>
> In general I think that is correct rather than a hole: same precedence
> as passing a DT to bootefi, an explicit devicetree beats the firmware
> default, and firmware cannot stop a loaded image from installing a
> configuration table anyway.
>
> Hope this works, cheers.

Yes, this seems right to me, thanks for the write-up.

Regards,
SImon

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-07-13 13:15 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-30 19:20 [RFC] bootstd: firmware-owned OS devicetree for EBBR / SystemReady IR Carlo Caione
2026-06-30 22:41 ` Tom Rini
2026-07-02 13:09 ` Simon Glass
2026-07-02 14:27   ` Carlo Caione
2026-07-09 19:15     ` Simon Glass
2026-07-10 10:51       ` Carlo Caione
2026-07-13 13:14         ` Simon Glass

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.