console: the bootloader route drops a dead probe and two stale claims

present() and its available() wrapper had no caller. The comments said the
board still carries TinySafeBoot and that the USART clear exists so the route
could be tested before the loader was replaced; pureboot is the board's loader,
so the clear is now stated as what it is, loader-agnostic. The legacy route's
history stays in the README, where a reader of the old firmware looks for it.
No image moved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
BlackMarkandClaude Opus 5.5 committed 2026-10-23 21:50:21 +02:00
1 parent 999d087eb4
commit 51535953b9
1 file changed
+10 -37
+10 -37
View File
@@ -4,24 +4,12 @@
#include "board.hpp" #include "board.hpp"
// Reaching the resident bootloader from the console. // Reaching the resident bootloader from the console. pureboot hands straight
// // back to the application on WDRF - an unattended board that watchdog-resets in
// The legacy firmware did this with a watchdog reset: `bootloader` armed the // a loop must not sit in a loader instead of running - so a reset-based route
// watchdog and hung, and the next boot noticed WDRF and jumped to the boot // opens no window at all, and on a board whose only way in is the firmware that
// section. That works for TinySafeBoot and **does not work for pureboot**, which // is a lockout. This route jumps instead, with the reset flags already clear,
// deliberately hands straight back to the application on WDRF - an unattended // so the loader starts as if from a clean power-on and opens its window.
// board that watchdog-resets in a loop must not sit in a loader instead of
// running. So a reset-based route into pureboot opens no window at all, and on a
// board whose only way in is the firmware that is a lockout.
//
// This route therefore never resets. It jumps, with the reset flags already
// clear, so the loader starts as if from a clean power-on and opens its window.
//
// The address is this board's, and it is not the legacy one: the loader lives in
// the top 512 bytes at 0x7e00 (`hfuse d4` puts the boot section at 0x7c00 with
// pureboot's staging slot below its own slot). The legacy firmware probed 0x7800
// - a 2 KB boot section's base - which on this board reads erased, so its check
// was always false and its `bootloader` command never actually arrived anywhere.
namespace app { namespace app {
class bootloader { class bootloader {
@@ -29,17 +17,10 @@ class bootloader {
using guard = dev::watchdog<{.timeout = 16_ms}>; using guard = dev::watchdog<{.timeout = 16_ms}>;
// The top 512 bytes. An erased slot reads 0xffff, which is not an // The top 512 bytes: `hfuse d4` puts the boot section at 0x7c00, with
// instruction any loader begins with - so this asks "is a loader installed" // pureboot's staging slot below its own slot.
// rather than "is it the one I expect", which is the check the legacy
// firmware got wrong in the other direction by testing one specific byte.
static constexpr std::uint16_t base = 0x7e00; static constexpr std::uint16_t base = 0x7e00;
static bool present()
{
return avr::flash_load(reinterpret_cast<const std::uint16_t *>(base)) != 0xffff;
}
// A function pointer holds a word address on AVR, so the byte address // A function pointer holds a word address on AVR, so the byte address
// halves. [[gnu::noipa]] keeps the call indirect: a constant target folds // halves. [[gnu::noipa]] keeps the call indirect: a constant target folds
// into a relative call that cannot reach across flash. // into a relative call that cannot reach across flash.
@@ -73,20 +54,12 @@ class bootloader {
// Release the USART. While TXEN0 is set the peripheral owns PD1, not the // Release the USART. While TXEN0 is set the peripheral owns PD1, not the
// port register, so a loader that bit-bangs the same pin receives // port register, so a loader that bit-bangs the same pin receives
// perfectly and answers into nothing - mute, not deaf, and unverifiable // perfectly and answers into nothing. pureboot releases it itself; this
// from the host. pureboot clears this itself; TinySafeBoot, which is what // keeps the hand-over correct for a loader that does not.
// this board still carries, does not. Four bytes make the hand-over work
// for either one, which is the only reason this route can be tested
// before the loader is replaced.
avr::hw::ucsr0b::write(0); avr::hw::ucsr0b::write(0);
call(reinterpret_cast<jump_fn>(base / 2)); call(reinterpret_cast<jump_fn>(base / 2));
} }
static bool available()
{
return present();
}
}; };
} // namespace app } // namespace app