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:
1 parent
999d087eb4
commit
51535953b9
1 file changed
+10
-37
+10
-37
@@ -4,24 +4,12 @@
|
||||
|
||||
#include "board.hpp"
|
||||
|
||||
// Reaching the resident bootloader from the console.
|
||||
//
|
||||
// The legacy firmware did this with a watchdog reset: `bootloader` armed the
|
||||
// watchdog and hung, and the next boot noticed WDRF and jumped to the boot
|
||||
// section. That works for TinySafeBoot and **does not work for pureboot**, which
|
||||
// deliberately hands straight back to the application on WDRF - an unattended
|
||||
// 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.
|
||||
// Reaching the resident bootloader from the console. pureboot hands straight
|
||||
// back to the application on WDRF - an unattended board that watchdog-resets in
|
||||
// a loop must not sit in a loader instead of running - so a reset-based route
|
||||
// opens no window at all, and on a board whose only way in is the firmware that
|
||||
// is a lockout. This route jumps instead, with the reset flags already clear,
|
||||
// so the loader starts as if from a clean power-on and opens its window.
|
||||
namespace app {
|
||||
|
||||
class bootloader {
|
||||
@@ -29,17 +17,10 @@ class bootloader {
|
||||
|
||||
using guard = dev::watchdog<{.timeout = 16_ms}>;
|
||||
|
||||
// The top 512 bytes. An erased slot reads 0xffff, which is not an
|
||||
// instruction any loader begins with - so this asks "is a loader installed"
|
||||
// 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.
|
||||
// The top 512 bytes: `hfuse d4` puts the boot section at 0x7c00, with
|
||||
// pureboot's staging slot below its own slot.
|
||||
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
|
||||
// halves. [[gnu::noipa]] keeps the call indirect: a constant target folds
|
||||
// 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
|
||||
// port register, so a loader that bit-bangs the same pin receives
|
||||
// perfectly and answers into nothing - mute, not deaf, and unverifiable
|
||||
// from the host. pureboot clears this itself; TinySafeBoot, which is what
|
||||
// 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.
|
||||
// perfectly and answers into nothing. pureboot releases it itself; this
|
||||
// keeps the hand-over correct for a loader that does not.
|
||||
avr::hw::ucsr0b::write(0);
|
||||
|
||||
call(reinterpret_cast<jump_fn>(base / 2));
|
||||
}
|
||||
|
||||
static bool available()
|
||||
{
|
||||
return present();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
Reference in new issue
Block a user