pureboot: the 1284P rides a 1 KiB slot — its own boot-sector minimum

The far machinery (ELPM reads, RAMPZ page commands, wire-word math)
costs ~46 B over the m328P's 504, and the tsb-calibrated C++-to-asm
gap says no implementation of this feature set reaches 512 on this
chip — a boundary its hardware does not have anyway: the 1284P's
smallest boot sector is 1 KiB. The slot therefore becomes
per-geometry (512 B, or 1 KiB past 64 KiB), which the host derives
from the word-addressing flag; slot arithmetic unifies (the index is
the wire high byte with its low bit dropped in either unit), the
update preflight demands a two-slot boot section in the chip's own
terms, and pbapp's hand-back jumps to the real slot base. libavr's
far primitives split their RAMPZ/Z asm operands (a page never
crosses 64 KiB, so callers keep a byte and a 16-bit cursor — the
32-bit address folds away; flash_load_far's byte form becomes the
out-RAMPZ+elpm pair avr-libc's pgm_read_byte_far rebuilds per call),
and the host splits reads at 64 KiB boundaries. All ten chips pass
the full suite — the 1284P at 558 B including protocol, relocation,
and the power-fail self-update — with pureboot byte-identical across
generated and reflect modes everywhere, and the original three
chips' images unchanged to the byte (488/502/504).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-21 13:54:40 +02:00
parent 0fa53e1cad
commit 65f8fdd537
8 changed files with 122 additions and 72 deletions

View File

@@ -197,13 +197,16 @@ elseif(LIBAVR_MCU STREQUAL "atmega168a")
elseif(LIBAVR_MCU STREQUAL "atmega1284p")
# 128 KiB: wire flash addresses are word addresses, reads go through
# ELPM, and the PC's modulo wrap exceeds what --pmem-wrap-around models.
# The slot is 1 KiB — this chip's own smallest boot sector; the far
# machinery cannot fit 512 B (see pureboot/README.md).
set(_pb_flash 131072)
set(_pb_wrap "")
set(_pb_page 256)
set(_pb_hz 16000000)
set(_pb_baud 115200)
set(_pb_eeprom 4096)
set(_pb_limit 512)
set(_pb_limit 1024)
set(_pb_slot 1024)
else()
set(_pb_flash 32768)
set(_pb_wrap -Wl,--pmem-wrap-around=32k)
@@ -213,7 +216,10 @@ else()
set(_pb_eeprom 1024)
set(_pb_limit 512)
endif()
math(EXPR _pb_base "${_pb_flash} - 512")
if(NOT DEFINED _pb_slot)
set(_pb_slot 512)
endif()
math(EXPR _pb_base "${_pb_flash} - ${_pb_slot}")
math(EXPR _pb_base_hex "${_pb_base}" OUTPUT_FORMAT HEXADECIMAL)
if(LIBAVR_MCU MATCHES "^atmega")
set(_pb_app 0)