Found on the first real-hardware flash (PM3 Easy). The fullimage ELF has two
adjacent PT_LOAD segments (seg1 ends at 0x15E5AC, seg2 starts there) that share
the 0x15E400 flash page. build_blocks aligned each segment independently, so the
shared page was written twice — seg2's 0xFF-padded head, written last,
erase-programmed the page and wiped seg1's real bytes there (the SAM7 programs a
whole page atomically). That region holds version_information, so the flashed OS
booted but reported 'Missing/Invalid version information'.
Fix: merge segments whose block-aligned spans touch into one buffer, so every
shared page is written once with both segments' real data; 0xFF only fills gaps
and aligned outer edges. Re-flash verified on hardware: 3df2ed2e8 -> 303bd5873,
valid version, matches_pin true. Bootrom untouched throughout (fullimage-only).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drives the full flash flow over the existing USB-serial link — enter
bootloader, arm window, stream the ELF block-by-block, reset — with no
external pm3-flash/DFU/JTAG.
- core/flash.py: Flasher (device_info, auto OS->bootloader handover,
flash_image block loop with ACK/NACK+EFC status, reset, end-to-end flash);
ELF32-ARM PT_LOAD parsing; 0xFF-padded block alignment; image resolver.
- core/transport.py: OLD 544-byte frame encode/decode, send_old /
send_old_no_response, magic-branching frame reader, reopen() for USB
re-enumeration.
- core/protocol.py: DEVICE_INFO flags, START_FLASH_MAGIC, flash geometry,
BL version helpers.
- Wired as pm3.flasher; reachable through the sync proxy.
Safety: fullimage-only by default; bootrom region refused unless
allow_bootrom=True; every block bounds-checked against the flash window.
Verification is per-block ACK/NACK (as the C flasher does); read-back verify
and hardware validation are follow-ups. 22 tests; suite 1026 pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>