Re: [PATCH v2 0/8] bootm: size the noload buffer from the compressor header

Tom Rini <[email protected]>
Newsgroups gmane.comp.boot-loaders.u-boot
Message-ID <20260818221019.GE523975__39623.2882094168$1787091041$gmane$org@bill-the-cat>
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
signature.asc (application/pgp-signature, 228 B)
-----BEGIN PGP SIGNATURE-----

iHUEABYKAB0WIQTzzqh0PWDgGS+bTHor4qD1Cr/kCgUCaoTYSAAKCRAr4qD1Cr/k
CslqAQDfk+ycTEXebgvm8YVTa0M/6c7WIqcCDlUsZjr64yrChQD/YY//q8RN/nu7
HXykC9ac0ZmyolwlDjT0p8cNBFIfbAc=
=oENr
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.