pureboot: the classic megas and the word-addressed 1284P groundwork
Device: boot-section detection probes SPMCR beside SPMCSR, the link picks any hardware USART through the instance-aware lookups (URSEL chips included), WDRF reads MCUSR-or-MCUCSR, and the >64 KiB shape lands — word-addressed wire flash (info flag bit 1, page byte 0 means 256, base as a word address), far reads through flash_load_far, a single 32-bit byte-cursor page walk (the 256-byte page wraps its low byte exactly), and slot arithmetic in words (the return address already is one). Host: addresses stay bytes internally and scale at the wire, the boot-fuse decode becomes a per-signature table (byte index + BOOTSZ ladder — the m168A's lives in EXTENDED), and the planner tests pin every chip's ladder plus the word-addressed info decode. Tests: the device runner serves every mega over the USART pty, pbapp banners over the right link, the update rehearsal synthesizes its assumed fuses from the tool's own table, and the PI lint tracks the renamed info symbol. All six classic-mega/168A targets pass the full suite (size, PI, planner, protocol, reloc, self-update) at 466–504 B; the 1284P builds await a libavr far-path slimming to make its 512. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -142,6 +142,10 @@ endif()
|
||||
# compile-time constant; a different PUREBOOT_TIMEOUT builds the re-timed
|
||||
# binary a self-update then installs.
|
||||
set(PUREBOOT_TIMEOUT 8 CACHE STRING "pureboot activation window, seconds")
|
||||
# Every mega runs the loader from its hardware boot section and boots the
|
||||
# application at word 0; the tinies get the trampoline surgery. All megas
|
||||
# assume a 16 MHz crystal at 115200 Bd; the tinies their internal RC at
|
||||
# 57600 Bd over the software UART.
|
||||
if(LIBAVR_MCU STREQUAL "attiny13a")
|
||||
set(_pb_flash 1024)
|
||||
set(_pb_wrap "")
|
||||
@@ -158,6 +162,48 @@ elseif(LIBAVR_MCU STREQUAL "attiny85")
|
||||
set(_pb_baud 57600)
|
||||
set(_pb_eeprom 512)
|
||||
set(_pb_limit 510)
|
||||
elseif(LIBAVR_MCU MATCHES "^atmega8a?$")
|
||||
set(_pb_flash 8192)
|
||||
set(_pb_wrap -Wl,--pmem-wrap-around=8k)
|
||||
set(_pb_page 64)
|
||||
set(_pb_hz 16000000)
|
||||
set(_pb_baud 115200)
|
||||
set(_pb_eeprom 512)
|
||||
set(_pb_limit 512)
|
||||
elseif(LIBAVR_MCU STREQUAL "atmega16")
|
||||
set(_pb_flash 16384)
|
||||
set(_pb_wrap -Wl,--pmem-wrap-around=16k)
|
||||
set(_pb_page 128)
|
||||
set(_pb_hz 16000000)
|
||||
set(_pb_baud 115200)
|
||||
set(_pb_eeprom 512)
|
||||
set(_pb_limit 512)
|
||||
elseif(LIBAVR_MCU MATCHES "^atmega32a?$")
|
||||
set(_pb_flash 32768)
|
||||
set(_pb_wrap -Wl,--pmem-wrap-around=32k)
|
||||
set(_pb_page 128)
|
||||
set(_pb_hz 16000000)
|
||||
set(_pb_baud 115200)
|
||||
set(_pb_eeprom 1024)
|
||||
set(_pb_limit 512)
|
||||
elseif(LIBAVR_MCU STREQUAL "atmega168a")
|
||||
set(_pb_flash 16384)
|
||||
set(_pb_wrap -Wl,--pmem-wrap-around=16k)
|
||||
set(_pb_page 128)
|
||||
set(_pb_hz 16000000)
|
||||
set(_pb_baud 115200)
|
||||
set(_pb_eeprom 512)
|
||||
set(_pb_limit 512)
|
||||
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.
|
||||
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)
|
||||
else()
|
||||
set(_pb_flash 32768)
|
||||
set(_pb_wrap -Wl,--pmem-wrap-around=32k)
|
||||
@@ -169,12 +215,22 @@ else()
|
||||
endif()
|
||||
math(EXPR _pb_base "${_pb_flash} - 512")
|
||||
math(EXPR _pb_base_hex "${_pb_base}" OUTPUT_FORMAT HEXADECIMAL)
|
||||
if(LIBAVR_MCU STREQUAL "atmega328p")
|
||||
if(LIBAVR_MCU MATCHES "^atmega")
|
||||
set(_pb_app 0)
|
||||
else()
|
||||
math(EXPR _pb_app "${_pb_base} - 2")
|
||||
endif()
|
||||
|
||||
# simavr names its cores after the base dies; the A revisions run on them.
|
||||
set(_pb_sim_mcu ${LIBAVR_MCU})
|
||||
if(LIBAVR_MCU STREQUAL "atmega8a")
|
||||
set(_pb_sim_mcu atmega8)
|
||||
elseif(LIBAVR_MCU STREQUAL "atmega32a")
|
||||
set(_pb_sim_mcu atmega32)
|
||||
elseif(LIBAVR_MCU STREQUAL "atmega168a")
|
||||
set(_pb_sim_mcu atmega168)
|
||||
endif()
|
||||
|
||||
add_executable(pureboot pureboot/pureboot.cpp)
|
||||
target_link_libraries(pureboot PRIVATE libavr)
|
||||
target_compile_definitions(pureboot PRIVATE PUREBOOT_TIMEOUT=${PUREBOOT_TIMEOUT})
|
||||
@@ -205,7 +261,7 @@ if(PROJECT_IS_TOP_LEVEL)
|
||||
COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:pbapp> $<TARGET_FILE:pbapp>.bin)
|
||||
add_test(NAME pureboot.protocol
|
||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/pbtest.py
|
||||
${PB_DEVICE} $<TARGET_FILE:pureboot> ${LIBAVR_MCU} ${_pb_hz} ${_pb_base_hex}
|
||||
${PB_DEVICE} $<TARGET_FILE:pureboot> ${_pb_sim_mcu} ${_pb_hz} ${_pb_base_hex}
|
||||
${_pb_page} ${_pb_baud} ${_pb_eeprom} $<TARGET_FILE:pbapp>.bin
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/pureboot/pureboot.py
|
||||
${CMAKE_BINARY_DIR}/pbtest-work)
|
||||
@@ -215,7 +271,7 @@ if(PROJECT_IS_TOP_LEVEL)
|
||||
# installed one slot lower, must serve the full command set.
|
||||
add_test(NAME pureboot.reloc
|
||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/pbreloc.py
|
||||
${PB_DEVICE} $<TARGET_FILE:pureboot> ${LIBAVR_MCU} ${_pb_hz} ${_pb_base_hex}
|
||||
${PB_DEVICE} $<TARGET_FILE:pureboot> ${_pb_sim_mcu} ${_pb_hz} ${_pb_base_hex}
|
||||
${_pb_page} ${_pb_baud} ${CMAKE_CURRENT_SOURCE_DIR}/pureboot/pureboot.py
|
||||
${CMAKE_BINARY_DIR}/pbreloc-work)
|
||||
set_tests_properties(pureboot.reloc PROPERTIES TIMEOUT 180
|
||||
@@ -233,7 +289,7 @@ if(PROJECT_IS_TOP_LEVEL)
|
||||
add_image_outputs(pureboot9)
|
||||
add_test(NAME pureboot.update
|
||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/pbupdate.py
|
||||
${PB_DEVICE} $<TARGET_FILE:pureboot> $<TARGET_FILE:pureboot9> ${LIBAVR_MCU}
|
||||
${PB_DEVICE} $<TARGET_FILE:pureboot> $<TARGET_FILE:pureboot9> ${_pb_sim_mcu}
|
||||
${_pb_hz} ${_pb_base_hex} ${_pb_page} ${_pb_baud} $<TARGET_FILE:pbapp>.bin
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/pureboot/pureboot.py
|
||||
${CMAKE_BINARY_DIR}/pbupdate-work)
|
||||
|
||||
Reference in New Issue
Block a user