mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-09-17 04:04:19 +00:00
deploy: 49dcba5c6e
This commit is contained in:
@@ -1650,9 +1650,9 @@ provisioned locally before either application or bootloader OTA.</p>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Qualified internal-flash target</td>
|
||||
<td style="text-align: right;">normal <code>0xED000</code> limit</td>
|
||||
<td style="text-align: right;">normal <code>0xED000</code> flash limit; top 64 KiB SRAM reserved for application-delta staging</td>
|
||||
<td style="text-align: right;">shared internal slot, exact start <code>0xE2000</code></td>
|
||||
<td style="text-align: right;">the same eleven-page slot; no second reservation</td>
|
||||
<td style="text-align: right;">the same eleven-page slot; no second flash reservation</td>
|
||||
<td>source <code>0xED</code>, flags <code>0x0A</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -1698,10 +1698,13 @@ write a raw-sector compatibility record because a blank sector is not proof of
|
||||
ownership. Upgrade preview.12 through USB/BLE DFU or SWD. Both fmt2 application
|
||||
and fmt3 bootloader OTA then require the installed BLM2 metadata to match the
|
||||
live SoftDevice/application layout; neither MeshCore nor OTAFIX uses sector 1.</p>
|
||||
<p>The internal path does not change the application linker or permanently set
|
||||
aside separate app-OTA, boot-package, and scratch regions. The ordinary
|
||||
bottom-aligned internal store holds one container at a time: either an
|
||||
application delta or a bootloader package.</p>
|
||||
<p>The internal path does not change the application's <code>0xED000</code> flash limit or
|
||||
permanently set aside separate app-OTA, boot-package, and flash-scratch
|
||||
regions. Qualified applications do use a dedicated linker that reserves the
|
||||
top 64 KiB of SRAM for hybrid application-delta staging and a retained
|
||||
authorization record. That SRAM is never part of a bootloader-update package.
|
||||
The ordinary bottom-aligned internal flash store holds one container prefix at
|
||||
a time: either an application delta or the complete bootloader package.</p>
|
||||
<p>The exact bootloader container is 41,330 bytes: 365 bytes of signed mOTA
|
||||
metadata, a 40 KiB payload, and the five-byte trailer. Below the normal
|
||||
<code>0xED000</code> store ceiling it bottom-aligns at <code>0xE2000</code>. Admission requires a
|
||||
@@ -1711,10 +1714,13 @@ erasing and compacts the payload forward in place to the page-aligned raw range
|
||||
<code>0xE2000..0xEC000</code>; it verifies every page and the whole image before asking the
|
||||
MBR to copy that image over <code>0xF4000..0xFE000</code>.</p>
|
||||
<p>An ordinary application delta can be smaller or larger than this eleven-page
|
||||
shape. It bottom-aligns dynamically below <code>0xED000</code> and may begin below
|
||||
<code>0xE2000</code>; its detools workspace must stop at its actual container start, while
|
||||
the reconstructed application must stop below <code>0xED000</code>. The two package kinds
|
||||
are mutually exclusive because they use the same store.</p>
|
||||
shape. On the qualified profile, a delta larger than one page uses the minimum
|
||||
page-aligned flash prefix ending at <code>0xED000</code> and keeps up to 64 KiB of its
|
||||
logical tail in reset-retained SRAM; its detools workspace must stop at the
|
||||
actual flash-prefix start. A one-page-or-smaller delta stays wholly in flash.
|
||||
In either case the reconstructed application must stop below <code>0xED000</code>. The
|
||||
two package kinds are mutually exclusive because they use the same flash
|
||||
store, and a bootloader package never uses the volatile SRAM suffix.</p>
|
||||
<p>For internal-self-update builds, an absent or corrupt live <code>EndF</code> disables
|
||||
<strong>all</strong> internal staging before the first erase. The older 608 KiB rescue
|
||||
estimate is unsafe when a normally linked application may extend to
|
||||
|
||||
+33
-17
@@ -2629,7 +2629,9 @@ fills its own <code>leaves[i]</code> as each verified block lands.</p>
|
||||
(<code>!= FF FF FF FF</code>). Because <code>leaves[]</code> live in the staged flash region, availability <strong>survives reboot</strong>.</p>
|
||||
<p><strong>Commit order per block (crash-safe):</strong> (1) verify proof, (2) write block payload to its offset, (3) write
|
||||
<code>leaves[i]</code> <strong>last</strong>. A power loss before step 3 leaves the slot erased -> the block is simply re-fetched
|
||||
(idempotent). On boot a node rebuilds an in-RAM present-bitmap by scanning <code>leaves[]</code>.</p>
|
||||
(idempotent). On boot a node rebuilds an in-RAM present-bitmap by scanning <code>leaves[]</code> for a persistent,
|
||||
reopenable store. A hybrid nRF52 transfer is the deliberate exception: its SRAM-backed payload suffix is
|
||||
volatile, so the application refuses to adopt that staged header instead of rebuilding partial progress.</p>
|
||||
<p><strong>Resume (<code>OtaManager::resumeStaged</code> + <code>OtaStore::checkpoint</code>/<code>reopen</code>):</strong> an interrupted fetch resumes from
|
||||
the staged container after a reboot - re-parse the stored manifest, recompute geometry, count present
|
||||
blocks, continue fetching the holes (or jump straight to COMPLETE). The checkpoint cadence (persist progress
|
||||
@@ -2640,11 +2642,14 @@ floor requires a strictly newer manifest. An explicit MID pull may deliberately
|
||||
package and keeps target <code>0</code> as a MID-only wildcard. Stores keep <code>leaves[]</code> in RAM until flush and never
|
||||
auto-GC, preserving resumable progress. The debug/operator equivalent is <code>ota dev resume <MID8></code>; after a
|
||||
reboot the MID is mandatory, while a no-argument form may only reuse a still-active session MID. It never
|
||||
uses the <code>nullptr</code> automatic-adoption path, so a malformed MID or no active MID fails closed.</p>
|
||||
uses the <code>nullptr</code> automatic-adoption path, so a malformed MID or no active MID fails closed.
|
||||
Hybrid nRF52 staging cannot enter this resume path after an application restart, even if its flash prefix
|
||||
still contains metadata; the complete logical container must be fetched again.</p>
|
||||
<p><strong>Flash-store note (RX-safe writes):</strong> a flash page-erase halts the CPU (~85 ms on nRF52) and starves LoRa
|
||||
RX, so the flash stores (<code>OtaStoreFlashNrf52</code>/<code>OtaStoreFlashEsp32</code>) <strong>coalesce writes to the erase unit</strong>
|
||||
(4 KB page / sector) and commit each once off the per-packet path - RAM stays O(one page), not O(image). A
|
||||
small delta that fits page 0 does zero flash I/O until COMPLETE.</p>
|
||||
(4 KB page / sector) and commit each once off the per-packet path. Ordinary stores keep RAM at O(one page),
|
||||
not O(image); a qualified hybrid nRF52 profile additionally reserves one fixed 64 KiB staging arena. A small
|
||||
delta that fits page 0 does zero flash I/O until COMPLETE.</p>
|
||||
<hr />
|
||||
<h2 id="8-lora-ota-protocol">8. LoRa OTA protocol</h2>
|
||||
<p>Carried in MeshCore packets with <strong><code>PAYLOAD_TYPE_OTA = 0x0C</code></strong>. Every OTA packet payload is:</p>
|
||||
@@ -3199,16 +3204,26 @@ retains its <code>.part</code> file; it does not erase the unrelated manual-inst
|
||||
<li><strong>nRF52 internal staging ceiling:</strong> an internal-store application derives the ceiling from facts available
|
||||
in every build, not a board-name list. A companion that actually links the internal ExtraFS datastore stays
|
||||
below <code>0xD4000</code>; a default linker region or a role that does not mount ExtraFS can reclaim the unused
|
||||
100 KiB through <code>0xED000</code>. An internal bootloader-self-update target keeps that normal linker and ceiling;
|
||||
it does not reserve a second boot-package or scratch region. The application uses a larger-than-legacy
|
||||
window only when the
|
||||
installed bootloader advertises the GPREGRET2 ceiling-handoff capability. The bootloader treats every
|
||||
unknown/legacy handoff value as
|
||||
<code>0xD4000</code>, and accepts a container only at the bottom-aligned position for the selected ceiling.</li>
|
||||
100 KiB through <code>0xED000</code>. A qualified internal bootloader-self-update target keeps that normal flash
|
||||
ceiling and does not reserve a second boot-package or flash-scratch region, but it uses a dedicated
|
||||
application linker that reserves the top 64 KiB of SRAM (<code>0x20030000..0x20040000</code>) plus a 72-byte
|
||||
retained authorization record after the existing persistent clock bytes. Application deltas larger than
|
||||
one flash page use a deterministic page-aligned flash prefix ending at <code>0xED000</code> and place up to 64 KiB
|
||||
of the logical container tail in that SRAM. Packages of one page or less, and bootloader-update packages,
|
||||
remain wholly in flash. Hybrid staging is enabled only when the installed bootloader contains exactly one
|
||||
valid <code>MOTARAMA</code> capability marker; otherwise a larger hybrid-profile fetch fails before erase. Immediately
|
||||
before a software reset the application publishes a valid-last <code>MOTAHYB1</code> record binding the split geometry
|
||||
and normalized container hash. The bootloader consumes it once and rejects power-loss, stale-reset, corrupt,
|
||||
or mismatched-RAM cases before its first application write. A hybrid transfer cannot resume after an
|
||||
application restart because its suffix is deliberately volatile. The bootloader treats every unknown/legacy
|
||||
GPREGRET2 handoff value as <code>0xD4000</code>, and accepts a flash-only container only at the bottom-aligned position
|
||||
for the selected ceiling.</li>
|
||||
<li><strong>nRF52 dynamic apply window:</strong> the post-build hook records the resolved app base, linked app end,
|
||||
internal-ExtraFS/SD/QSPI storage flags, and desired staging ceiling immediately before <code>EndF</code>. <code>motatool</code> reads that authenticated
|
||||
firmware record and chooses <code>memory_size</code> from the actual patch size and bottom-aligned stage address;
|
||||
firmware without the record retains the conservative <code>0x98000</code> default. Before writing <code>APRV</code>, an
|
||||
internal-ExtraFS/SD/QSPI/hybrid-RAM storage flags, and desired staging ceiling immediately before <code>EndF</code>.
|
||||
<code>motatool</code> reads that authenticated firmware record and chooses <code>memory_size</code> from the actual patch size
|
||||
and bottom-aligned stage address. For a hybrid base it charges only the deterministic flash prefix against
|
||||
that workspace; the retained-RAM suffix is still part of the same hashed logical container.
|
||||
Firmware without the record retains the conservative <code>0x98000</code> default. Before writing <code>APRV</code>, an
|
||||
internal-store app validates the staged-address bound; an external SD/QSPI app validates the full detools
|
||||
geometry against the application workspace. The bootloader independently parses and validates the same
|
||||
geometry before its first application write. Expanded auto-sized packages require a bootloader
|
||||
@@ -3280,10 +3295,11 @@ retains its <code>.part</code> file; it does not erase the unrelated manual-inst
|
||||
It holds either an ordinary app delta or the exact 41,330-byte v3 container, never both. The boot package
|
||||
bottom-aligns at <code>0xE2000</code>; a hash-valid live <code>EndF</code> must prove the complete running image ends at or below
|
||||
that address before the first erase. OTAFIX reads each source window before erasing and compacts the
|
||||
payload forward in the same eleven pages to raw <code>0xE2000..0xEC000</code>; no separate scratch bank or special
|
||||
application linker exists. GPREGRET <code>0x6B</code> plus GPREGRET2 <code>0xED</code> selects boot update, while ordinary app
|
||||
apply uses GPREGRET <code>0x6A</code> plus the same storage source. Exact installed/candidate capability flags are
|
||||
<code>0x0A</code> (<code>STAGE_CEILING|BOOT_UPDATE</code>). Ordinary deltas remain dynamically sized, may start below
|
||||
payload forward in the same eleven pages to raw <code>0xE2000..0xEC000</code>; no separate flash scratch bank exists.
|
||||
The qualified application linker reserves a 64 KiB SRAM arena only for hybrid application deltas; the
|
||||
bootloader package remains wholly in flash. GPREGRET <code>0x6B</code> plus GPREGRET2 <code>0xED</code> selects boot update,
|
||||
while ordinary app apply uses GPREGRET <code>0x6A</code> plus the same storage source. Exact installed/candidate
|
||||
capability flags are <code>0x0A</code> (<code>STAGE_CEILING|BOOT_UPDATE</code>). Ordinary deltas remain dynamically sized, may start below
|
||||
<code>0xE2000</code>, and reconstruct only below the normal <code>0xED000</code> app ceiling. The same signature, explicit
|
||||
confirmation, exact identity, vector, CRC, and single-marker rules as the XIAO path apply. Bootloader FULL
|
||||
admission is isolated from ordinary application FULL policy, and privileged partials are never resumed
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user