review: the port's findings — the version map speaks v7, costs told true

The in-file version window now carries the v7 line its own comment
claimed to hold; the GPIOR note counts words, not instructions; the
USART-release cost and citation match the silicon (two bytes on the
classics, §20.6.3); and the 512-byte claim reads as the slot bound it
is. The libavr pin advances over the review pass — images byte-identical.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-28 18:44:32 +02:00
parent 5bc35a9733
commit b60f182105
4 changed files with 13 additions and 8 deletions

2
libavr

Submodule libavr updated: 6f8771f411...674e63e8f9

View File

@@ -2,8 +2,8 @@
A serial bootloader on [libavr](https://git.blackmark.me/avr/libavr), pure by A serial bootloader on [libavr](https://git.blackmark.me/avr/libavr), pure by
constraint: one C++ source, no inline assembly, no global register variables constraint: one C++ source, no inline assembly, no global register variables
(attributes and compiler flags allowed), **512 bytes on every chip libavr (attributes and compiler flags allowed), **a 512-byte slot on every chip
targets — all 37**. The device speaks primitives; every composite — verify, libavr targets — all 37**. The device speaks primitives; every composite — verify,
erase, reset-vector surgery, updating the loader itself — lives in the host erase, reset-vector surgery, updating the loader itself — lives in the host
tool (`pureboot.py`). tool (`pureboot.py`).
@@ -88,7 +88,8 @@ the usual one where a board's USB bridge is wired to RXD/TXD: the link's `init`
clears that USART's `UCSRnB` first, because while its `TXEN` is set the USART — clears that USART's `UCSRnB` first, because while its `TXEN` is set the USART —
not the port register — owns the TX pin, and a loader entered from an not the port register — owns the TX pin, and a loader entered from an
application that left it enabled would receive and obey while answering nothing application that left it enabled would receive and obey while answering nothing
(§20.2). It costs four bytes, and only on those pins. (§20.6.3). It costs one store — four bytes on the extended-I/O chips, two on
the classic megas — and only on those pins.
`SERIAL autobaud` takes neither: the loader **measures** the host's bit timing `SERIAL autobaud` takes neither: the loader **measures** the host's bit timing
at run time, so `CLOCK` and `BAUD` are not build parameters there and one at run time, so `CLOCK` and `BAUD` are not build parameters there and one

View File

@@ -1,6 +1,6 @@
// pureboot — a serial bootloader on libavr: one C++ source, no inline // pureboot — a serial bootloader on libavr: one C++ source, no inline
// assembly, no global register variables, 512 bytes on every chip libavr // assembly, no global register variables, a 512-byte slot on every chip
// targets. The device speaks primitives; every composite (verify, erase, // libavr targets. The device speaks primitives; every composite (verify, erase,
// reset-vector surgery, self-update) lives in the host tool. Protocol, // reset-vector surgery, self-update) lives in the host tool. Protocol,
// deployment and configuration: README.md next to this file. // deployment and configuration: README.md next to this file.
// //
@@ -242,8 +242,8 @@ struct software_link {
// clock to time a window against — so this backend brings its own, below. // clock to time a window against — so this backend brings its own, below.
struct autobaud_link { struct autobaud_link {
// The unit in GPIOR2:GPIOR1 where the chip has them: the loader owns the // The unit in GPIOR2:GPIOR1 where the chip has them: the loader owns the
// whole chip while it runs, and the pair is four instructions cheaper per // whole chip while it runs, and the pair costs one word per access where
// session than a RAM word. // the RAM word costs two — six words across the image.
using uart = avr::uart::software_autobaud<avr::PUREBOOT_RX, avr::PUREBOOT_TX, avr::uart::unit_home::gpior>; using uart = avr::uart::software_autobaud<avr::PUREBOOT_RX, avr::PUREBOOT_TX, avr::uart::unit_home::gpior>;
static void init() static void init()

View File

@@ -42,6 +42,10 @@ RETRIES = 3 # rewrites of a page that reads back wrong, before the run stops
# 'g' writes, each taking a selector byte, a 16-bit address and a count, over # 'g' writes, each taking a selector byte, a 16-bit address and a count, over
# the spaces below. The loader carries one transfer loop instead of four bodies # the spaces below. The loader carries one transfer loop instead of four bodies
# — which is what buys the data space and the host-issued SPM operations. # — which is what buys the data space and the host-issued SPM operations.
# 6 marks the builds that may carry a baked OSCCAL trim, nothing on the wire;
# 7 gives 'J' a selector byte (older loaders take the bare address — jump()
# sends each form to the version that speaks it) and re-homes the autobaud
# unit into the GPIOR pair where the chip has one.
UNIFIED_LOADER = 5 UNIFIED_LOADER = 5
SP_FLASH, SP_EEPROM, SP_RAM, SP_FUSE, SP_SPM = 0, 1, 2, 3, 4 SP_FLASH, SP_EEPROM, SP_RAM, SP_FUSE, SP_SPM = 0, 1, 2, 3, 4