On Tue, Aug 18, 2026 at 01:23:14PM +0000, Aristo Chen wrote:

> This is v2 of "bootm: size the noload decompression buffer from the
> compressor header". Tom pushed back on v1
> (https://patchwork.ozlabs.org/project/uboot/patch/[email protected]/)
> on two grounds:
> 
>   1. No concrete problem report driving the change.
>   2. ~1297 platforms grew by ~170-400 bytes; the change is not
>      opt-in, so the size cost falls on everyone.

So, the first example that pops up in my builds is imx8mn_beacon_2g.
And for v1 of the series:
   aarch64: (for 1/1 boards) all +16384.0 data +14336.0 text +2048.0
            imx8mn_beacon_2g: all +16384 data +14336 text +2048
               u-boot: add: 0/0, grow: 1/0 bytes: 328/0 (328)
                 function                                   old     new   delta
                 bootm_run_states                          3316    3644    +328

And now for v2:
   aarch64: (for 1/1 boards) all +16384.0 data +14336.0 text +2048.0
            imx8mn_beacon_2g: all +16384 data +14336 text +2048
               u-boot: add: 0/0, grow: 1/0 bytes: 368/0 (368)
                 function                                   old     new   delta
                 bootm_run_states                          3316    3684    +368

Next, picking turris_mox as it enables ZSTD:
v1:
   aarch64: (for 1/1 boards) all +472.0 text +472.0
            turris_mox     : all +472 text +472
               u-boot: add: 2/0, grow: 1/0 bytes: 472/0 (472)
                 function                                   old     new   delta
                 image_decomp_get_uncompressed_size           -     416    +416
                 bootm_run_states                          2360    2412     +52
                 zstd_get_frame_header                        -       4      +4
v2:
   aarch64: (for 1/1 boards) all +428.0 text +428.0
            turris_mox     : all +428 text +428
               u-boot: add: 1/0, grow: 1/0 bytes: 428/0 (428)
                 function                                   old     new   delta
                 bootm_run_states                          2360    2784    +424
                 zstd_get_frame_header                        -       4      +4

So, that is better. Looking at smartweb, both iterations are the same:
       arm: (for 1/1 boards) all +96.0 text +96.0
            smartweb       : all +96 text +96
               u-boot: add: 0/0, grow: 1/0 bytes: 76/0 (76)
                 function                                   old     new   delta
                 bootm_run_states                          3592    3668     +76

What's honestly concerning is chromebook_coral where v2 *shrinks*:
               u-boot: add: 0/0, grow: 0/-1 bytes: 0/-2 (-2)
                 function                                   old     new   delta
                 bootm_load_os                              520     518      -2
but v1 grows:
               u-boot: add: 1/0, grow: 1/0 bytes: 110/0 (110)
                 function                                   old     new   delta
                 bootm_load_os                              520     587     +67
                 image_decomp_get_uncompressed_size           -      43     +43

> On the first point, Nora Schiffer replied with a concrete use case
> (EFI-in-FIT plus padded loaders such as shim, systemd-boot, and
> OpenWrt's lzma-loader can produce compression ratios that outrun the
> 8x heuristic), and mentioned this is on the road map for TQ-Systems
> standard BSPs.
> 
> On the second point, v2 reworks the implementation to cut the size
> cost, measures it across the format and architecture buckets, and
> splits the work per format so each decompressor's support can be
> taken or dropped on its own.
> 
> Background: for a compressed kernel_noload image, bootm_load_os()
> sizes the decompression buffer as ALIGN(image_len * 8, SZ_1M). The
> 8x heuristic works for typical kernels, but any well-compressed
> payload can exceed it, and no fixed multiplier is safe against
> arbitrarily compressible input.
> 
> Each implementation patch adds a small static header-parse helper in
> bootm.c (no new public API) and wires it into a size-hint switch;
> helper and switch case are only compiled when the matching
> decompressor is enabled, so boards that do not build a format pay no
> code for it. gzip's ISIZE is a fixed trailer read, lzma's size a
> fixed header read, lz4 mirrors ulz4fn()'s frame-header validation,
> and zstd asks zstd_get_frame_header(), whose frame-parsing code
> already ships with the zstd decompressor. The header-recorded value
> is attacker-controlled, so it is capped at CONFIG_SYS_BOOTM_LEN, and
> it is only an allocation hint: the decoder stays authoritative
> during the actual decompression.
> 
> Text size deltas of the u-boot ELF (size(1), distro gcc 13.3 cross
> toolchains); data/bss are unchanged everywhere. To make the columns
> directly comparable, the v1 column is v1's implementation commit
> cherry-picked onto this series' base, so both columns share one
> baseline:

Please use binman to look at the size changes, as it gives much more
useful information. I've noted
https://git.u-boot-project.org/u-boot/u-boot-extras/-/blob/master/contrib/trini/u-boot-size-test.sh?ref_type=heads
for others before as a wrapper around the options to get the most useful
information out.

-- 
Tom

Attachment: signature.asc
Description: PGP signature

Reply via email to