diff --git a/build/mk-bootimg.sh b/build/mk-bootimg.sh index 642150f..e23cd76 100755 --- a/build/mk-bootimg.sh +++ b/build/mk-bootimg.sh @@ -130,8 +130,41 @@ cat > "$WORKDIR/boot.its" <<'ITS' }; ITS -echo "== FIT (external data, -E -p 0x800)" -( cd "$WORKDIR" && mkimage -f boot.its -E -p 0x800 boot.img >/dev/null ) +# - SUB-IMAGE ALIGNMENT (`-B 0x800`). `-p` only places the FIRST payload; the +# rest are packed contiguously, and U-Boot reads each one by dividing its +# data-position by the 512-byte block size with a TRUNCATING divide. A +# payload that is not block-aligned is therefore read from the wrong offset: +# the RESC loader's sha256 fails and logo.bmp silently does not load +# (observed 2026-09-01, flare-edge 9387cff). +# +# MEASURED, both directions. Without -B, this script produced kernel at +# 0x9A94 (data-position % 512 = 148) -- misaligned, exactly the failing +# shape. The vendor images that actually boot this board are aligned to +# 0x800, not merely to 512: boot.img has fdt/kernel/resource at 0x800, +# 0x12800, 0x3A7800 and recovery.img at 0x800, 0x12800, 0x3F8800 -- every +# one a multiple of 2048. +# +# 9387cff recorded `-B 0x200` from that failure. It is right but weaker than +# it needed to be: it was inferred from noticing the proven image was +# "512-aligned" without checking for a larger factor. 0x800 satisfies +# everything 0x200 does (every 0x800 multiple is a 0x200 multiple) and +# additionally reproduces the vendor layout exactly, for at most 2 KiB of +# padding. When the two disagree, match the image that is known to boot. +echo "== FIT (external data, -E -p 0x800 -B 0x800)" +( cd "$WORKDIR" && mkimage -f boot.its -E -p 0x800 -B 0x800 boot.img >/dev/null ) + +# Every payload must land on a 0x800 boundary. This is the check that would have +# caught the unaligned build before it reached a panel, so it runs on every +# build rather than living in a separate tool nobody remembers to invoke. +for _n in fdt kernel resource; do + _pos="$(fdtget -t u "$WORKDIR/boot.img" "/images/$_n" data-position 2>/dev/null || true)" + [ -n "$_pos" ] || continue + if [ $(( _pos % 2048 )) -ne 0 ]; then + echo "FATAL: /images/$_n data-position $_pos is not 0x800-aligned;" >&2 + echo " U-Boot's block divide would read it from the wrong offset" >&2 + exit 1 + fi +done # A FIT whose metadata swelled to the size of the whole image is an # embedded-data build, which this U-Boot rejects. Catch it here rather than on