[PATCH v3 07/10] binman: Add QCDT support
Simon Glass
sjg at chromium.org
Sun Jun 14 18:19:48 CEST 2026
Hi Sam,
On 2026-06-10T01:27:41, Sam Day via B4 Relay
<devnull+me.samcday.com at kernel.org> wrote:
> binman: Add QCDT support
>
> This vendor-specific format is used by many bootloaders on older qcom
> SoCs, such as msm8916. It's a container for N FDTs. Each one is
> contained in a record that includes metadata about the platform/variant
> it targets. The previous bootloader picks the 'right' record based on
> this metadata.
>
> This initial impl targets a streamlined v2 path, with no support for
> different versions or multiple qcom,msm-id/qcom,board-id tuples. If/when
> that's needed it will be implemented in a follow-up.
>
> In the following commit, support for DTBH will also be introduced.
> Because QCDT and DTBH share a lot of common behaviour, this commit also
> introduces a Entry_Android_vendor_dt_table base class.
>
> This impl was based on the lk2nd/CAF LK dtbTool script.
>
> Link: https://github.com/msm8916-mainline/lk2nd/blob/main/lk2nd/scripts/dtbTool
> Signed-off-by: Sam Day <me at samcday.com>
>
> tools/binman/android_vendor_dt_table.py | 104 +++++++++++++++++++++
> tools/binman/etype/android_boot.py | 31 ++++++
> tools/binman/etype/qcdt.py | 80 ++++++++++++++++
> tools/binman/ftest.py | 96 +++++++++++++++++++
> tools/binman/test/qcdt.dts | 36 +++++++
> tools/binman/test/qcdt_bad_msm_id.dts | 17 ++++
> tools/binman/test/qcdt_invalid_pagesize.dts | 12 +++
> tools/binman/test/qcdt_missing_msm_id.dts | 12 +++
> tools/binman/test/qcdt_missing_payload.dts | 14 +++
> tools/binman/test/qcdt_missing_subnodes.dts | 13 +++
> tools/binman/test/qcdt_multiple_dtbs.dts | 34 +++++++
> tools/binman/test/qcdt_page_size_from_abootimg.dts | 33 +++++++
> tools/binman/test/qcdt_zero_pagesize.dts | 12 +++
> 13 files changed, 494 insertions(+)
> diff --git a/tools/binman/android_vendor_dt_table.py b/tools/binman/android_vendor_dt_table.py
> @@ -0,0 +1,104 @@
> +class Entry_Android_vendor_dt_table(Entry_section):
> + """Base class for legacy Android vendor DT table entries"""
The capital A breaks the naming convention every other entry type
follows (Entry_section, Entry_android_boot).
I'm not 100% sure about the best way to do this base class - but let's
run with what you have and see how it goes. We can always tweak later,
e.g. if someone else does a similar thing.
> diff --git a/tools/binman/android_vendor_dt_table.py b/tools/binman/android_vendor_dt_table.py
> @@ -0,0 +1,104 @@
> + def ReadEntries(self):
> + for node in self._node.subnodes:
> + if self.IsSpecialSubnode(node):
> + continue
> +
> + payloads = self._GetPayloadSubnodes(node)
> + if len(payloads) > 1:
> + self.Raise("subnode '%s': must contain exactly one DTB "
> + "payload subnode" % node.name)
> + if not payloads:
> + continue
The qcdt docstring advertises dtb-* subnodes, but nothing here
enforces the name - any non-special subnode is treated as a DTB
record. Either enforce the dtb- prefix so a typo produces a clear
error, or drop the implication from the docs.
Also, silently skipping a record node with no payload subnode means
the missing-payload error only surfaces later in _GetDtbData() -
raising at ReadEntries time would give a more obvious error location.
> diff --git a/tools/binman/etype/qcdt.py b/tools/binman/etype/qcdt.py
> @@ -0,0 +1,80 @@
> + Properties / Entry arguments:
> + - page-size: QCDT page size, defaults to 2048, unless there's a parent
> + android-boot node with an explicit page-size
> +
> + This entry uses the following subnodes:
> + - dtb-*: DTB records, each containing qcom,msm-id, qcom,board-id and
> + exactly one DTB payload entry
The docs do not mention that QCDT_VERSION is hardcoded to 2, nor do
they describe what qcom,msm-id and qcom,board-id actually mean
(platform_id/soc_rev and variant_id/hw_subtype). Since the etype
rejects malformed values with a specific cell-count error, users will
need this info to author a working DTS. Please flesh out the
docstring.
> diff --git a/tools/binman/etype/qcdt.py b/tools/binman/etype/qcdt.py
> @@ -0,0 +1,80 @@
> + def BuildSectionData(self, required):
> + page_size = self._GetPageSize()
> + dtbs = self._ReadDtbRecords(required, self._ReadDtbRecord)
> + if dtbs is None:
> + return None
> +
> + size = QCDT_HEADER_SIZE + len(dtbs) * QCDT_RECORD_SIZE
> + dtb_offset = self.AlignUp(size, page_size)
Just to check - page_size falls back to 2048 when no explicit setting
and no parent android-boot is found. There is no validation that
page_size is at least QCDT_HEADER_SIZE + N*QCDT_RECORD_SIZE; if a
caller sets a tiny page-size and many DTBs, the first dtb_offset
overflows into the page allocated for the header. Worth a sanity
check, matching the V0/V2 header-size checks in android_boot.
Regards,
Simon
More information about the U-Boot
mailing list