diff --git a/spi_check.py b/spi_check.py new file mode 100755 index 0000000..d0fef97 --- /dev/null +++ b/spi_check.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +"""RK3588 SPI image pre-flash integrity check. + +Verifies a u-boot-rockchip-spi*.bin image *before* the user commits +to a maskrom-recovery-prone flash. Catches the class of silent-build +failures that brick boards: + + - missing idbloader (binman packed 0xFF where RKNS wrapper should be) + - truncated idbloader (less than the declared payload region) + - mkimage-rejected TPL blob that left the SPL slot empty + +Does NOT execute code — pure static parsing. Fast and safe. + +Exit codes: + 0 = image has a valid-looking idbloader; safe to flash + 1 = file unreadable / too small + 2 = missing RKNS wrapper at 0x8000 (the "today's bug" case) + 3 = wrapper present but surrounding region is all 0xFF (payload missing) + +Usage: rk3588_spi_check.py +""" +import struct +import sys + +IDBL_OFFSET = 0x8000 +RKNS_MAGIC = 0x534E4B52 # "RKNS" LE — rkspi boot header +PAYLOAD_END = 0x60000 # stock u-boot places next section here + +def die(code, msg): + print(f"FAIL: {msg}", file=sys.stderr) + sys.exit(code) + +def main(path): + with open(path, "rb") as f: + data = f.read() + print(f"SPI image: {path} size=0x{len(data):x} ({len(data)} B)") + + if len(data) < PAYLOAD_END: + die(1, f"image too small ({len(data)} < 0x{PAYLOAD_END:x})") + + wrapper = struct.unpack_from("