docs: Pi install + pm3flash firmware flashing (README, CLAUDE, roadmap)
- README: rewrite Install (from source, submodules, deps, Pi/aarch64); new 'Flashing firmware (pm3flash)' section — CLI usage, --build, image resolution, cross-compile + PLATFORM note, Raspberry Pi bring-up, programmatic API; point Firmware Compatibility at it; add a License section (MIT). - CLAUDE.md: flash.py/_firmware.py/flash_cli.py in the structure; a 'Firmware flashing' section with the maintainer gotchas (OLD frame, fullimage-only, page-merge, platform != is_rdv4, the pin). - roadmap: new 2026-07-05-firmware-flasher plan doc + a Firmware-flashing row. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
50
docs/plans/2026-07-05-firmware-flasher.md
Normal file
50
docs/plans/2026-07-05-firmware-flasher.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# Pure-Python firmware flasher + `pm3flash`
|
||||
|
||||
**Status:** ✅ Landed (hardware-validated on a PM3 Easy) · **Date:** 2026-07-05
|
||||
Related: [firmware-fork DT-Gitea migration](2026-07-05-firmware-fork-dt-migration.md)
|
||||
|
||||
## Goal
|
||||
|
||||
Let pm3py get the fork firmware onto a device by itself — no C `pm3-flash`/DFU/JTAG — so
|
||||
`pip install pm3py` + one command flashes the build this pm3py corresponds to. Supports the
|
||||
project "in the meantime", before tagged firmware releases exist on the DT Gitea.
|
||||
|
||||
## What landed
|
||||
|
||||
- **`Flasher`** (`pm3py/core/flash.py`) over the legacy 544-byte **OLD frame** (bootloader
|
||||
protocol, distinct from the NG frames the rest of the client speaks; OLD-frame plumbing in
|
||||
`core/transport.py`). Automatic OS→bootloader handover (`CMD_START_FLASH`, no button),
|
||||
`CMD_FINISH_WRITE` block loop with per-block ACK/NACK, reset, reopen-and-verify.
|
||||
- **Safety:** fullimage-only by default; the bootrom region is refused unless
|
||||
`allow_bootrom=True`. A bad OS write is recoverable (proven — recovered a corrupted-OS
|
||||
device); a bad bootrom write bricks to JTAG.
|
||||
- **Firmware pin** (`pm3py/_firmware.py`): `FIRMWARE_PIN` = the fork build pm3py corresponds
|
||||
to (currently the submodule SHA). `pm3.firmware.matches_pin` / `.expected_firmware` on
|
||||
connect.
|
||||
- **`pm3flash` CLI** (`pm3py/flash_cli.py`): detect → resolve/build image → flash → verify.
|
||||
`--image` (prebuilt), `--build PLATFORM` (`make` from the submodule; platform explicit —
|
||||
never inferred from `is_rdv4`, which reports the running firmware, not the board),
|
||||
`--force`, `--allow-bootrom`.
|
||||
|
||||
## Lessons (found on hardware / by adversarial review)
|
||||
|
||||
- **Merge segments sharing a flash page.** The SAM7 erase-programs whole pages; two adjacent
|
||||
PT_LOAD segments in one page must be written once with both segments' data, else 0xFF
|
||||
padding clobbers real bytes (bug: the flashed OS booted but had invalid version info).
|
||||
- **`--build` must flash what it built,** not gate on the pin — a dirty rebuild keeps the same
|
||||
base SHA, so `matches_pin` can't distinguish it (`--build` therefore implies `--force`).
|
||||
- **No CWD-relative firmware discovery** — running `make` on a stray `./firmware` is arbitrary
|
||||
code execution; only an explicit arg / `$PM3PY_FIRMWARE_SRC` / the package repo root.
|
||||
|
||||
## Open follow-ups
|
||||
|
||||
- **Auto-download** of the pinned release asset (toolchain-free install) — needs a tagged
|
||||
firmware release to exist; rides on the DT-Gitea migration. Drops into `resolve_image`.
|
||||
- **Read-back verify** via `CMD_READ_MEM_DOWNLOAD` (v1 trusts per-block ACK/NACK, like the C
|
||||
flasher).
|
||||
|
||||
## Provenance
|
||||
|
||||
Built + hardware-validated in one session; the `--build` layer was adversarially reviewed by
|
||||
a multi-agent workflow (correctness / subprocess-safety / CLI-UX lenses with a verify pass),
|
||||
which surfaced the pin-skip, make-missing, and CWD-Makefile issues fixed above.
|
||||
@@ -49,6 +49,12 @@ approach, concrete steps, tests, risks.
|
||||
| [2026-07-03-firmware-upstream-rebase-plan](2026-07-03-firmware-upstream-rebase-plan.md) | 📎 | Rebase the `proxmark3-pm3py` fork against upstream PM3 (atomic single-file-commit workflow). |
|
||||
| [2026-07-05-firmware-fork-dt-migration](2026-07-05-firmware-fork-dt-migration.md) | 📋 | Migrate the firmware fork + pm3py to the DT Gitea; clean `master`(RRG-mirror)/`pm3py`(patches) rebase-fork model. |
|
||||
|
||||
## Firmware flashing
|
||||
|
||||
| Plan | Status | Summary |
|
||||
|------|--------|---------|
|
||||
| [2026-07-05-firmware-flasher](2026-07-05-firmware-flasher.md) | ✅ | Pure-Python flasher (OLD-frame bootloader protocol) + `pm3flash` CLI + firmware pin; hardware-validated on a PM3 Easy. Auto-download of the pinned release is the open follow-up (rides on the DT-Gitea migration). |
|
||||
|
||||
---
|
||||
|
||||
### Conventions
|
||||
|
||||
Reference in New Issue
Block a user