Flash status: scan PICOBIN blocks for per-slot validity and version
This commit is contained in:
@@ -227,7 +227,12 @@ func cmdFlashStatus(args []string) error {
|
||||
slog.Info("flash-status",
|
||||
"via", t.name,
|
||||
"boot_partition", status.BootPartition,
|
||||
"boot_type", status.BootType)
|
||||
"slot_a_valid", status.SlotA.Valid,
|
||||
"slot_a_version", status.SlotA.Version,
|
||||
"slot_a_hash_ok", status.SlotA.HashOK,
|
||||
"slot_b_valid", status.SlotB.Valid,
|
||||
"slot_b_version", status.SlotB.Version,
|
||||
"slot_b_hash_ok", status.SlotB.HashOK)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -128,12 +128,21 @@ struct RequestFlashStatus {
|
||||
auto as_tuple() { return std::tie(); }
|
||||
};
|
||||
|
||||
struct SlotInfo {
|
||||
bool valid;
|
||||
uint32_t version;
|
||||
bool hash_ok;
|
||||
auto as_tuple() const { return std::tie(valid, version, hash_ok); }
|
||||
auto as_tuple() { return std::tie(valid, version, hash_ok); }
|
||||
};
|
||||
|
||||
struct ResponseFlashStatus {
|
||||
static constexpr int8_t ext_id = 15;
|
||||
int8_t boot_partition;
|
||||
uint8_t boot_type;
|
||||
auto as_tuple() const { return std::tie(boot_partition, boot_type); }
|
||||
auto as_tuple() { return std::tie(boot_partition, boot_type); }
|
||||
SlotInfo slot_a;
|
||||
SlotInfo slot_b;
|
||||
auto as_tuple() const { return std::tie(boot_partition, slot_a, slot_b); }
|
||||
auto as_tuple() { return std::tie(boot_partition, slot_a, slot_b); }
|
||||
};
|
||||
|
||||
struct RequestListTests {
|
||||
|
||||
@@ -3,12 +3,15 @@
|
||||
#include "pico/bootrom.h"
|
||||
#include "hardware/flash.h"
|
||||
#include "hardware/watchdog.h"
|
||||
#include "boot/picobin.h"
|
||||
#include "dispatch.h"
|
||||
#include "net.h"
|
||||
#include "debug_log.h"
|
||||
|
||||
static constexpr uint32_t XIP_BASE_ADDR = 0x10000000;
|
||||
static constexpr uint32_t FLASH_SIZE = 2 * 1024 * 1024;
|
||||
static constexpr uint32_t SLOT_A_OFFSET = 0x00000;
|
||||
static constexpr uint32_t SLOT_B_OFFSET = 0x80000;
|
||||
static boot_reason detected_boot_reason;
|
||||
|
||||
static void poke_watchdog() {
|
||||
@@ -88,16 +91,43 @@ std::optional<ResponseFlashWrite> handle_flash_write(const responder&, const Req
|
||||
return ResponseFlashWrite{};
|
||||
}
|
||||
|
||||
static SlotInfo scan_slot(uint32_t flash_offset) {
|
||||
SlotInfo info{};
|
||||
constexpr uint32_t scan_limit = 4096;
|
||||
auto* scan = reinterpret_cast<const uint32_t*>(XIP_BASE_ADDR + flash_offset);
|
||||
auto* scan_end = scan + scan_limit / 4;
|
||||
while (scan < scan_end && *scan != PICOBIN_BLOCK_MARKER_START) scan++;
|
||||
if (scan >= scan_end) return info;
|
||||
info.valid = true;
|
||||
|
||||
auto* p = reinterpret_cast<const uint8_t*>(scan + 1);
|
||||
auto* end = reinterpret_cast<const uint8_t*>(scan + 64);
|
||||
while (p + 2 <= end) {
|
||||
uint8_t type = p[0];
|
||||
uint8_t size_words = p[1];
|
||||
if (type == PICOBIN_BLOCK_ITEM_2BS_LAST) break;
|
||||
uint32_t item_bytes = static_cast<uint32_t>(size_words) * 4;
|
||||
if (p + item_bytes > end) break;
|
||||
if (type == PICOBIN_BLOCK_ITEM_1BS_VERSION && size_words >= 2) {
|
||||
auto* words = reinterpret_cast<const uint16_t*>(p + 4);
|
||||
uint16_t minor = words[0];
|
||||
uint16_t major = words[1];
|
||||
info.version = (static_cast<uint32_t>(major) << 16) | minor;
|
||||
}
|
||||
p += item_bytes;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
std::optional<ResponseFlashStatus> handle_flash_status(const responder&, const RequestFlashStatus&) {
|
||||
ResponseFlashStatus resp;
|
||||
boot_info_t bi;
|
||||
if (rom_get_boot_info(&bi)) {
|
||||
if (rom_get_boot_info(&bi))
|
||||
resp.boot_partition = bi.partition;
|
||||
resp.boot_type = bi.boot_type;
|
||||
} else {
|
||||
else
|
||||
resp.boot_partition = -1;
|
||||
resp.boot_type = 0;
|
||||
}
|
||||
resp.slot_a = scan_slot(SLOT_A_OFFSET);
|
||||
resp.slot_b = scan_slot(SLOT_B_OFFSET);
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,9 +63,17 @@ type RequestReboot struct{}
|
||||
type ResponseReboot struct{}
|
||||
|
||||
type RequestFlashStatus struct{}
|
||||
|
||||
type SlotInfo struct {
|
||||
Valid bool
|
||||
Version uint32
|
||||
HashOK bool
|
||||
}
|
||||
|
||||
type ResponseFlashStatus struct {
|
||||
BootPartition int8
|
||||
BootType uint8
|
||||
SlotA SlotInfo
|
||||
SlotB SlotInfo
|
||||
}
|
||||
|
||||
type RequestListTests struct{}
|
||||
|
||||
Reference in New Issue
Block a user