pureboot: a version number for the loader, not for the protocol
The info block's third byte was a protocol version that never moved in the loader's lifetime. It is the pureboot version now, and this change is version 2: the one number that says what a deployed loader is. Every loader already in the field answers 1. The protocol keeps no number of its own — a pureboot version implies it, and the host tool is what holds that map. pureboot.py states the loader-version window it speaks (OLDEST_LOADER/NEWEST_LOADER; a version that changes the protocol becomes the new floor there), so a loader newer than the tool is refused by name rather than decoded on the assumption nothing moved, while an older one is read, identified and installed like any other. The tool carries its own version, free to drift from the loader's: --version prints it and the window, --info leads with the device's, --update-loader names the version it installs. Tests: the planner unit pins the window — every version in it decodes, one above it is refused, an older loader's image is still found — and the live suite pins the built loader against the tool beside it, so a bump that reaches only one of them fails. The image is byte-identical to the previous build but for that byte. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -170,7 +170,7 @@ The info block (`b`):
|
||||
|
||||
| Offset | Content |
|
||||
|---|---|
|
||||
| 0–2 | `'P'`, `'B'`, protocol version (1) |
|
||||
| 0–2 | `'P'`, `'B'`, pureboot version (2) |
|
||||
| 3–5 | device signature |
|
||||
| 6 | SPM page size in bytes (0 means 256) |
|
||||
| 7–8 | loader base — application flash ends here (a word address when bit 1 is set) |
|
||||
@@ -180,6 +180,21 @@ The info block (`b`):
|
||||
Composites are the host's job: verify = read back and compare, erase =
|
||||
write `0xff` (per page for flash, per byte for EEPROM).
|
||||
|
||||
## Version
|
||||
|
||||
The third byte of the info block is the **pureboot version** — the loader's
|
||||
one identity number, and the only way to tell what a deployed loader is.
|
||||
Nothing else is numbered: the wire protocol has no version of its own, a
|
||||
pureboot version implies its protocol, and the host tool is what holds that
|
||||
map. It states the window of loader versions it speaks
|
||||
(`OLDEST_LOADER`/`NEWEST_LOADER` in `pureboot.py`); a version that changes
|
||||
the protocol becomes the new floor there. So far none has: pureboot 1 and 2
|
||||
speak the identical session, and a loader newer than the tool is refused by
|
||||
name rather than decoded on the assumption that nothing moved.
|
||||
|
||||
The tool carries its own version, free to drift from the loader's:
|
||||
`--version` prints both it and the window.
|
||||
|
||||
## Deployment
|
||||
|
||||
The build leaves three artifacts per chip. The ELF is a container for the
|
||||
@@ -245,7 +260,7 @@ BOOTRST does not exist there.
|
||||
## Updating the loader
|
||||
|
||||
`pureboot.py --update-loader new_pureboot.bin` replaces the resident loader
|
||||
with any pureboot build — a re-timed window, a newer protocol — using the
|
||||
with any pureboot build — a re-timed window, a newer version — using the
|
||||
loader itself as its own staging loader. The image is the loader's own 512
|
||||
bytes as a raw binary, or the Intel HEX the build emits beside it, which
|
||||
links the loader at its base inside an otherwise blank flash image:
|
||||
@@ -312,11 +327,12 @@ Intel HEX by extension. `--force` overrides the refusable safety checks (today:
|
||||
application data into a mega's reset walk region).
|
||||
|
||||
Readouts come one fact per line: `--info` prints the decoded info block
|
||||
field by field, `--fuses` each fuse byte on its own line — plus, on a
|
||||
boot-sectioned mega, the decoded meaning (where the BOOTSZ section starts,
|
||||
what BOOTRST does to reset). Transfers that take wire time — programming,
|
||||
reading, erasing, verifying, the update phases — draw a transient progress
|
||||
bar on stderr when it is a tty; logs and pipes see only the summary lines.
|
||||
field by field, the loader's version first; `--fuses` each fuse byte on its
|
||||
own line — plus, on a boot-sectioned mega, the decoded meaning (where the
|
||||
BOOTSZ section starts, what BOOTRST does to reset). Transfers that take
|
||||
wire time — programming, reading, erasing, verifying, the update phases —
|
||||
draw a transient progress bar on stderr when it is a tty; logs and pipes
|
||||
see only the summary lines.
|
||||
`-v`/`--verbose` adds the decisions as they happen: knock counts, the
|
||||
programming plan (vector-surgery targets, skipped blank pages), update
|
||||
state handling and per-phase page counts.
|
||||
|
||||
Reference in New Issue
Block a user