Hi,

On Tue, 29 Sept 2026 at 13:03, Quentin Schulz <[email protected]> wrote:
>
>
>
> On 9/29/26 1:03 PM, Alexey Charkov wrote:
> > On Tue, Sep 29, 2026 at 2:29 PM Quentin Schulz <[email protected]> 
> > wrote:
> >>
> >> Hi Alexey,
> >>
> >> On 9/28/26 6:44 PM, Alexey Charkov wrote:
> >>> On Mon, Sep 28, 2026 at 7:53 PM Quentin Schulz <[email protected]> 
> >>> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 9/28/26 4:03 PM, Alexey Charkov wrote:
> >>>>> Hi Quentin,
> >>>>>
> >>>>> On Mon, Sep 28, 2026 at 5:26 PM Quentin Schulz 
> >>>>> <[email protected]> wrote:
> >>>>>>
> >>>>>> Hi Alexey,
> >>>>>>
> >>>>>> On 7/31/26 7:10 PM, Alexey Charkov wrote:
> >>>>>>> When a generated FIT is used to boot Linux directly, bypassing U-Boot
> >>>>>>> proper (Falcon mode), there is no runtime code to discover the kernel
> >>>>>>> command line and (optional) initrd location and include them in a FDT.
> >>>>>>>
> >>>>>>> To facilitate easier preparation of a ready-to-boot FIT, add support 
> >>>>>>> for
> >>>>>>> pre-patching the FDTs in a FIT with a preconfigured /chosen node 
> >>>>>>> including
> >>>>>>> the bootargs and initrd location.
> >>>>>>>
> >>>>>>
> >>>>>> This sounds wrong to me. Why should we hardcode those at build time? We
> >>>>>> already do DT fixups in U-Boot proper *at runtime*, so we should
> >>>>>> probably do the same in xPL when booting in Falcon mode instead of
> >>>>>> hardcoding stuff. Since you're aware of this, I'm guessing you decided
> >>>>>> against, but you don't tell us why. I'm a bit worried going with the
> >>>>>> suggested implementation means we'll eventually have a binman node
> >>>>>> property for each DT node/property we want to write/override.
> >>>>>
> >>>>> The "regular" Falcon way of doing things (i.e. the one not involving
> >>>>> TF-A) has so far been: "capture what U-Boot patches into the args to
> >>>>> be passed to the kernel, package it into a fixed binary, and boot only
> >>>>> that". No runtime fixups. So I more or less followed that pattern, but
> >>>>> tried to make it a bit more accessible by eliminating the "capture
> >>>>> something at runtime and save it somehow somewhere" step, which I find
> >>>>> unnecessarily painful.
> >>>>>
> >>>>> Maybe runtime fixups could be brought into xPL, but they are
> >>>>> excruciatingly slow, whereas speed is the main reason for wanting
> >>>>> Falcon mode boot in the first place. Right now with Falcon mode on
> >>>>> RK3576 I'm getting 2.5 seconds from applying power to _userspace_
> >>>>> (i.e. full graphical UI drawn on the screen), whereas the best I could
> >>>>> get with U-Boot is just over 3s to its boot menu, much of that time
> >>>>> spent going over the flat devicetree before relocation in O(n^2)
> >>>>> passes. And those 3s are after stripping the massive pinctrl node with
> >>>>> hundreds of its always-present children from the pre-relocation DT,
> >>>>> which alone saves ~0.4s.
> >>>>>
> >>>>
> >>>> Are they always present, even with /omit-if-no-ref/ instruction? Or
> >>>> maybe you're building the device trees with -@? Trying to figure out if
> >>>> somehow we have a bug in dtc (or in our scripts making use of it).
> >>>
> >>> The problem is that there are a lot of `status = "disabled";` device
> >>> nodes referencing pinctrl nodes, which keep dtc from dropping them
> >>> altogether, so a lot of unused pin configs end up in the binary -
> >>> enough to be noticeable in boot time.
> >>>
> >>
> >> And we cannot really get rid of the status = "disabled" nodes as they
> >> may be switched to "enabled" for some reason at runtime by e.g. U-Boot I
> >> guess? I'm wondering if this (stripping all nodes which are disabled) is
> >> something we could still allow (e.g. gated by a Kconfig symbol).
> >
> > Yes, stripping those entirely would break DT overlays and runtime
>
> Base DT for overlays need to be compiled with -@ so you have all symbols
> available, this is something we could detect (presence of /__symbols__
> node IIRC) and bail out...
>
> > board fixups (e.g. what I do for the Flipper One to switch between
> > SATA/PCIe pin modes based on the M.2 key B config pins strapping).
> >
>
> but that would also prevent that kind of things and since you actually
> are already impacted by this, the hack I suggested isn't appealing anyway.
>
> >  From what I understood while investigating those boot delays, it's the
> > linear FDT representation in (uncached) pre-relocation memory what
> > kills performance when the count of nodes grows to real-world numbers.
> > Having a more efficient data structure to hold the tree
> > pre-relocation, or enabling D-cache pre-relocation, would both speed
> > it up considerably - perhaps more so than trimming the tree itself.
> > But going down that road sounds a bit scary.
> >
>
> No experience with cache so big scary word to me indeed ;)
>
> >>>> Don't we have FDT and DM in SPL anyway as that's how we probe drivers in
> >>>> that stage (not counting the few SPL-only boards we have)?
> >>>
> >>> SPL's DTB is tiny due to bootph-* markup (it was just 27 nodes last
> >>> time I counted for my RK3576 use case). Making SPL parse the whole
> >>> OS-oriented device tree, along with all the relocations required to
> >>> insert stuff at runtime, will hurt.
> >>>
> >>
> >> Ah yes, missed that.
> >>
> >>>> I don't have anything better to suggest, I'm just really worried about
> >>>> the potential ballooning of properties we need to mirror in binman.
> >>>>
> >>>>>>> Signed-off-by: Alexey Charkov <[email protected]>
> >>>>>>> ---
> >>>>>>>      tools/binman/entry.py     |   8 ++++
> >>>>>>>      tools/binman/etype/fit.py | 103 
> >>>>>>> ++++++++++++++++++++++++++++++++++++++++++++++
> >>>>>>>      2 files changed, 111 insertions(+)
> >>>>>>>
> >>>>>>> diff --git a/tools/binman/entry.py b/tools/binman/entry.py
> >>>>>>> index ce7ef28e94b1..e0dea8bf3a49 100644
> >>>>>>> --- a/tools/binman/entry.py
> >>>>>>> +++ b/tools/binman/entry.py
> >>>>>>> @@ -636,6 +636,14 @@ class Entry(object):
> >>>>>>>              self.Detail('GetData: size %s' % to_hex_size(self.data))
> >>>>>>>              return self.data
> >>>>>>>
> >>>>>>> +    def GetNode(self):
> >>>>>>> +        """Get the devicetree node which describes this entry
> >>>>>>> +
> >>>>>>> +        Returns:
> >>>>>>> +            Node: Node for this entry
> >>>>>>> +        """
> >>>>>>> +        return self._node
> >>>>>>> +
> >>>>>>>          def GetPaddedData(self, data=None):
> >>>>>>>              """Get the data for an entry including any padding
> >>>>>>>
> >>>>>>> diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py
> >>>>>>> index 32caa03a7e16..750ff5b47ed5 100644
> >>>>>>> --- a/tools/binman/etype/fit.py
> >>>>>>> +++ b/tools/binman/etype/fit.py
> >>>>>>> @@ -304,6 +304,40 @@ class Entry_fit(Entry_section):
> >>>>>>>
> >>>>>>>          See :ref:`fdtgrep_filter` for more information.
> >>>>>>>
> >>>>>>> +    Patching /chosen into the generated device trees
> >>>>>>> +    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >>>>>>> +
> >>>>>>> +    When the OS is booted directly from this FIT (e.g. Falcon mode) 
> >>>>>>> U-Boot
> >>>>>>> +    proper never runs, so its usual runtime /chosen fixups do not 
> >>>>>>> happen. Two
> >>>>>>> +    optional properties on the `@fdt-SEQ` node make binman patch 
> >>>>>>> each generated
> >>>>>>> +    device tree at build time:
> >>>>>>> +
> >>>>>>> +    fit,bootargs
> >>>>>>> +        A string written to /chosen/bootargs of every generated 
> >>>>>>> device tree
> >>>>>>> +        (any existing value is overwritten). Typically set to 
> >>>>>>> `CONFIG_BOOTARGS`
> >>>>>>> +        via the preprocessed devicetree source.
> >>>>>>> +
> >>>>>>> +    fit,initrd
> >>>>>>> +        The image name of a loadable (e.g. "ramdisk") to use as the 
> >>>>>>> initramfs.
> >>>>>>> +        Its `load` address and packed size are written to
> >>>>>>> +        /chosen/linux,initrd-start and /chosen/linux,initrd-end (at 
> >>>>>>> the width of
> >>>>>>> +        the device tree's root #address-cells) and reserved in the 
> >>>>>>> FDT
> >>>>>>> +        memory-reservation map, mirroring fdt_initrd(). If the 
> >>>>>>> referenced image
> >>>>>>> +        is absent or empty (e.g. an optional initramfs that was not 
> >>>>>>> supplied)
> >>>>>>> +        the initrd properties are omitted.
> >>>>>>> +
> >>>>>>
> >>>>>> This sounds wrong, why would the FDT image node need to know about 
> >>>>>> which
> >>>>>> ramdisk may be used? Shouldn't we rather have a ramdisk property in a
> >>>>>> configuration node, and then patch the FDT based on that information?
> >>>>>
> >>>>> Falcon mode boot where these are useful is for a fixed-configuration
> >>>>> boot flow anyway, where one wouldn't have a way to select among
> >>>>
> >>>> How do you plan on doing A/B with Falcon boot? How do you know from
> >>>> which partition the kernel you booted originated so you don't upgrade on
> >>>> the currently booted partition? There must be some way for U-Boot SPL to
> >>>> tell the kernel at runtime where it came from?
> >>>
> >>> I don't currently do A/B with Falcon; instead, I rely on the fallback
> >>> to U-Boot, and U-Boot in turn loads from a UFS boot W-LU (which is A/B
> >>> native). Making A/B work with Falcon would be a nice follow-up, but I
> >>
> >> This means supporting two completely different boot flows with potential
> >> side effects (U-Boot proper probing/breaking stuff while Falcon mode
> >> doesn't).
> >
> > Yep, not ideal. It's all heavy work in progress, so I might still
> > rethink the whole approach more than once :)
> >
> >>> believe it will require some external metadata to choose the active
> >>> boot source anyway - and then the same external metadata can be used
> >>> for the upgrade. Such as the UFS device attributes, or whatever people
> >>> use for RAUC and such.
> >>>
> >>
> >> I guess you could use a U-Boot environment for that or some more secure
> >> location (via OP-TEE/TPM, etc...).
> >
> > RPMB with the key managed via OP-TEE backed by hardware secure OTP and
> > on-chip crypto would have been great, but it's a mighty detour from
> > where we currently stand, so I'm leaving that for desserts :)
> >
> >>>>> several ramdisks to go with the kernel image. So putting this
> >>>>> information directly where the user (i.e. the kernel) will find it
> >>>>> cuts out intermediate steps, which in turn improves speed and reduces
> >>>>> complexity.
> >>>>
> >>>> You already have:
> >>>>
> >>>> fit,firmware = "atf-1", "kernel", "ramdisk";
> >>>> fdt = "fdt-SEQ";
> >>>>
> >>>> in the configuration node. So simply have binman derive from
> >>>> fit,firmware which node is included of type "ramdisk" and fixup the
> >>>> device trees in fdt-SEQ based on that info? Less user-prone IMO.
> >>>
> >>> Ah, I thought you were referring to runtime FDT fixups based on the
> >>> selected configuration. Patching it in using binman based on the
> >>> configuration node contents should work, too, but what's the practical
> >>> benefit? It would still use the same ramdisk node, just written in a
> >>> different place - or am I missing something?
> >>>
> >>
> >> Not written in a different place, written in the only place it already
> >> is, removing the need for duplicating the info which the user shouldn't
> >> have to do.
> >
> > I think I start getting what you mean, let me see if I can indeed make
> > binman infer which "ramdisk" should go for "ramdisk" and write the
> > attributes based on that :)
> >
>
> I'll try to be more concise/explicit next time. Trying to review too
> many things for different projects at once at the moment so I sometimes
> just do "brain to fingers" without putting much more thoughts into it.
>
> >> Re: fit,bootargs, can't you simply have the property included in your
> >> -u-boot.dtsi directly, so we don't have to have yet another binman
> >> option? I understand this won't work well if we separate binman from
> >> U-Boot like talked in a different thread, but we are not there yet.
> >
> > That would mean rewriting the .dtsi every time the bootargs need to
> > change, which in this setup is just an (already existing) Kconfig
> > option. The property is also not useful for U-Boot proper, which would
> > inherit it via -u-boot.dtsi. Plus, I'd rather not make the whole
> > Falcon thing too board-specific, as then it makes trying it out on a
> > different board way more pain than strictly necessary.
> >
>
> You could reuse the Kconfig option in the dtsi. But ACK, no perfect
> solution it seems so far.

A few vague thoughts:

1. If binman finds the ramdisk from the configuration, note that an
FDT image can be shared by several configurations with different
ramdisks (or none). In that case there is no single correct /chosen,
so binman should probably raise an error rather than letting the last
one win.

2. To avoid adding a binman property for each fixup, how about
allowing a 'chosen' subnode in the FDT image node, whose properties
are merged into each generated DTB?

       @fdt-SEQ {
           ...
           chosen {
               bootargs = CONFIG_BOOTARGS;
           };
       };

That keeps it out of U-Boot proper's DT and still comes from Kconfig.
The initrd properties would then be the only special case. We would
need to update the FIT spec.

3. We don't support decompression for ramdisk - linux,initrd-end and
the memreserve use the packed size, so it  might be nice to have a
test to ensure U-Boot rejects that.

Regards,
Simon

Reply via email to