Re: [PATCH v9 2/2] arm64: boot: Support Flat Image Tree

From: Chen-Yu Tsai
Date: Tue Jan 09 2024 - 22:48:11 EST


On Tue, Jan 9, 2024 at 9:47 PM Masahiro Yamada <masahiroy@xxxxxxxxxx> wrote:
>
> On Fri, Dec 29, 2023 at 3:39 PM Simon Glass <sjg@xxxxxxxxxxxx> wrote:
> >
> > Hi Masahiro,
> >
> > On Thu, Dec 14, 2023 at 7:34 AM Masahiro Yamada <masahiroy@xxxxxxxxxx> wrote:
> > >
> > > On Thu, Dec 14, 2023 at 3:12 PM Masahiro Yamada <masahiroy@xxxxxxxxxx> wrote:
> > > >
> > > > On Thu, Dec 14, 2023 at 1:03 PM Chen-Yu Tsai <wenst@xxxxxxxxxxxx> wrote:
> > > > >
> > > > > On Sun, Dec 10, 2023 at 1:31 AM Geert Uytterhoeven <geert@xxxxxxxxxxxxxx> wrote:
> > > > > >
> > > > > > Hi Laurent,
> > > > > >
> > > > > > On Sat, Dec 9, 2023 at 4:29 PM Laurent Pinchart
> > > > > > <laurent.pinchart@xxxxxxxxxxxxxxxx> wrote:
> > > > > > > On Sat, Dec 09, 2023 at 10:13:59PM +0900, Chen-Yu Tsai wrote:
> > > > > > > > On Thu, Dec 7, 2023 at 11:38 PM Laurent Pinchart
> > > > > > > > <laurent.pinchart@xxxxxxxxxxxxxxxx> wrote:
> > > > > > > > > On Thu, Dec 07, 2023 at 10:27:23PM +0800, Chen-Yu Tsai wrote:
> > > > > > > > > > On Sun, Dec 03, 2023 at 05:34:01PM +0200, Laurent Pinchart wrote:
> > > > > > > > > > > On Fri, Dec 01, 2023 at 08:54:42PM -0700, Simon Glass wrote:
> > > > > > > > > > > > Add a script which produces a Flat Image Tree (FIT), a single file
> > > > > > > > > > > > containing the built kernel and associated devicetree files.
> > > > > > > > > > > > Compression defaults to gzip which gives a good balance of size and
> > > > > > > > > > > > performance.
> > > > > > > > > > > >
> > > > > > > > > > > > The files compress from about 86MB to 24MB using this approach.
> > > > > > > > > > > >
> > > > > > > > > > > > The FIT can be used by bootloaders which support it, such as U-Boot
> > > > > > > > > > > > and Linuxboot. It permits automatic selection of the correct
> > > > > > > > > > > > devicetree, matching the compatible string of the running board with
> > > > > > > > > > > > the closest compatible string in the FIT. There is no need for
> > > > > > > > > > > > filenames or other workarounds.
> > > > > > > > > > > >
> > > > > > > > > > > > Add a 'make image.fit' build target for arm64, as well. Use
> > > > > > > > > > > > FIT_COMPRESSION to select a different algorithm.
> > > > > > > > > > > >
> > > > > > > > > > > > The FIT can be examined using 'dumpimage -l'.
> > > > > > > > > > > >
> > > > > > > > > > > > This features requires pylibfdt (use 'pip install libfdt'). It also
> > > > > > > > > > > > requires compression utilities for the algorithm being used. Supported
> > > > > > > > > > > > compression options are the same as the Image.xxx files. For now there
> > > > > > > > > > > > is no way to change the compression other than by editing the rule for
> > > > > > > > > > > > $(obj)/image.fit
> > > > > > > > > > > >
> > > > > > > > > > > > While FIT supports a ramdisk / initrd, no attempt is made to support
> > > > > > > > > > > > this here, since it must be built separately from the Linux build.
> > > > > > > > > > >
> > > > > > > > > > > FIT images are very useful, so I think this is a very welcome addition
> > > > > > > > > > > to the kernel build system. It can get tricky though: given the
> > > > > > > > > > > versatile nature of FIT images, there can't be any
> > > > > > > > > > > one-size-fits-them-all solution to build them, and striking the right
> > > > > > > > > > > balance between what makes sense for the kernel and the features that
> > > > > > > > > > > users may request will probably lead to bikeshedding. As we all love
> > > > > > > > > > > bikeshedding, I thought I would start selfishly, with a personal use
> > > > > > > > > > > case :-) This isn't a yak-shaving request though, I don't see any reason
> > > > > > > > > > > to delay merging this series.
> > > > > > > > > > >
> > > > > > > > > > > Have you envisioned building FIT images with a subset of DTBs, or adding
> > > > > > > > > > > DTBOs ? Both would be fairly trivial extensions to this script by
> > > > > > > > > > > extending the supported command line arguments. It would perhaps be more
> > > > > > > > > > > difficult to integrate in the kernel build system though. This leads me
> > > > > > > > > > > to a second question: would you consider merging extensions to this
> > > > > > > > > > > script if they are not used by the kernel build system, but meant for
> > > > > > > > > > > users who manually invoke the script ? More generally, is the script
> > > > > > > > > >
> > > > > > > > > > We'd also be interested in some customization, though in a different way.
> > > > > > > > > > We imagine having a rule file that says X compatible string should map
> > > > > > > > > > to A base DTB, plus B and C DTBO for the configuration section. The base
> > > > > > > > > > DTB would carry all common elements of some device, while the DTBOs
> > > > > > > > > > carry all the possible second source components, like different display
> > > > > > > > > > panels or MIPI cameras for instance. This could drastically reduce the
> > > > > > > > > > size of FIT images in ChromeOS by deduplicating all the common stuff.
> > > > > > > > >
> > > > > > > > > Do you envision the "mapping" compatible string mapping to a config
> > > > > > > > > section in the FIT image, that would bundle the base DTB and the DTBOs ?
> > > > > > > >
> > > > > > > > That's exactly the idea. The mapping compatible string could be untied
> > > > > > > > from the base board's compatible string if needed (which we probably do).
> > > > > > > >
> > > > > > > > So something like:
> > > > > > > >
> > > > > > > > config {
> > > > > > > > config-1 {
> > > > > > > > compatible = "google,krane-sku0";
> > > > > > > > fdt = "krane-baseboard", "krane-sku0-overlay";
> > > > > > > > };
> > > > > > > > };
> > > > > > > >
> > > > > > > > With "krane-sku0-overlay" being an overlay that holds the differences
> > > > > > > > between the SKUs, in this case the display panel and MIPI camera (not
> > > > > > > > upstreamed) that applies to SKU0 in particular.
> > > > > > >
> > > > > > > The kernel DT makefiles already contain information on what overlays to
> > > > > > > apply to what base boards, in order to test the overlays and produce
> > > > > > > "full" DTBs. Maybe that information could be leveraged to create the
> > > > > > > configurations in the FIT image ?
> > > > > >
> > > > > > Although the "full" DTBs created may only be a subset of all possible
> > > > > > combinations (I believe Rob just started with creating one "full" DTB
> > > > > > for each overlay, cfr. the additions I made in commit a09c3e105a208580
> > > > > > ("arm64: dts: renesas: Apply overlays to base dtbs")), that could
> > > > > > definitely be a start.
> > > > > >
> > > > > > Now, since the kernel build system already creates "full" DTBs, does
> > > > > > that mean that all of the base DTBs, overlays, and "full" DTBs will
> > > > > > end up in the FIT image?
> > > > >
> > > > > I suppose we could add an option to the packing tool to be able to _not_
> > > > > add the "full" DTBs if they can also be assembled with a base DTB and
> > > > > overlays. Think of it as a firmware compatibility option: if the firmware
> > > > > supports overlays, then you almost always want the deconstructed parts,
> > > > > not the fully assembled ones. Vice versa.
> > > > >
> > > > > If we don't we could end up with two configurations that have the same
> > > > > compatible string?
> > > >
> > > >
> > > > Right.
> > > >
> > > > We would end up with such situations because applying
> > > > an overlay does not change the compatible string.
> > > >
> > > >
> > > >
> > > > With this code in arch/arm64/boot/dts/ti/Makefile:
> > > >
> > > > k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
> > > > k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
> > > > k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
> > > > k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
> > > >
> > > >
> > > >
> > > >
> > > > $ fdtdump arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb
> > > > 2>/dev/null| head -n15 | tail -n2
> > > > model = "TQ-Systems TQMa64xxL SoM on MBax4xxL carrier board";
> > > > compatible = "tq,am642-tqma6442l-mbax4xxl", "tq,am642-tqma6442l",
> > > > "ti,am642";
> > > >
> > > >
> > > > $ fdtdump arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl-wlan.dtb
> > > > 2>/dev/null| head -n15 | tail -n2
> > > > model = "TQ-Systems TQMa64xxL SoM on MBax4xxL carrier board";
> > > > compatible = "tq,am642-tqma6442l-mbax4xxl", "tq,am642-tqma6442l",
> > > > "ti,am642";
> > > >
> > > >
> > > >
> > > >
> > > >
> > > > These two go into image.fit, but one of them is completely dead
> > > > since there is no way to distinguish them.
> > > >
> > > >
> > > > $ fdtdump arch/arm64/boot/image.fit
> > > >
> > > > ...
> > > >
> > > > conf-10 {
> > > > compatible = "tq,am642-tqma6442l-mbax4xxl",
> > > > "tq,am642-tqma6442l", "ti,am642";
> > > > description = "TQ-Systems TQMa64xxL SoM on MBax4xxL carrier board";
> > > > fdt = "fdt-10";
> > > > kernel = "kernel";
> > > > };
> > > >
> > > > ...
> > > >
> > > > conf-25 {
> > > > compatible = "tq,am642-tqma6442l-mbax4xxl",
> > > > "tq,am642-tqma6442l", "ti,am642";
> > > > description = "TQ-Systems TQMa64xxL SoM on MBax4xxL carrier board";
> > > > fdt = "fdt-25";
> > > > kernel = "kernel";
> > > > };
> > > >
> > > >
> > > >
> > > >
> > > >
> > > > I agree with Chen-Yu.
> > > >
> > > > FIT should not include full DTBs.
> > > >
> > > > Bootloaders should assemble the final DTB
> > > > from base and overlays on-the-fly.
> > > >
> > > >
> > > > The FIT spec allows the "fdt" property to list
> > > > multiple image nodes.
> > > >
> > > >
> > > > o config-1
> > > > |- description = "configuration description"
> > > > |- kernel = "kernel sub-node unit name"
> > > > |- fdt = "fdt sub-node unit-name" [, "fdt overlay sub-node unit-name", ...]
> > > > |- loadables = "loadables sub-node unit-name"
> > > > |- script = "
> > > > |- compatible = "vendor
> > >
> > >
> > >
> > >
> > >
> > > This is a question for U-Boot (and barebox).
> > >
> > >
> > >
> > >
> > > images {
> > > base {
> > > ...
> > > };
> > >
> > > addon1 {
> > > ...
> > > };
> > >
> > > addon2 {
> > > ...
> > > };
> > > };
> > >
> > > configurations {
> > > ...
> > > fdt = "base", "addon1", "addon2";
> > > };
> > >
> > >
> > >
> > >
> > > Is U-Boot's "bootm" command able to dynamically construct
> > > the full DTB from "base" + "addon1" + "addon2"
> > > and pass to the kernel?
> > >
> > >
> > >
> > > When I used overlay from U-Boot command line last time,
> > > I typed complicated commands, following this manual:
> > > https://docs.u-boot.org/en/latest/usage/fdt_overlays.html
> > >
> > >
> >
> > So far this is not possible with bootm, no. But if we can add
> > extensions to the FIT spec, then it should be possible to implement
> > this.
> >
> > Is it (or will it be) possible to get Linux to build the DT + overlay
> > combinations?
>
>
> As Chen-Yu replied, dtb files specified in the -dtbs syntax in Makefiles
> are assembled at build time using fdtoverlay.
>
> Once they are built, you will never know how they are built
> unless you parse Makefiles.
>
> Your script simply picks up *.dtb files found under arch/*/boot/dts/.
> There are three possibilities in *.dtb files:
>
> [1] *.dtb assembled from other base and overlays
> [2] *.dtb directly compiled from a single *.dts
> [3] *.dtb meant to be used as a base of overlay,
> but not meant for direct use.
>
>
> It would be challenging to include only appropriate *.dtb
> (and *.dtbo) files into the FIT image.

Irrespective of how and which DTB files are built, I think it would help
if we could decouple the compatible string in the configuration node from
the compatible string in the DTB.

Many of the overlays currently in-tree are extensions of a given board,
enabling a certain feature. Same could be said for all the out-of-tree
Raspberry Pi overlays. Fundamentally it is still the same board, and
the DTB's compatible shouldn't change. However the compatible string
in the configuration node is only used by the firmware for selection
purposes. It could be much more expansive including the extension
features.

We could have an extra config file that lists DTB files to exclude from
the FIT image, and replacement compatible strings for the configuration
node for certain DTB files.

Using an in-tree example: instead of "gw,imx8mm-gw73xx-0x" mapping to
imx8mm-venice-gw73xx-0x-*.dtb in addition to the base DT file
imx8mm-venice-gw73xx-0x.dtb, each could be mapped to a different
extension compatible, so "gw,imx8mm-gw73xx-0x-imx219" would map to
imx8mm-venice-gw73xx-0x-imx219.dtb.

How these configuration compatible strings should be defined is another
matter...

> I wrote the following patch set, which might be useful
> to address this issue.
>
> https://lore.kernel.org/linux-kbuild/20240109120738.346061-1-masahiroy@xxxxxxxxxx/T/#t

I think this would help with selecting between the combined DTB vs base DTB
plus DTBO overlays, and perhaps automatic exclusion of combined DTBs when
board compatibles collide. But I do think device vendors and maintainers
would want the extra flexibility I illustrated above.


Regards
ChenYu

> > > One more question to confirm if I can use this
> > > for my practical use-cases.
> > >
> > > Is U-Boot able to handle FIT (includes kernel + DTs)
> > > and a separate initrd?
> > >
> > > # bootm <fit-address>:<conf-name> <ramdisk-address>
> > >
> > >
> > > Presumably, it would be difficult to inject initramdisk
> > > into image.fit later, so I am hoping bootm would work like that,
> > > but I did not delve into U-Boot code.
> > >
> > >
> >
> > The ramdisk is handled by the FIT configuration. I suppose it would be
> > possible to add a way to bypass the logic in select_ramdisk(), but I
> > wonder what is the use case for this?
>
>
> I believe ramdisk is likely used to boot the arm64 Linux system.
>
> Since the FIT image generated by this lacks ramdisk,
> it looks useless to me unless there is a way to pass a ramdisk somehow.
>
>
> Barebox is good because it already supports FIT + separate ramdisk.
>
> I usually use U-Boot for my work, so I need to inject a ramdisk
> if I want to use this patch.
>
>
>
>
> > >
> > > If it works, is it possible to verify the integrity of initrd?
> > > The kernel and DTs inside FIT will be verified, but not sure
> > > if it is possible for ramdisk.
> >
> > I do have thoughts about a possible new FIT feature to allow external
> > files, which could perhaps include an initrd.
> >
> > Regards,
> > Simon
> >
>
>
> --
> Best Regards
> Masahiro Yamada