[PATCH v2 1/8] binman: Android boot image support
Simon Glass
sjg at chromium.org
Mon Jun 8 15:24:45 CEST 2026
Hi Sam,
On 2026-06-07T23:37:09, Sam Day via B4 Relay
<devnull+me.samcday.com at kernel.org> wrote:
> binman: Android boot image support
>
> Introduce initial support for Android boot images (abootimgs). This
> initial stab supports both v0 and v2 headers. The AOSP implementation
> was used as a reference.
>
> Since we're targeting U-Boot use cases here, a couple of things were
> omitted from this impl, namely 'second' and recovery_dtbo support.
>
> Link: https://android.googlesource.com/platform/system/tools/mkbootimg/
> Signed-off-by: Sam Day <me at samcday.com>
>
> tools/binman/etype/android_boot.py | 313 +++++++++++++++++++++++++++
> tools/binman/ftest.py | 66 ++++++
> tools/binman/test/vendor/android_boot_v0.dts | 29 +++
> tools/binman/test/vendor/android_boot_v2.dts | 46 ++++
> 4 files changed, 454 insertions(+)
> diff --git a/tools/binman/etype/android_boot.py b/tools/binman/etype/android_boot.py
> @@ -0,0 +1,313 @@
> + @staticmethod
> + def _CheckFit(name, data, size):
> + if len(data) > size:
> + raise ValueError('%s is %d bytes, maximum is %d' %
> + (name, len(data), size))
> +
> + return data + b'\0' * (size - len(data))
Please raise via self.Raise() so the user gets the node path. A bare
ValueError makes it hard to track down which entry overflowed when
several android-boot images are present.
> diff --git a/tools/binman/etype/android_boot.py b/tools/binman/etype/android_boot.py
> @@ -0,0 +1,313 @@
> + def _GetEntryData(self, name, required):
> + entry = self._entries.get(name)
> + data = entry.GetData(required)
> + if data is None and not required:
> + return None
> +
> + return data
> +
> + def _GetOptionalEntryData(self, name, required, default=b''):
> + entry = self._entries.get(name)
> + if not entry:
> + return default
> +
> + data = entry.GetData(required)
> + if data is None and not required:
> + return None
> +
> + return data
These two are almost identical and the names don't distinguish them,
i.e. _GetEntryData() will AttributeError if the name isn't present,
while _GetOptionalEntryData() returns the default. Please fold them
into one with a default=None parameter: None means required, anything
else means optional (function comment). Also, the 'if data is None and
not required' branch in _GetEntryData() does nothing - both arms
return data.
> diff --git a/tools/binman/etype/android_boot.py b/tools/binman/etype/android_boot.py
> @@ -0,0 +1,313 @@
> + def ReadNode(self):
> + super().ReadNode()
> + self.header_version = fdt_util.GetInt(self._node, 'header-version', 0)
...
> + if self.header_version not in (0, 2):
> + self.Raise('Only Android boot image header versions 0 and 2 are '
> + 'supported')
Please call this out in the commit message - AOSP defines v0..v4 and
readers will wonder why v1/v3/v4 are missing. Something like "v1, v3,
v4 are not implemented as no use case has come up yet" would help.
> diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
> @@ -5598,6 +5598,72 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
> + self.assertEqual(U_BOOT_DATA, data[0x800:0x800 + len(U_BOOT_DATA)])
> + self.assertEqual(U_BOOT_DTB_DATA,
> + data[0x1000:0x1000 + len(U_BOOT_DTB_DATA)])
> +
> + self.assertEqual(U_BOOT_DATA, data[0x800:0x800 + len(U_BOOT_DATA)])
Last assertion duplicates the first - please drop it.
> diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
> @@ -5598,6 +5598,72 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
> + def testAndroidBootV0(self):
> + """Test that binman can produce a plain legacy Android boot image"""
> + data = self._DoReadFile('vendor/android_boot_v0.dts')
Missing coverage for several error paths - U haven't run this but
there is Raise() for unsupported header_version, non-power-of-two
page-size, etc. Binman aims for full branch coverage - please add
tests for these, and verify 'binman test -T' still shows 100% coverage
for your etype
> diff --git a/tools/binman/test/vendor/android_boot_v2.dts b/tools/binman/test/vendor/android_boot_v2.dts
> @@ -0,0 +1,46 @@
> + kernel-offset = <0x00008000>;
> + ramdisk-offset = <0x01000000>;
> + second-offset = <0x00f00000>;
> + tags-offset = <0x00000100>;
'second-offset' is silently ignored - the etype doesn't parse it and
the commit message says 'second' support is dropped. Do you need it?
> diff --git a/tools/binman/test/vendor/android_boot_v0.dts b/tools/binman/test/vendor/android_boot_v0.dts
> @@ -0,0 +1,29 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/dts-v1/;
Why a new 'vendor/' subdirectory? The contents here are plain Android
boot images, not anything vendor-specific. I'd suggest 'android/' (or
leaving them in test/ alongside other etype .dts files), which also
leaves a clearer naming pattern for QCDT/DTBH later.
> diff --git a/tools/binman/etype/android_boot.py b/tools/binman/etype/android_boot.py
> @@ -0,0 +1,313 @@
> + Example::
> + A v2 abootimg with control FDT placed in the DTB section:
> +
> + android-boot {
...
> + A v0 abootimg with embedded control FDT (v0 doesn't support DTBs) and
> + an empty ramdisk (some bootloaders insist on a ramdisk being present):
> + android-boot {
These render as one big code block in the auto-generated docs, with
the v0 description folded into the literal. Please split into two
'Example::' blocks, with a blank line between the v0 prose and its
'android-boot {'.
Regards,
Simon
More information about the U-Boot
mailing list