Round 14: 4K-align U-Boot entry inside the wrapped Image (start.S wfi hang)

This commit is contained in:
vhaudiquet
2026-08-30 10:12:07 +02:00
parent 278f93f805
commit ac6167e4e4
4 changed files with 26 additions and 4 deletions
+17
View File
@@ -608,3 +608,20 @@ post-relocation one):
Read: last paint reached = code survived through that checkpoint; the
crash/hang is in the next window. Success = banner on black.
## Round 14 — all green decoded: U-Boot's 4K-alignment requirement
Reboot with `fc48d83b…`: **all green, no bands** — U-Boot hung before
`board_early_init_f`. Root cause found in start.S: with
CONFIG_POSITION_INDEPENDENT, U-Boot verifies `adr _start` & 0xfff == 0
(it uses ADRP+ADD with lo12 relocations during the PIE fixup) and
otherwise loops in `wfi` forever — a silent hang, no exception. Our
wrapper pushed U-Boot's entry to load_base+0xB4: misaligned by
construction.
### Fix (payload `faee130f…`)
`build-uboot-payload.sh` now pads the wrapper so U-Boot starts at the
next 4 KiB boundary (0x1000) inside the 2 MiB-aligned image; wrapper
tail branch patched accordingly (0x140003d4 → 0x1000, verified by
disassembly). Keep this invariant for every future layout change.
+9 -4
View File
@@ -40,8 +40,12 @@ hdr = bytearray(64)
hdr[0:4] = struct.pack('<I', (0x40 >> 2) | 0x14000000) # code0: b +0x40
struct.pack_into('<Q', hdr, 0x10, total) # image_size
struct.pack_into('<Q', hdr, 0x18, 1 << 3) # flags: bit3
hdr[0x38:0x3c] = b'ARM\x64' # magic
# U-Boot requires its runtime _start to be 4K-aligned (start.S checks
# `adr _start` & 0xfff and hangs in wfi otherwise; it uses ADRP+ADD with
# lo12 relocations during the PIE fixup). depthcharge loads the image at
# a 2 MiB-aligned slot, so place U-Boot at the next 4 KiB boundary.
uboot_off = (wrap_off + wrap_len + 0xfff) & ~0xfff
total = uboot_off + len(uboot)
# patch the wrapper's trailing `b .` to jump to the U-Boot entry
br_off = wrap_off + wrap_len - 4
imm = (uboot_off - br_off) // 4
@@ -51,9 +55,10 @@ wrapper[-4:] = struct.pack('<I', (imm & 0x03ffffff) | 0x14000000)
with open(out, 'wb') as f:
f.write(hdr)
f.write(wrapper)
f.write(bytes(uboot_off - wrap_off - wrap_len))
f.write(uboot)
print("layout: header 64, wrapper %d (0x40..0x%x), uboot %d, total %d" %
(wrap_len, uboot_off, len(uboot), total))
print("layout: header 64, wrapper %d (0x40..0x%x), uboot %d @0x%x, total %d" %
(wrap_len, uboot_off, len(uboot), uboot_off, total))
EOF
# 3. pack + verify
Binary file not shown.
BIN
View File
Binary file not shown.