Align every FIT sub-image to 0x800, and check it
mkimage -p only places the FIRST payload. The rest are packed contiguously, and U-Boot reads each by dividing its data-position by the 512-byte block size with a truncating divide -- so a payload that is not block-aligned is read from the wrong offset. Measured: without -B this script emitted the kernel at 0x9A94, data-position % 512 = 148, which is exactly the failing shape. That failure is on record. flare-edge 9387cff (2026-09-01) hit it on a boot_b FIT: "unaligned sub-images fail the RESC loader's sha256 and the logo silently falls back to 'No resource file'". It landed on -B 0x200, inferred from noticing the proven image was "512-aligned" without checking for a larger factor. The proven images are aligned to 0x800, not merely to 512. Measured on the pair that boots this board today: boot.img fdt/kernel/resource at 0x800 / 0x12800 / 0x3A7800, recovery.img at 0x800 / 0x12800 / 0x3F8800 -- every one a multiple of 2048. So 0x800 satisfies everything 0x200 does, since every 0x800 multiple is a 0x200 multiple, and additionally reproduces the vendor layout exactly. The cost is at most 2 KiB of padding. Where a remembered rule and a booting image disagree, match the image. The alignment is now also asserted at build time rather than trusted. It runs on every build because the failure it catches is silent -- a wrong offset does not fail the build, it fails on a panel, and only sometimes visibly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T2D2KtdgwbhbF6Mo64eUrn
This commit is contained in:
+35
-2
@@ -130,8 +130,41 @@ cat > "$WORKDIR/boot.its" <<'ITS'
|
|||||||
};
|
};
|
||||||
ITS
|
ITS
|
||||||
|
|
||||||
echo "== FIT (external data, -E -p 0x800)"
|
# - SUB-IMAGE ALIGNMENT (`-B 0x800`). `-p` only places the FIRST payload; the
|
||||||
( cd "$WORKDIR" && mkimage -f boot.its -E -p 0x800 boot.img >/dev/null )
|
# 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
|
# 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
|
# embedded-data build, which this U-Boot rejects. Catch it here rather than on
|
||||||
|
|||||||
Reference in New Issue
Block a user