From: Douglas Anderson <dianders@chromium.org>
To: Devicetree-compiler@vger.kernel.org,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Konrad Dybcio <konradybcio@kernel.org>
Cc: linux-kbuild@vger.kernel.org,
"Brian Norris" <briannorris@chromium.org>,
"Catalin Marinas" <catalin.marinas@arm.com>,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
"Simon Glass" <sjg@chromium.org>,
"Chen-Yu Tsai" <wenst@chromium.org>,
linux-arm-msm@vger.kernel.org, "Nicolas Schier" <nsc@kernel.org>,
"Peter Griffin" <peter.griffin@linaro.org>,
"Nathan Chancellor" <nathan@kernel.org>,
"Tudor Ambarus" <tudor.ambarus@linaro.org>,
Devicetree@vger.kernel.org,
"Julius Werner" <jwerner@chromium.org>,
"Saravana Kannan" <saravanak@kernel.org>,
"Will Deacon" <will@kernel.org>,
"Michal Simek" <michal.simek@amd.com>,
"André Draszik" <andre.draszik@linaro.org>,
"Douglas Anderson" <dianders@chromium.org>,
"Andrew Jones" <andrew.jones@linux.dev>,
"Breno Leitao" <leitao@debian.org>,
"David Sterba" <dsterba@suse.com>, "Gary Guo" <gary@garyguo.net>,
"Josh Poimboeuf" <jpoimboe@kernel.org>,
"Luis Augenstein" <luis.augenstein@tngtech.com>,
"Marco Elver" <elver@google.com>,
"Mark Rutland" <mark.rutland@arm.com>,
"Masahiro Yamada" <masahiroy@kernel.org>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Nick Terrell" <terrelln@fb.com>,
"Peter Zijlstra" <peterz@infradead.org>,
"Rong Xu" <xur@google.com>,
"Thomas Weißschuh" <thomas.weissschuh@linutronix.de>,
devicetree@vger.kernel.org
Subject: [RFC PATCH 4/7] arm64: boot: Support building image.fit from a specified FIT_ITS script
Date: Tue, 20 Oct 2026 08:35:22 -0700 [thread overview]
Message-ID: <20261020083501.RFC.4.I5cd8aab4380bc4cfd302c4e4708af58c43370715@changeid> (raw)
In-Reply-To: <20261020153652.2907186-1-dianders@chromium.org>
Allow passing `FIT_ITS=<path>` on the make command line (relative to
either `$(srctree)` or `arch/arm64/boot/dts/`) when building `image.fit`
to assemble the FIT image from a checked-in `.its` script via `mkimage`
instead of auto-generating a FIT image with `scripts/make_fit.py`. When
`FIT_ITS` is not specified, `image.fit` continues to be built using
`scripts/make_fit.py` as before.
Supporting a checked-in `.its` script includes:
- Adding `cmd_lz4_frame` (`Image-framed.lz4` and `%.dtb.lz4`) for
standard LZ4 frame compression (magic `0x184d2204`) expected by FIT
bootloaders such as U-Boot and depthcharge, plus generic compressed
DTB rules (`bz2`, `gz`, `lz4`, `lzma`, `lzo`, `zst`, `xz`) in
`scripts/Makefile.dtbs`.
- Restricting `$(dtb-y)` to the DTBs referenced via `/incbin/(...)` in
`$(FIT_ITS)` and automatically building the referenced kernel image
target (e.g. `Image-framed.lz4`) and any compressed `.dtb.<ext>`
blobs.
- Populating any omitted `compatible` property on
`/configurations/conf-*` nodes in `cmd_fit_its` from the
corresponding uncompressed `.dtb`'s root `/compatible` property
using `fdtget` and `fdtput`. This is useful so we don't have to
manually keep the .its script in sync with the source. This is extra
important if compression is used since the bootloader may not be
able to easily peek into the device trees itself.
The main motivation for checking in an .its script instead of using an
auto-generated one is to be able to manually set the "description"
field of the configurations. This allows us to provide information that
the bootloader can use to figure out which configuration(s) to load.
This idea came from Michal Simek.
Assisted-by: Gemini:gemini-pro-prerelease
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
Makefile | 2 +-
arch/arm64/Makefile | 3 ++
arch/arm64/boot/Makefile | 9 ++++--
scripts/Makefile.dtbs | 43 ++++++++++++++++++++++++++++-
scripts/Makefile.lib | 59 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 111 insertions(+), 5 deletions(-)
diff --git a/Makefile b/Makefile
index 0dc1a9f4e63e..8c5500179e2e 100644
--- a/Makefile
+++ b/Makefile
@@ -2239,7 +2239,7 @@ clean: $(clean-dirs)
\( -name '*.[aios]' -o -name '*.rsi' -o -name '*.ko' -o -name '.*.cmd' \
-o -name '*.ko.*' -o -name '*.o.thinlto.bc' \
-o -name '*.dtb' -o -name '*.dtbo' \
- -o -name '*.dtb.S' -o -name '*.dtbo.S' \
+ -o -name '*.dtb.*' -o -name '*.dtbo.S' \
-o -name '*.dt.yaml' -o -name 'dtbs-list' \
-o -name '*.dwo' -o -name '*.lst' \
-o -name '*.su' -o -name '*.mod' \
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 6b005c8fef70..f9a25db9ae03 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -185,6 +185,9 @@ $(BOOT_TARGETS): vmlinux
Image.%: Image
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+Image-framed.%: Image
+ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
ifeq ($(CONFIG_COMPRESSED_INSTALL),y)
DEFAULT_KBUILD_IMAGE = $(KBUILD_IMAGE)
else
diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile
index b5a08333bc57..fe21bace3692 100644
--- a/arch/arm64/boot/Makefile
+++ b/arch/arm64/boot/Makefile
@@ -16,8 +16,8 @@
OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
-targets := Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo \
- Image.zst Image.xz image.fit
+targets := Image Image.bz2 Image.gz Image.lz4 Image-framed.lz4 Image.lzma \
+ Image.lzo Image.zst Image.xz image.fit
$(obj)/Image: vmlinux FORCE
$(call if_changed,objcopy)
@@ -31,6 +31,9 @@ $(obj)/Image.gz: $(obj)/Image FORCE
$(obj)/Image.lz4: $(obj)/Image FORCE
$(call if_changed,lz4)
+$(obj)/Image-framed.lz4: $(obj)/Image FORCE
+ $(call if_changed,lz4_frame)
+
$(obj)/Image.lzma: $(obj)/Image FORCE
$(call if_changed,lzma)
@@ -44,7 +47,7 @@ $(obj)/Image.xz: $(obj)/Image FORCE
$(call if_changed,xzkern)
$(obj)/image.fit: $(obj)/Image $(obj)/dts/dtbs-list FORCE
- $(call if_changed,fit)
+ $(if $(FIT_ITS_FILE),$(call if_changed,fit_its),$(call if_changed,fit))
EFI_ZBOOT_PAYLOAD := Image
EFI_ZBOOT_BFD_TARGET := elf64-littleaarch64
diff --git a/scripts/Makefile.dtbs b/scripts/Makefile.dtbs
index c4e466390284..1bc42b30cc52 100644
--- a/scripts/Makefile.dtbs
+++ b/scripts/Makefile.dtbs
@@ -5,6 +5,26 @@ all-dtb := $(dtb-y) $(dtb-)
# If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built
dtb-$(CONFIG_OF_ALL_DTBS) += $(dtb-)
+# If FIT_ITS is specified, restrict $(dtb-y) to only the DTBs referenced via
+# /incbin/(...) in $(FIT_ITS_FILE) and also build any compressed .dtb.<ext>
+# blobs referenced there alongside their base .dtb.
+ifdef FIT_ITS_FILE
+ifneq ($(filter arch/$(SRCARCH)/boot/dts%, $(obj)),)
+its-dtb-files := $(notdir $(shell $(call fit_its_incbin,\.dtb)))
+
+# Strip compression and .dtb suffixes to get stem names (e.g. "foo", "bar"),
+# then intersect with the stems in this directory's $(all-dtb).
+its-dtb-stems := $(patsubst %.dtb, %, \
+ $(filter %.dtb, $(its-dtb-files) $(basename $(its-dtb-files))))
+its-local-stems := $(filter $(patsubst %.dtb, %, $(all-dtb)), $(its-dtb-stems))
+
+# Build only the matching base .dtb files and any compressed .dtb.<ext> variants
+dtb-y := $(addsuffix .dtb, $(its-local-stems))
+its-dtb-comp := $(addprefix $(obj)/, \
+ $(foreach d, $(its-local-stems), $(filter $(d).dtb.%, $(its-dtb-files))))
+endif
+endif
+
# Composite DTB (i.e. DTB constructed by overlay)
multi-dtb-y := $(call multi-search, $(dtb-y), .dtb, -dtbs)
# Primitive DTB compiled from *.dts
@@ -23,7 +43,7 @@ dtb-y := $(addprefix $(obj)/, $(dtb-y))
multi-dtb-y := $(addprefix $(obj)/, $(multi-dtb-y))
real-dtb-y := $(addprefix $(obj)/, $(real-dtb-y))
-always-y += $(dtb-y)
+always-y += $(dtb-y) $(its-dtb-comp)
targets += $(real-dtb-y)
# dtbs-list
@@ -142,6 +162,27 @@ $(obj)/%.dtb: $(obj)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE
$(obj)/%.dtbo: $(src)/%.dtso $(DTC) FORCE
$(call if_changed_dep,dtc)
+$(obj)/%.dtb.bz2: $(obj)/%.dtb FORCE
+ $(call if_changed,bzip2)
+
+$(obj)/%.dtb.gz: $(obj)/%.dtb FORCE
+ $(call if_changed,gzip)
+
+$(obj)/%.dtb.lz4: $(obj)/%.dtb FORCE
+ $(call if_changed,lz4_frame)
+
+$(obj)/%.dtb.lzma: $(obj)/%.dtb FORCE
+ $(call if_changed,lzma)
+
+$(obj)/%.dtb.lzo: $(obj)/%.dtb FORCE
+ $(call if_changed,lzo)
+
+$(obj)/%.dtb.zst: $(obj)/%.dtb FORCE
+ $(call if_changed,zstd)
+
+$(obj)/%.dtb.xz: $(obj)/%.dtb FORCE
+ $(call if_changed,xzmisc)
+
# targets
# ---------------------------------------------------------------------------
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 0a4fdd8bd975..91880648fe21 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -383,9 +383,16 @@ quiet_cmd_lzo = LZO $@
quiet_cmd_lzo_with_size = LZO $@
cmd_lzo_with_size = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@
+# cmd_lz4 uses -l (legacy format, magic 0x184c2102) required by the kernel's
+# in-tree decompressor (lib/decompress_unlz4.c). Bootloaders that decompress
+# FIT images (such as U-Boot and depthcharge) require the standard LZ4 frame
+# format (magic 0x184d2204, without -l), provided by cmd_lz4_frame.
quiet_cmd_lz4 = LZ4 $@
cmd_lz4 = cat $(real-prereqs) | $(LZ4) -l -9 - - > $@
+quiet_cmd_lz4_frame = LZ4 $@
+ cmd_lz4_frame = $(LZ4) -12 -z -f -q $< $@
+
quiet_cmd_lz4_with_size = LZ4 $@
cmd_lz4_with_size = { cat $(real-prereqs) | $(LZ4) -l -9 - -; \
$(size_append); } > $@
@@ -429,6 +436,58 @@ quiet_cmd_fit = FIT $@
$(if $(FIT_DECOMPOSE_DTBS),--decompose-dtbs) \
--compress $(FIT_COMPRESSION) -k $< @$(word 2,$^)
+# If FIT_ITS is specified on the command line (either relative to $(srctree)
+# or relative to arch/$(SRCARCH)/boot/dts/), locate that .its script and
+# define a helper to extract /incbin/("...") paths from it.
+ifdef FIT_ITS
+FIT_ITS_FILE := $(firstword $(wildcard \
+ $(FIT_ITS) \
+ $(srctree)/$(FIT_ITS) \
+ $(srctree)/arch/$(SRCARCH)/boot/dts/$(FIT_ITS)))
+ifeq ($(FIT_ITS_FILE),)
+$(error FIT_ITS '$(FIT_ITS)' not found)
+endif
+
+# Extract /incbin/("...") path(s) from $(FIT_ITS_FILE).
+# $(1): optional pattern to match inside the /incbin/("...") path
+# $(2): optional image node name to restrict the search to
+fit_its_incbin = sed -n \
+ "$(if $(2),/^[[:space:]]*$(2)[[:space:]]*{/$(comma)/\/incbin\//) \
+ s|.*/incbin/(\"\([^\"]*$(1)[^\"]*\)\").*|\1|p" \
+ $(FIT_ITS_FILE)
+
+ifneq ($(filter image.fit,$(targets)),)
+FIT_ITS_IMAGES := $(addprefix $(obj)/, \
+ $(notdir $(shell $(call fit_its_incbin,Image))))
+FIT_ITS_DTBS := $(addprefix $(objtree)/, \
+ $(shell $(call fit_its_incbin,\.dtb)))
+$(obj)/image.fit: $(FIT_ITS_IMAGES) $(FIT_ITS_DTBS) $(FIT_ITS_FILE)
+endif
+endif
+
+# Build the FIT image from the .its script with mkimage and populate any
+# missing 'compatible' property on /configurations/conf-* nodes from the
+# corresponding uncompressed .dtb's root '/compatible' property using
+# fdtget/fdtput.
+quiet_cmd_fit_its = FIT $@
+ cmd_fit_its = \
+ PATH="$(abspath $(objtree))/scripts/dtc:$(PATH)"; \
+ $(BASH) $(MKIMAGE) \
+ -D "-I dts -O dtb -i $(objtree) -i $(srctree)" \
+ -f $(FIT_ITS_FILE) $@; \
+ configs=$$(fdtget -l $@ /configurations); \
+ for c in $$configs; do \
+ conf=/configurations/$$c; \
+ if [ -n "$$(fdtget -d '' $@ $$conf compatible)" ]; then \
+ continue; \
+ fi; \
+ fdt=$$(fdtget $@ $$conf fdt); \
+ inc=$$($(call fit_its_incbin,\.dtb,$$fdt)); \
+ dtb="$(objtree)/$${inc%.dtb*}.dtb"; \
+ compat=$$(fdtget -ts "$$dtb" / compatible); \
+ fdtput -ts $@ $$conf compatible $$compat; \
+ done
+
# XZ
# ---------------------------------------------------------------------------
# Use xzkern or xzkern_with_size to compress the kernel image and xzmisc to
--
2.56.0.212.g129ede20d9-goog
next prev parent reply other threads:[~2026-10-20 15:37 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-20 15:35 [RFC PATCH 0/7] arm64: Add fit images for sc7180-trogdor and google,lga Douglas Anderson
2026-10-20 15:35 ` [RFC PATCH 1/7] scripts/dtc: Add fdtget.c and fdtput.c to sync script Douglas Anderson
2026-10-20 15:35 ` [RFC PATCH 2/7] scripts/dtc: Update to upstream version v1.8.1-22-gf3451d12532b Douglas Anderson
2026-10-20 15:35 ` [RFC PATCH 3/7] scripts/dtc: Build fdtget and fdtput host tools Douglas Anderson
2026-10-20 15:35 ` Douglas Anderson [this message]
2026-10-20 15:35 ` [RFC PATCH 5/7] kbuild: fit: Add opt-in FIT_FACTOR_DTBS support using fdtfactor Douglas Anderson
2026-10-20 15:35 ` [RFC PATCH 6/7] arm64: dts: google: lga: Add lga.its FIT image script Douglas Anderson
2026-10-20 15:35 ` [RFC PATCH 7/7] arm64: dts: qcom: sc7180: Add sc7180-trogdor.its " Douglas Anderson
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=20261020083501.RFC.4.I5cd8aab4380bc4cfd302c4e4708af58c43370715@changeid \
--to=dianders@chromium.org \
--cc=Devicetree-compiler@vger.kernel.org \
--cc=Devicetree@vger.kernel.org \
--cc=andre.draszik@linaro.org \
--cc=andrew.jones@linux.dev \
--cc=briannorris@chromium.org \
--cc=catalin.marinas@arm.com \
--cc=conor+dt@kernel.org \
--cc=dsterba@suse.com \
--cc=elver@google.com \
--cc=gary@garyguo.net \
--cc=jpoimboe@kernel.org \
--cc=jwerner@chromium.org \
--cc=konradybcio@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=leitao@debian.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kbuild@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luis.augenstein@tngtech.com \
--cc=mark.rutland@arm.com \
--cc=masahiroy@kernel.org \
--cc=michal.simek@amd.com \
--cc=nathan@kernel.org \
--cc=nsc@kernel.org \
--cc=ojeda@kernel.org \
--cc=peter.griffin@linaro.org \
--cc=peterz@infradead.org \
--cc=robh@kernel.org \
--cc=saravanak@kernel.org \
--cc=sjg@chromium.org \
--cc=terrelln@fb.com \
--cc=thomas.weissschuh@linutronix.de \
--cc=tudor.ambarus@linaro.org \
--cc=wenst@chromium.org \
--cc=will@kernel.org \
--cc=xur@google.com \
/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
all inboxes | Powered by JetHome®