The firmware confirms the app slots, and the page numbers them like upstream

UVStudio's own js/flash.js names the protocol: MSG_APP_INFO 0x0730/0x0731, MSG_APP_ERASE 0x0732/0x0733, MSG_APP_WRITE 0x0734/0x0735, MSG_APP_VALIDATE 0x0736/0x0737, with APP_SLOT_COUNT 16, APP_IMG_OFFSET 0x1000, APP_HDR_SIZE 64 and APP_MAGIC 0x31504146 -- the constants this page already used. It uses slots 0..7 and labels them 1..8, and writes the header last so a partial write cannot validate; the page now labels slots the same way.

The Labs build answers 0x0730 over USART, so an installed Beam.app was queried on the radio: slot 0 came back status 0 with the header this page wrote (FAP1, code_size 1100, CRC 0x0d976058, flags 0x0801, name Beam), which confirms the region, the offset and the layout from the firmware's side rather than from a header I read. Slots 1 and 2 answered status 2 with unrelated data -- the overlap the install guard refuses to overwrite.
This commit is contained in:
mckero committed 2026-10-01 17:17:22 +08:00
1 parent 617c1e2dbd
commit 0267371e28
3 files changed
+41 -2

No files matched your search

+4 -2
View File
@@ -942,7 +942,7 @@ def render_index(scale: int) -> str:
<label>Overlay apps</label>
<span id="appstate">-</span>
<span class="hint">the Labs edition's apps live in the same external flash (16 slots
from 0x102000, the firmware's menu lists the first eight). Pick a .app for a slot to
from 0x102000; the firmware's menu lists the first eight, numbered 1..8). Pick a .app for a slot to
install it — no serial port and no browser permission are involved</span>
</div>
<table id="apptable"><tbody></tbody></table>
@@ -1300,7 +1300,9 @@ async function loadApps() {{
: s.state === 'empty' ? '<i>Empty</i>'
: '<i>' + s.state + '</i> — not an app';
const size = s.state === 'app' ? s.code_size + ' B' : '';
tr.innerHTML = '<td>app ' + s.slot + (s.slot < 8 ? '' : ' (after the menu)') +
// Upstream and the firmware's own menu number the eight usable slots 1..8, while the
// region has sixteen: slot 0 is "1" there, so show them the same way.
tr.innerHTML = '<td>app ' + (s.slot + 1) + (s.slot < 8 ? '' : ' (after the menu)') +
'</td><td>' + what + '</td><td>' + size + '</td><td></td>';
const td = tr.lastElementChild;
const inp = document.createElement('input');