What it is. ARM code is full of branch instructions whose targets are stored relative to the instruction, so the same call target is encoded differently every time it appears. The BCJ filter rewrites those to absolute addresses before LZMA2, giving it repeats to find. With -Xbcj arm,armthumb, mksquashfs tries each filter and no filter on every block and keeps the smallest, so an image can only shrink. Buildroot exposes it as BR2_TARGET_ROOTFS_SQUASHFS_EXTREME_COMP=y, which adds exactly that for xz on ARM. Today only hi3516cv6xx_lite sets it (#2447).
Measured by unpacking the latest release nor-lite images and repacking them with the tree's mksquashfs 4.6.1, keeping 128K blocks:
| board |
shipped |
with BCJ |
saved |
| hi3516ev300 |
5 165 056 |
5 095 424 |
68 KB |
| gk7205v200 |
5 169 152 |
5 091 328 |
76 KB |
| hi3518ev200 |
4 939 776 |
4 804 608 |
132 KB |
| hi3516cv200 |
5 120 000 |
4 988 928 |
128 KB |
| ssc338q |
6 189 056 |
6 115 328 |
72 KB |
| hi3516av300 |
8 003 584 |
7 827 456 |
172 KB |
armthumb is needed, not only arm: on hi3516ev300, gk7205v200 and ssc338q arm alone saves only 25–30 KB, because most of their userland is Thumb-2. The kernel image is not affected.
Change. BR2_TARGET_ROOTFS_SQUASHFS_EXTREME_COMP=y for ARM boards — in general/openipc.fragment if the fragment can be made arch-conditional, otherwise in the ARM defconfigs. Block size stays at 128K here: larger blocks save more (another ~150 KB at 256K, ~350 KB at 1M) but cost RAM in the squashfs caches and decompress a whole block per page-cache miss. That is a separate decision that needs measurement on a camera.
Kernel side. The decoder needs CONFIG_XZ_DEC_ARM/ARMTHUMB. Every ARM board kernel config has them except infinity6c, so the ssc377*/ssc378* boards must stay excluded until the infinity6c kernel fix has shipped a release.
Evidence needed before merge: a BCJ-packed image booting on at least one ARMv5 board (hi3518ev200 / hi3516cv200) and one Thumb-2-heavy board (hi3516ev300 / gk7205v200), with dmesg and df.
Part of #2509.
What it is. ARM code is full of branch instructions whose targets are stored relative to the instruction, so the same call target is encoded differently every time it appears. The BCJ filter rewrites those to absolute addresses before LZMA2, giving it repeats to find. With
-Xbcj arm,armthumb, mksquashfs tries each filter and no filter on every block and keeps the smallest, so an image can only shrink. Buildroot exposes it asBR2_TARGET_ROOTFS_SQUASHFS_EXTREME_COMP=y, which adds exactly that for xz on ARM. Today onlyhi3516cv6xx_litesets it (#2447).Measured by unpacking the
latestrelease nor-lite images and repacking them with the tree's mksquashfs 4.6.1, keeping 128K blocks:armthumbis needed, not onlyarm: on hi3516ev300, gk7205v200 and ssc338qarmalone saves only 25–30 KB, because most of their userland is Thumb-2. The kernel image is not affected.Change.
BR2_TARGET_ROOTFS_SQUASHFS_EXTREME_COMP=yfor ARM boards — ingeneral/openipc.fragmentif the fragment can be made arch-conditional, otherwise in the ARM defconfigs. Block size stays at 128K here: larger blocks save more (another ~150 KB at 256K, ~350 KB at 1M) but cost RAM in the squashfs caches and decompress a whole block per page-cache miss. That is a separate decision that needs measurement on a camera.Kernel side. The decoder needs
CONFIG_XZ_DEC_ARM/ARMTHUMB. Every ARM board kernel config has them except infinity6c, so thessc377*/ssc378*boards must stay excluded until the infinity6c kernel fix has shipped a release.Evidence needed before merge: a BCJ-packed image booting on at least one ARMv5 board (hi3518ev200 / hi3516cv200) and one Thumb-2-heavy board (hi3516ev300 / gk7205v200), with
dmesganddf.Part of #2509.