Wellfed Docs
well-fed.dev

Hardware

PLAF103 boot and flash layout

This page maps what we know of the PLAF103's 8 MiB flash: the boot material, the two application banks, Wellfed's storage region and the sectors stock uses. It is a reference for anyone writing tools or firmware that touch flash.

All values are flash offsets, with exclusive ends. Mapped external flash begins at 0x08000000. The machine-readable version is layout.json.

How it boots#

The PLAF103 uses the AmebaD's dual-core startup: factory loader and configuration first, then the application banks (chip memory map). Stock 1.1.15 loads its KM0 and KM4 image regions and picks an application bank by its validity marker. The factory loader checks bank 1 first and falls back to bank 0 (bank policy).

The map#

Range Role
0x000000–0x006000 Factory and pre-application material. Preserve. The SDK places KM0 boot, calibration, system data and KM4 boot here.
0x006000 Bank 0 start
0x186000 Bank 1 start, the stock recovery target
0x186000–0x2d6000 Stock's footprint in bank 1, as reviewed
0x340000–0x370000 Wellfed's storage region, 48 sectors (below)
0x3e8000–0x3f0000 Stock settings sectors
0x3f0000–0x400000 Stock clock-checkpoint block. Stock block-erases it when it saves the clock. Preserved (clock_checkpoint_block).
0x400000–0x401000 Stock audio-start sector
0x7cb000–0x7cc000 Stock log sector
0x7d0000–0x7d7000 Stock plan-record sectors
0x7da000–0x7db000 Stock error-record sector

This is not a complete partition map. Unknown gaps are not free storage. Physical flash ends at 0x800000. The OTP, eFuse and security registers sit outside it and are not in a normal flash backup.

Wellfed's storage region#

The region is STORAGE_OFFSET/STORAGE_SECTORS in firmware, and wellfed_board_plaf103::storage names the owner of every sector.

Sectors Owner
0–1 Feeding journal
2–3 Settings
4 Confirmation record
5–6 Wi-Fi credentials
7–8 Seed
9–10 Clients
11–12 Plans
13–24 Event ring
25–26 Update store
27–28 Time settings
29–31 Per-feed traces
32–33 Lifetime statistics
34–35 Portion calibration
36–47 Free

The region only grows upward. A sector keeps its address, and a build compiled for a smaller region never reaches the sectors added after it.

No flash tool writes this region. The development, update and stock-recovery writers stay inside their bank, and stock recovery also verifies that everything outside bank 1 is unchanged.

Flash clock#

Wellfed runs the flash at 50 MHz in Dual IO mode, set through KM0's Flash_Speed. At 80 MHz, over-the-air downloads into bank 0 hit random faults and single-bit read errors on our unit. At 50 MHz the boot calibration window is wider, and those faults have stopped in every install so far (8 of 8). We'll treat the fix as settled once the long unattended run passes. Quad IO is not used, because its check fails at the slow boot clock.

OTA images and the layout#

The pinned stock OTA file is 1,376,288 bytes, including a 32-byte container header. Its SHA-256 is 05147476fc70c91cc77ad7da6d6772376b2081d460ac7b1912e2d73868a09498. OTA container offsets and raw flash offsets are different coordinate systems.

Our structural auditor checks an image's checksum, declared lengths, headers, load addresses, placement and the known preserve ranges. It does not prove that the factory loader will boot a new image. Stock OTA requirements separates what stock checks from our stricter profile and from the factory loader's needs.

The flags in layout.json stay conservative: the map is incomplete, there is no general guarantee of verified capacity, and no general guarantee that an image boots. Read coverage and diagnostic boots apply to the research unit and the exact images tested.

The SDK's device and firstboot profiles overlay the stock-derived bank addresses and startup pin pulls. They do not replace or validate the SDK's separately generated bootloader, and generated loader files are unsupported. See build profiles and recovery.

Evidence#

  • Recovered: the SDK's placement of boot material in 0x000000–0x006000, and stock's block erase of the clock-checkpoint block on its clock save.
  • Observed: the stock settings, audio-start, log, plan-record and error-record sectors.
  • Modeled: running the factory loader's instructions against modeled ROM and MMIO accepts the reviewed diagnostic in both bank fixtures. It is not a full reset-path or power-cut simulation.
  • Storage region growth: the owner extended the region from 16 sectors on October 23, 2026, and from 32 to 48 on October 26. Both rest on a static pass that found no stock access in 0x306000–0x3e8000, and on all 15 full dumps reading blank there (resource budget).
  • Observed, October 27, 2026 (flash clock): at 80 MHz, bank 0's downloads faulted at random sectors and one readback returned a single flipped bit. At 50 MHz the calibration window read 29–31 over 15 boots, against 11–17 at 80 MHz, and 8 of 8 alternating over-the-air installs through bank 0 passed with no fault. That is one evening's runs, not yet a sustained run.