feat(flash): pure-Python firmware flasher over the OLD-frame protocol

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>
This commit is contained in:
michael
2026-07-05 21:33:01 -07:00
parent 42a9146e6c
commit 762e305dd9
5 changed files with 687 additions and 0 deletions

View File

@@ -15,6 +15,7 @@ from .hf_iso14a import HF14ACommands
from .hf_iso15 import HF15Commands
from .hf_mfc import HFMFCommands
from .hf_mfu import HFMFUCommands
from .flash import Flasher
log = logging.getLogger(__name__)
@@ -74,6 +75,7 @@ class Proxmark3:
self.hf.iso15 = HF15Commands(self._transport)
self.hf.mf = HFMFCommands(self._transport)
self.hf.mfu = HFMFUCommands(self._transport)
self.flasher = Flasher(self._transport)
self.firmware = FirmwareInfo()
async def connect(self) -> None: