* [RFC PATCH v2 2/5] kbuild: fit: Support selecting DTBs and config properties from a file
2026-11-13 21:09 [RFC PATCH v2 0/5] arm64: Add FIT configurations for sc7180-trogdor and google,lga Douglas Anderson
2026-11-13 21:09 ` [RFC PATCH v2 1/5] kbuild: fit: Document FIT_COMPRESSION and FIT_DECOMPOSE_DTBS Douglas Anderson
@ 2026-11-13 21:09 ` Douglas Anderson
2026-11-13 21:09 ` [RFC PATCH v2 3/5] kbuild: fit: Add opt-in FIT_FACTOR_DTBS support using fdtfactor Douglas Anderson
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Douglas Anderson @ 2026-11-13 21:09 UTC (permalink / raw)
To: Devicetree-compiler, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Konrad Dybcio
Cc: linux-arm-msm, Julius Werner, Michal Simek, André Draszik,
linux-arm-kernel, Simon Glass, Peter Griffin, linux-kbuild,
Tudor Ambarus, Chen-Yu Tsai, Will Deacon, Nathan Chancellor,
Devicetree, Catalin Marinas, Nicolas Schier, linux-kernel,
Saravana Kannan, Brian Norris, Douglas Anderson, Alice Ryhl,
Jonathan Corbet, Josh Poimboeuf, Lorenzo Stoakes (ARM),
Manuel Ebner, Marco Elver, Mark Rutland, Mauro Carvalho Chehab,
Peter Zijlstra (Intel),
Randy Dunlap, Rong Xu, Shuah Khan, devicetree, linux-doc
Allow passing `FIT_CONFIG=<path>` on the make command line (relative to
either `$(srctree)` or `arch/$(SRCARCH)/boot/dts/`) when building
`image.fit` to select which DTBs are built and included in the FIT image
and to optionally set properties or subnodes on each
`/configurations/conf-N` node.
The `.fitconfig` file uses standard INI syntax parsed by Python's
`configparser` module:
- `#` starts a comment.
- Each `[<dtb-name>.dtb]` section header specifies a `.dtb` filename
(relative to the directory containing the `.fitconfig` file), starting
a new FIT configuration entry.
- Optional `<prop> = <value>` lines inside a section set or override
properties on that `/configurations/conf-N` node, or on a child
subnode when `<subnode>/<prop> = <value>` is used (for example, adding
a `match-1` subnode with board/SoC matching properties per [1]).
Unquoted integer literals (such as `0x070406` or `123`) are written as
32-bit integer cells; all other values (including values enclosed in
double quotes) are written as strings. Any configuration that does not
override `description` or `compatible` continues to inherit `/model`
and `/compatible` from the DTB.
When `FIT_CONFIG` is specified, `scripts/Makefile.lib` invokes
`scripts/make_fit.py --list-dtbs` to obtain the list of DTBs to build,
`scripts/Makefile.dtbs` restricts `$(dtb-y)` (including `make dtbs` and
`make dtbs_install`) to those DTBs, and `cmd_fit` passes `--config
$(FIT_CONFIG_FILE)` to `scripts/make_fit.py`.
The main motivation for this is to allow associating per-board matching
metadata with each configuration [1] and restricting the FIT image to a
specific family of boards without needing a hand-written `.its` file or
`mkimage`.
[1] https://github.com/open-source-firmware/flat-image-tree/pull/66
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
Changes in v2:
- Replace FIT_ITS + mkimage + fdtget/fdtput approach with FIT_CONFIG
.fitconfig sidecar files handled directly by scripts/make_fit.py
(Simon Glass)
- Support subnode properties (e.g. match-1/...) and u32 integer values
for the proposed FIT configuration match subnode spec (Simon Glass)
- Document FIT_CONFIG in Documentation/kbuild/kbuild.rst and under
image.fit in arm64 'make help' (Simon Glass)
Documentation/kbuild/kbuild.rst | 7 ++
arch/arm64/Makefile | 3 +-
scripts/Makefile.dtbs | 9 +++
scripts/Makefile.lib | 25 +++++++
scripts/make_fit.py | 117 ++++++++++++++++++++++++++++----
5 files changed, 146 insertions(+), 15 deletions(-)
diff --git a/Documentation/kbuild/kbuild.rst b/Documentation/kbuild/kbuild.rst
index 744a32ccbd1c..80cac4c432e4 100644
--- a/Documentation/kbuild/kbuild.rst
+++ b/Documentation/kbuild/kbuild.rst
@@ -376,3 +376,10 @@ FIT_DECOMPOSE_DTBS
If set to a non-empty value when building ``image.fit``, decompose composite
DTBs (built from a base ``.dtb`` plus ``.dtbo`` overlays) into their component
blobs and deduplicate them in the FIT.
+
+FIT_CONFIG
+----------
+Path to a ``.fitconfig`` configuration file (relative to ``$(srctree)`` or
+``arch/$(SRCARCH)/boot/dts/``) selecting which DTBs to build and include in
+``image.fit`` and optionally setting properties or subnodes on each
+``/configurations/conf-N`` node.
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 8818d6a2015b..b4982e94f80a 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -223,7 +223,8 @@ define archhelp
echo '* Image.gz - Compressed kernel image (arch/$(ARCH)/boot/Image.gz)'
echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
echo ' image.fit - Flat Image Tree (arch/$(ARCH)/boot/image.fit)'
- echo ' Configured by FIT_COMPRESSION and FIT_DECOMPOSE_DTBS'
+ echo ' Configured by FIT_COMPRESSION, FIT_DECOMPOSE_DTBS,'
+ echo ' and FIT_CONFIG'
echo ' install - Install kernel (compressed if COMPRESSED_INSTALL set)'
echo ' zinstall - Install compressed kernel'
echo ' Install using (your) ~/bin/installkernel or'
diff --git a/scripts/Makefile.dtbs b/scripts/Makefile.dtbs
index c4e466390284..cc14fc905ea3 100644
--- a/scripts/Makefile.dtbs
+++ b/scripts/Makefile.dtbs
@@ -5,6 +5,15 @@ 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_CONFIG is specified, restrict $(dtb-y) to only the DTBs listed in
+# $(FIT_CONFIG_FILE).
+ifdef FIT_CONFIG_FILE
+ifneq ($(filter arch/$(SRCARCH)/boot/dts%, $(obj)),)
+dtb-y := $(filter $(all-dtb), \
+ $(patsubst $(obj)/%, %, $(filter $(obj)/%, $(FIT_CONFIG_DTBS))))
+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
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 19e96b30a122..e08e35d4ed74 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -427,8 +427,33 @@ quiet_cmd_fit = FIT $@
--name '$(UIMAGE_NAME)' $(FIT_EXTRA_ARGS) \
$(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \
$(if $(FIT_DECOMPOSE_DTBS),--decompose-dtbs) \
+ $(if $(FIT_CONFIG_FILE),--config $(FIT_CONFIG_FILE)) \
--compress $(FIT_COMPRESSION) -k $< @$(word 2,$^)
+# If FIT_CONFIG is specified on the command line (either relative to $(srctree)
+# or relative to arch/$(SRCARCH)/boot/dts/), locate that file and extract the
+# list of .dtb files to build.
+ifdef FIT_CONFIG
+FIT_CONFIG_REL := $(firstword $(patsubst $(abs_srctree)/%,%,\
+ $(patsubst $(srctree)/%,%,$(patsubst ./%,%,$(wildcard \
+ $(FIT_CONFIG) \
+ $(srctree)/$(FIT_CONFIG) \
+ $(srctree)/arch/$(SRCARCH)/boot/dts/$(FIT_CONFIG))))))
+ifeq ($(FIT_CONFIG_REL),)
+$(error FIT_CONFIG '$(FIT_CONFIG)' not found)
+endif
+FIT_CONFIG_FILE := $(srctree)/$(FIT_CONFIG_REL)
+ifndef FIT_CONFIG_DTBS
+export FIT_CONFIG_DTBS := $(addprefix $(dir $(FIT_CONFIG_REL)), \
+ $(shell $(MAKE_FIT) -C $(FIT_CONFIG_FILE) --list-dtbs))
+$(if $(FIT_CONFIG_DTBS),,$(error Failed to parse DTB list from $(FIT_CONFIG_FILE)))
+endif
+
+ifneq ($(filter image.fit,$(targets)),)
+$(obj)/image.fit: $(FIT_CONFIG_FILE)
+endif
+endif
+
# XZ
# ---------------------------------------------------------------------------
# Use xzkern or xzkern_with_size to compress the kernel image and xzmisc to
diff --git a/scripts/make_fit.py b/scripts/make_fit.py
index 9bd35aa72119..0c0af8042641 100755
--- a/scripts/make_fit.py
+++ b/scripts/make_fit.py
@@ -26,6 +26,10 @@ the entire FIT.
Use -c to compress the data, using bzip2, gzip, lz4, lzma, lzo and
zstd algorithms.
+Use -C to specify a FIT configuration file (.fitconfig) that selects
+which DTBs to include and optionally sets properties or subnodes (such
+as 'match-1') on the generated /configurations/conf-N nodes.
+
Use -D to decompose "composite" DTBs into their base components and
deduplicate the resulting base DTBs and DTB overlays. This requires the
DTBs to be sourced from the kernel build directory, as the implementation
@@ -37,6 +41,7 @@ as U-Boot, Linuxboot, Tianocore, etc.
import argparse
import collections
+import configparser
import multiprocessing
import os
import subprocess
@@ -69,21 +74,25 @@ def parse_args():
"""
epilog = 'Build a FIT from a directory tree containing .dtb files'
parser = argparse.ArgumentParser(epilog=epilog, fromfile_prefix_chars='@')
- parser.add_argument('-A', '--arch', type=str, required=True,
+ parser.add_argument('-A', '--arch', type=str,
help='Specifies the architecture')
parser.add_argument('-c', '--compress', type=str, default='none',
help='Specifies the compression')
+ parser.add_argument('-C', '--config', type=str,
+ help='Specifies a FIT configuration file (.fitconfig)')
parser.add_argument('-D', '--decompose-dtbs', action='store_true',
help='Decompose composite DTBs into base DTB and overlays')
parser.add_argument('-E', '--external', action='store_true',
help='Convert the FIT to use external data')
- parser.add_argument('-n', '--name', type=str, required=True,
+ parser.add_argument('-l', '--list-dtbs', action='store_true',
+ help='List the DTB filenames from the configuration file and exit')
+ parser.add_argument('-n', '--name', type=str,
help='Specifies the name')
- parser.add_argument('-o', '--output', type=str, required=True,
+ parser.add_argument('-o', '--output', type=str,
help='Specifies the output file (.fit)')
- parser.add_argument('-O', '--os', type=str, required=True,
+ parser.add_argument('-O', '--os', type=str,
help='Specifies the operating system')
- parser.add_argument('-k', '--kernel', type=str, required=True,
+ parser.add_argument('-k', '--kernel', type=str,
help='Specifies the (uncompressed) kernel input file (.itk)')
parser.add_argument('-r', '--ramdisk', type=str,
help='Specifies the ramdisk/initrd input file')
@@ -92,7 +101,15 @@ def parse_args():
parser.add_argument('dtbs', type=str, nargs='*',
help='Specifies the devicetree files to process')
- return parser.parse_args()
+ args = parser.parse_args()
+ if args.list_dtbs:
+ if not args.config:
+ parser.error('--list-dtbs requires -C/--config')
+ else:
+ for opt in ('arch', 'name', 'output', 'os', 'kernel'):
+ if not getattr(args, opt):
+ parser.error(f'--{opt} is required')
+ return args
def setup_fit(fsw, name):
@@ -160,6 +177,49 @@ def write_ramdisk(fsw, data, args):
fsw.property('data', data)
+def parse_config(fname):
+ """Parse a FIT configuration (.fitconfig) file
+
+ Each [section] header names a .dtb file (relative to the directory
+ containing the configuration file) and starts a FIT configuration entry.
+ Optional 'key = value' lines in the section set or override properties
+ on that /configurations/conf-N node (or on a subnode when 'key' has the
+ form 'subnode/prop', such as 'match-1/board-id = 0x070406').
+
+ Args:
+ fname (str): Path to the .fitconfig file
+
+ Returns:
+ dict: Mapping of DTB filename (str) to property overrides (dict)
+ """
+ cfg = configparser.ConfigParser(interpolation=None)
+ cfg.optionxform = str
+ with open(fname, 'r', encoding='utf-8') as inf:
+ cfg.read_file(inf, source=fname)
+ return {sec: dict(cfg.items(sec)) for sec in cfg.sections()}
+
+
+def write_prop(fsw, name, val):
+ """Write a configuration property as a u32 or string
+
+ Unquoted integer literals (such as '0x070406' or '123') are written
+ as 32-bit integer cells; all other values (including values enclosed
+ in double quotes) are written as strings.
+
+ Args:
+ fsw (libfdt.FdtSw): Object to use for writing
+ name (str): Property name
+ val (str): Raw property value string from the configuration file
+ """
+ if len(val) >= 2 and val.startswith('"') and val.endswith('"'):
+ fsw.property_string(name, val[1:-1])
+ return
+ try:
+ fsw.property_u32(name, int(val, 0))
+ except ValueError:
+ fsw.property_string(name, val)
+
+
def finish_fit(fsw, entries, has_ramdisk=False):
"""Finish the FIT ready for use
@@ -170,20 +230,35 @@ def finish_fit(fsw, entries, has_ramdisk=False):
entries (list of tuple): List of configurations:
str: Description of model
str: Compatible stringlist
+ list of int: Sequence numbers of FDTs (fdt-<n>) for this config
+ dict: Optional configuration property/subnode overrides
has_ramdisk (bool): True if a ramdisk is included in the FIT
"""
fsw.end_node()
seq = 0
with fsw.add_node('configurations'):
- for model, compat, files in entries:
+ for model, compat, files, props in entries:
seq += 1
with fsw.add_node(f'conf-{seq}'):
- fsw.property('compatible', bytes(compat))
- fsw.property_string('description', model)
+ if 'compatible' not in props:
+ fsw.property('compatible', bytes(compat))
+ if 'description' not in props:
+ fsw.property_string('description', model)
+ subnodes = collections.defaultdict(dict)
+ for pname, pval in props.items():
+ if '/' in pname:
+ subnode, subprop = pname.split('/', 1)
+ subnodes[subnode][subprop] = pval
+ else:
+ write_prop(fsw, pname, pval)
fsw.property('fdt', bytes(''.join(f'fdt-{x}\x00' for x in files), "ascii"))
fsw.property_string('kernel', 'kernel')
if has_ramdisk:
fsw.property_string('ramdisk', 'ramdisk')
+ for subnode, subprops in subnodes.items():
+ with fsw.add_node(subnode):
+ for subprop, pval in subprops.items():
+ write_prop(fsw, subprop, pval)
fsw.end_node()
@@ -322,9 +397,20 @@ def _process_dtbs(args, fsw, entries, fdts):
# First figure out the unique DTB files that need compression
todo = []
- file_info = [] # List of (fname, model, compat, files) tuples
+ file_info = [] # List of (fname, model, compat, files, props) tuples
+
+ if args.config:
+ config = parse_config(args.config)
+ by_name = {os.path.basename(fn): fn for fn in args.dtbs}
+ config_dir = os.path.dirname(args.config)
+ dtb_configs = [
+ (by_name.get(dtb, os.path.join(config_dir, dtb)), props)
+ for dtb, props in config.items()
+ ]
+ else:
+ dtb_configs = [(fname, {}) for fname in args.dtbs]
- for fname in args.dtbs:
+ for fname, props in dtb_configs:
# Ignore non-DTB (*.dtb) files
if os.path.splitext(fname)[1] != '.dtb':
continue
@@ -335,7 +421,7 @@ def _process_dtbs(args, fsw, entries, fdts):
sys.stderr.write(f'Error processing {fname}:\n')
raise e
- file_info.append((fname, model, compat, files))
+ file_info.append((fname, model, compat, files, props))
for fn in files:
if fn not in fdts and fn not in todo:
todo.append(fn)
@@ -354,7 +440,7 @@ def _process_dtbs(args, fsw, entries, fdts):
cache = dict(results)
# Now write all DTBs to the FIT using pre-compressed data
- for fname, model, compat, files in file_info:
+ for fname, model, compat, files, props in file_info:
for fn in files:
if fn not in fdts:
seq += 1
@@ -364,7 +450,7 @@ def _process_dtbs(args, fsw, entries, fdts):
fdts[fn] = seq
files_seq = [fdts[fn] for fn in files]
- entries.append([model, compat, files_seq])
+ entries.append([model, compat, files_seq, props])
return seq, size
@@ -415,6 +501,9 @@ def build_fit(args):
def run_make_fit():
"""Run the tool's main logic"""
args = parse_args()
+ if args.list_dtbs:
+ print(' '.join(parse_config(args.config)))
+ return
out_data, count, size = build_fit(args)
with open(args.output, 'wb') as outf:
--
2.56.0.611.g1030f0b940-goog
^ permalink raw reply [flat|nested] 6+ messages in thread* [RFC PATCH v2 3/5] kbuild: fit: Add opt-in FIT_FACTOR_DTBS support using fdtfactor
2026-11-13 21:09 [RFC PATCH v2 0/5] arm64: Add FIT configurations for sc7180-trogdor and google,lga Douglas Anderson
2026-11-13 21:09 ` [RFC PATCH v2 1/5] kbuild: fit: Document FIT_COMPRESSION and FIT_DECOMPOSE_DTBS Douglas Anderson
2026-11-13 21:09 ` [RFC PATCH v2 2/5] kbuild: fit: Support selecting DTBs and config properties from a file Douglas Anderson
@ 2026-11-13 21:09 ` Douglas Anderson
2026-11-13 21:09 ` [RFC PATCH v2 4/5] arm64: dts: google: lga: Add lga.fitconfig FIT configuration file Douglas Anderson
2026-11-13 21:09 ` [RFC PATCH v2 5/5] arm64: dts: qcom: sc7180: Add sc7180-trogdor.fitconfig FIT config file Douglas Anderson
4 siblings, 0 replies; 6+ messages in thread
From: Douglas Anderson @ 2026-11-13 21:09 UTC (permalink / raw)
To: Devicetree-compiler, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Konrad Dybcio
Cc: linux-arm-msm, Julius Werner, Michal Simek, André Draszik,
linux-arm-kernel, Simon Glass, Peter Griffin, linux-kbuild,
Tudor Ambarus, Chen-Yu Tsai, Will Deacon, Nathan Chancellor,
Devicetree, Catalin Marinas, Nicolas Schier, linux-kernel,
Saravana Kannan, Brian Norris, Douglas Anderson, Alice Ryhl,
Jonathan Corbet, Josh Poimboeuf, Lorenzo Stoakes (ARM),
Manuel Ebner, Marco Elver, Mark Rutland, Mauro Carvalho Chehab,
Peter Zijlstra (Intel),
Randy Dunlap, Rong Xu, Shuah Khan, devicetree, linux-doc,
workflows
When packaging many board DTBs from the same SoC family into a FIT
image, full per-board `.dtb` blobs duplicate the vast majority of the
SoC and board-family device tree across every FDT node in `/images`.
Because each FDT blob in a FIT image is compressed independently,
standard per-node compression cannot deduplicate those repeated common
nodes across boards. Factoring the common nodes into a shared base DTB
and small per-board `.dtbo` overlays yields substantial space savings
(for example, reducing the 47 LZ4-compressed `sc7180-trogdor` DTBs from
1.71 MB to 213 KB, an 87.5% reduction). In addition, some bootloaders
(such as the Pixel 10 bootloader) specifically require a shared base DTB
plus per-board `.dtbo` overlays rather than monolithic per-board DTBs.
Add opt-in support for factoring the DTBs inside a compiled FIT image
into shared base DTBs and per-board overlays using `fdtfactor` (from the
upstream `dtc` project [1]) when `FIT_FACTOR_DTBS=1` is passed to make:
- When `FIT_FACTOR_DTBS` is set, pass `-@ -L` to `dtc` for the DTBs
included in the FIT image so they retain `/__symbols__` and
`/__local_fixups__` metadata needed for factoring.
- Run `$(FDTFACTOR) $(FDTFACTOR_ARGS) -F $@` (with `FDTFACTOR_ARGS`
defaulting to `--strip-local-fixups`) at the end of `cmd_fit` when
`FIT_FACTOR_DTBS` is set. `fdtfactor` transparently handles both
uncompressed and compressed (e.g. `gzip`, `lz4`, `xz`) FDT image nodes
inside the FIT.
Because `fdtfactor` is a Python tool that depends on `pylibfdt` (similar
to `scripts/make_fit.py` itself) and Kbuild does not build `pylibfdt`
from `scripts/dtc/`, `fdtfactor` (along with a matching `pylibfdt`) is
an optional external host dependency documented in
`Documentation/process/changes.rst` and
`Documentation/kbuild/kbuild.rst`.
[1] https://lore.kernel.org/r/20261101220224.1436242-1-dianders@chromium.org
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
This patch obviously could only land if some form of the `fdtfactor`
series [1] lands in upstream `dtc`. While `fdtfactor` itself will remain
an external host dependency (since it relies on `pylibfdt`), we will
still want to sync the `libfdt` overlay `/__local_fixups__` changes from
that series into `scripts/dtc/libfdt/` before landing this patch so
composite DTBs built by Kbuild with `fdtoverlay` retain full
`/__local_fixups__` metadata.
If people hate this patch, we could certainly just run `fdtfactor`
after the kernel build finishes.
Changes in v2:
- Update fdtfactor invocation for v2+ flags (-v -> -s, -f -> -F)
- Expand commit message and notes to explain why FIT_FACTOR_DTBS is
needed, that fdtfactor is an external host dependency, and that
compressed DTBs in the FIT are supported (Simon Glass)
- Document the optional fdtfactor dependency and FIT_FACTOR_DTBS /
FDTFACTOR / FDTFACTOR_ARGS in Documentation/process/changes.rst,
Documentation/kbuild/kbuild.rst, and arm64 'make help' (Simon Glass)
Documentation/kbuild/kbuild.rst | 14 ++++++++++++++
Documentation/process/changes.rst | 10 ++++++++++
arch/arm64/Makefile | 2 +-
scripts/Makefile.dtbs | 8 ++++++++
scripts/Makefile.lib | 7 ++++++-
5 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/Documentation/kbuild/kbuild.rst b/Documentation/kbuild/kbuild.rst
index 80cac4c432e4..4271883bc10e 100644
--- a/Documentation/kbuild/kbuild.rst
+++ b/Documentation/kbuild/kbuild.rst
@@ -383,3 +383,17 @@ Path to a ``.fitconfig`` configuration file (relative to ``$(srctree)`` or
``arch/$(SRCARCH)/boot/dts/``) selecting which DTBs to build and include in
``image.fit`` and optionally setting properties or subnodes on each
``/configurations/conf-N`` node.
+
+FIT_FACTOR_DTBS
+---------------
+If set to a non-empty value when building ``image.fit``, compile the included
+DTBs with ``-@ -L`` and run ``fdtfactor`` to factor common device tree nodes
+into shared base DTBs and per-board ``.dtbo`` overlays inside the FIT.
+Requires the external ``fdtfactor`` tool (and ``pylibfdt``) from the upstream
+``dtc`` project.
+
+FDTFACTOR, FDTFACTOR_ARGS
+-------------------------
+The ``fdtfactor`` program and extra arguments used when ``FIT_FACTOR_DTBS`` is
+set. ``FDTFACTOR`` defaults to ``fdtfactor`` and ``FDTFACTOR_ARGS`` defaults
+to ``--strip-local-fixups``.
diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst
index 28f2ca63318e..f9b2a35ddc45 100644
--- a/Documentation/process/changes.rst
+++ b/Documentation/process/changes.rst
@@ -201,6 +201,16 @@ platforms. The tool is available via the ``u-boot-tools`` package or can be
built from the U-Boot source code. See the instructions at
https://docs.u-boot.org/en/latest/build/tools.html#building-tools-for-linux
+fdtfactor (optional)
+--------------------
+
+This tool (along with ``pylibfdt`` from the same ``dtc`` release) is used when
+building a Flat Image Tree (FIT) with ``FIT_FACTOR_DTBS=1`` to factor common
+device tree nodes across boards into shared base DTBs and per-board overlays;
+see ``FIT_FACTOR_DTBS`` in Documentation/kbuild/kbuild.rst. It is part of the
+upstream ``dtc`` project at
+https://git.kernel.org/pub/scm/utils/dtc/dtc.git
+
GNU AWK
-------
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index b4982e94f80a..f12f4f7c6a02 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -224,7 +224,7 @@ define archhelp
echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
echo ' image.fit - Flat Image Tree (arch/$(ARCH)/boot/image.fit)'
echo ' Configured by FIT_COMPRESSION, FIT_DECOMPOSE_DTBS,'
- echo ' and FIT_CONFIG'
+ echo ' FIT_CONFIG, FIT_FACTOR_DTBS, and FDTFACTOR_ARGS'
echo ' install - Install kernel (compressed if COMPRESSED_INSTALL set)'
echo ' zinstall - Install compressed kernel'
echo ' Install using (your) ~/bin/installkernel or'
diff --git a/scripts/Makefile.dtbs b/scripts/Makefile.dtbs
index cc14fc905ea3..bc0c62617a7c 100644
--- a/scripts/Makefile.dtbs
+++ b/scripts/Makefile.dtbs
@@ -126,6 +126,14 @@ DTC_FLAGS += -Wnode_name_chars_strict \
-Wunique_unit_address
endif
+# When FIT_FACTOR_DTBS is set, pass -@ -L to dtc so the built DTBs retain the
+# /__symbols__ and /__local_fixups__ nodes required by fdtfactor.
+ifneq ($(FIT_FACTOR_DTBS),)
+ifneq ($(filter arch/$(SRCARCH)/boot/dts%, $(obj)),)
+DTC_FLAGS += -@ -L
+endif
+endif
+
DTC_FLAGS += $(DTC_FLAGS_$(target-stem))
# Set -@ if the target is a base DTB that overlay is applied onto
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index e08e35d4ed74..af2d3e508424 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -418,6 +418,9 @@ quiet_cmd_uimage = UIMAGE $@
# ---------------------------------------------------------------------------
MAKE_FIT := $(srctree)/scripts/make_fit.py
+# External fdtfactor tool from upstream dtc (requires matching pylibfdt)
+FDTFACTOR ?= fdtfactor
+FDTFACTOR_ARGS ?= --strip-local-fixups
# Use this to override the compression algorithm
FIT_COMPRESSION ?= gzip
@@ -428,7 +431,9 @@ quiet_cmd_fit = FIT $@
$(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \
$(if $(FIT_DECOMPOSE_DTBS),--decompose-dtbs) \
$(if $(FIT_CONFIG_FILE),--config $(FIT_CONFIG_FILE)) \
- --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^)
+ --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^) \
+ $(if $(FIT_FACTOR_DTBS),&& $(FDTFACTOR) $(FDTFACTOR_ARGS) \
+ $(if $(findstring 1,$(KBUILD_VERBOSE)),-s) -F $@)
# If FIT_CONFIG is specified on the command line (either relative to $(srctree)
# or relative to arch/$(SRCARCH)/boot/dts/), locate that file and extract the
--
2.56.0.611.g1030f0b940-goog
^ permalink raw reply [flat|nested] 6+ messages in thread