diff --git a/build.sh b/build.sh index 8f18d6a..1949834 100644 --- a/build.sh +++ b/build.sh @@ -204,7 +204,7 @@ print(str(size // 1048576) + "MB") ) # MCUboot/sysbuild boards: only the merged (MCUboot + signed app) # image is bootable on a bare/existing chip at 0x0. The signed app - # alone requires MCUboot already present and must land at 0x20000 — + # alone requires MCUboot already present and must land at 0x10000 — # publishing it standalone as a "plain .bin" bricks boards when # flashed the same way as classic-ESP32's self-contained zephyr.bin # (see GH #42). Don't ship it. @@ -212,7 +212,7 @@ print(str(size // 1048576) + "MB") --output firmware/"$board_clean_for_path"-companion-"$COMMIT_HASH"-merged.bin \ --flash-mode dio --flash-freq 40m --flash-size "$FLASH_SIZE" \ 0x00000 build/mcuboot/zephyr/zephyr.bin \ - 0x20000 build/zephcore/zephyr/zephyr.signed.bin + 0x10000 build/zephcore/zephyr/zephyr.signed.bin fi if [[ $2 == "repeaters" ]]; then @@ -256,7 +256,7 @@ print(str(size // 1048576) + "MB") --output firmware/"$board_clean_for_path"-repeater-"$COMMIT_HASH"-merged.bin \ --flash-mode dio --flash-freq 40m --flash-size "$FLASH_SIZE" \ 0x00000 build/mcuboot/zephyr/zephyr.bin \ - 0x20000 build/zephcore/zephyr/zephyr.signed.bin + 0x10000 build/zephcore/zephyr/zephyr.signed.bin # Signed app image for WiFi OTA: uploaded to MCUboot slot1 via the # repeater's /update page. NOT bootable standalone — never flash this diff --git a/zephcore/CMakeLists.txt b/zephcore/CMakeLists.txt index 300f82b..3afc8dd 100644 --- a/zephcore/CMakeLists.txt +++ b/zephcore/CMakeLists.txt @@ -405,6 +405,27 @@ if(ZEPHCORE_BOARD_OVERLAY AND EXISTS ${ZEPHCORE_BOARD_OVERLAY}) endif() endif() +# Flash partition layout lives in a separate boards/<...>//partitions.overlay +# so the SAME file can be fed to the MCUboot image too (see sysbuild/CMakeLists.txt). +# The app and MCUboot MUST share one flash map — otherwise MCUboot stages/looks for +# the OTA image at a different address than the app writes it to, and OTA silently +# reverts on reboot. Keeping it in its own file is what makes that sharing possible. +set(ZEPHCORE_BOARD_PARTITIONS "") +file(GLOB_RECURSE BOARD_PARTITIONS_CANDIDATES "${CMAKE_CURRENT_SOURCE_DIR}/boards/*/${BOARD_BASE}/partitions.overlay") +if(BOARD_PARTITIONS_CANDIDATES) + list(GET BOARD_PARTITIONS_CANDIDATES 0 ZEPHCORE_BOARD_PARTITIONS) +endif() +if(NOT ZEPHCORE_BOARD_PARTITIONS AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD_BASE}/partitions.overlay") + set(ZEPHCORE_BOARD_PARTITIONS "${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD_BASE}/partitions.overlay") +endif() +if(ZEPHCORE_BOARD_PARTITIONS AND EXISTS ${ZEPHCORE_BOARD_PARTITIONS}) + if(EXTRA_DTC_OVERLAY_FILE) + set(EXTRA_DTC_OVERLAY_FILE "${EXTRA_DTC_OVERLAY_FILE};${ZEPHCORE_BOARD_PARTITIONS}" CACHE STRING "" FORCE) + else() + set(EXTRA_DTC_OVERLAY_FILE "${ZEPHCORE_BOARD_PARTITIONS}" CACHE STRING "" FORCE) + endif() +endif() + # Debug: Show what configs are being used message(STATUS "ZephCore config hierarchy:") diff --git a/zephcore/boards/esp32/heltec_wifi_lora32_v3/board.overlay b/zephcore/boards/esp32/heltec_wifi_lora32_v3/board.overlay index 8aea505..7436beb 100644 --- a/zephcore/boards/esp32/heltec_wifi_lora32_v3/board.overlay +++ b/zephcore/boards/esp32/heltec_wifi_lora32_v3/board.overlay @@ -127,50 +127,9 @@ }; /* - * Flash partitions — reclaim unused space from 8MB layout. - * Delete lpcore slots, storage, scratch, and coredump partitions. - * Repurpose 0x7A0000 - 0x800000 (384KB) for LittleFS. + * Flash partitions live in partitions.overlay (this dir) so the identical map is + * fed to both the app and the MCUboot image — see that file and sysbuild/CMakeLists.txt. */ -/delete-node/ &slot0_lpcore_partition; -/delete-node/ &slot1_lpcore_partition; -/delete-node/ &storage_partition; -/delete-node/ &scratch_partition; -/delete-node/ &coredump_partition; -/delete-node/ &slot0_partition; -/delete-node/ &slot1_partition; - -/ { - chosen { - zephyr,settings-partition = &storage_partition; - }; -}; - -&flash0 { - partitions { - /* App slots — both trimmed 8KB so slot0 == slot1 (16KB total freed - * for the NVS partition below), keeping MCUboot swap-mode compatible, - * not just overwrite-only. slot0 start (0x20000) unchanged. */ - slot0_partition: partition@20000 { - label = "image-0"; - reg = <0x20000 0x3BE000>; - }; - slot1_partition: partition@3de000 { - label = "image-1"; - reg = <0x3DE000 0x3BE000>; - }; - /* BLE bond store — 16KB NVS, isolated from /lfs (see esp32_common.conf). - * Carved from the end of slot1 so lfs stays byte-identical. */ - storage_partition: partition@79c000 { - label = "storage"; - reg = <0x79C000 0x4000>; - }; - /* LittleFS 384KB for DataStore (identity, prefs, contacts) */ - lfs_partition: partition@7a0000 { - label = "lfs"; - reg = <0x7A0000 0x60000>; - }; - }; -}; /* LittleFS auto-mount — standard /lfs mount point */ #include "../../common/filesystem.dtsi" diff --git a/zephcore/boards/esp32/heltec_wifi_lora32_v3/partitions.overlay b/zephcore/boards/esp32/heltec_wifi_lora32_v3/partitions.overlay new file mode 100644 index 0000000..7ca3a47 --- /dev/null +++ b/zephcore/boards/esp32/heltec_wifi_lora32_v3/partitions.overlay @@ -0,0 +1,58 @@ +/* + * Flash partition layout — SHARED by the app image and MCUboot. + * + * This file is fed to BOTH images (app via EXTRA_DTC_OVERLAY_FILE, MCUboot via + * mcuboot_EXTRA_DTC_OVERLAY_FILE in sysbuild/CMakeLists.txt) so their flash maps + * are identical — otherwise MCUboot looks for the OTA image at a different + * address than the app writes it to and OTA silently reverts. Keep it free of + * app-only nodes (drivers, chosen mounts) so MCUboot can consume it too. + * + * slot0 starts at 0x10000 (right after the 64KB MCUboot region), matching the + * Arduino/ESP-IDF app offset so Mesh America's app-only "flash-update" works. + * sys_partition (0x10000, virtual-eFuse scratch — unused, virtual eFuse off) is + * reclaimed. Each slot is grown 0x8000 vs the old 0x20000 layout so slot0 == slot1 + * and slot1 ends exactly on the unchanged storage/lfs offsets — the reflash keeps + * identity/prefs/contacts/BLE-bonds byte-identical. + * + * 8MB layout: MCUboot 0x0..0x10000, slot0/slot1 0x3C6000 each, storage+lfs at top. + */ +/delete-node/ &sys_partition; +/delete-node/ &slot0_lpcore_partition; +/delete-node/ &slot1_lpcore_partition; +/delete-node/ &storage_partition; +/delete-node/ &scratch_partition; +/delete-node/ &coredump_partition; +/delete-node/ &slot0_partition; +/delete-node/ &slot1_partition; + +/ { + chosen { + zephyr,settings-partition = &storage_partition; + }; +}; + +&flash0 { + partitions { + /* App slots — equal size (swap-mode compatible), slot0 at 0x10000. */ + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x10000 0x3C6000>; + }; + slot1_partition: partition@3d6000 { + label = "image-1"; + reg = <0x3D6000 0x3C6000>; + }; + /* BLE bond store — 16KB NVS, isolated from /lfs (see esp32_common.conf). + * Offset unchanged so existing bonds survive the reflash. */ + storage_partition: partition@79c000 { + label = "storage"; + reg = <0x79C000 0x4000>; + }; + /* LittleFS 384KB for DataStore (identity, prefs, contacts). + * Offset unchanged so existing identity/prefs/contacts survive. */ + lfs_partition: partition@7a0000 { + label = "lfs"; + reg = <0x7A0000 0x60000>; + }; + }; +}; diff --git a/zephcore/boards/esp32/heltec_wifi_lora32_v4/board.overlay b/zephcore/boards/esp32/heltec_wifi_lora32_v4/board.overlay index 7ed82d9..f919424 100644 --- a/zephcore/boards/esp32/heltec_wifi_lora32_v4/board.overlay +++ b/zephcore/boards/esp32/heltec_wifi_lora32_v4/board.overlay @@ -83,50 +83,10 @@ }; /* - * Flash partitions — repartition 16 MB layout for ZephCore. - * Delete lpcore slots, storage, scratch, and coredump to reclaim space. - * Place LittleFS at 0xFA0000 - 0x1000000 (384 KB). + * Flash partitions live in partitions.overlay (this dir) so the identical map + * is fed to both the app and the MCUboot image — see that file and + * sysbuild/CMakeLists.txt. */ -/delete-node/ &slot0_lpcore_partition; -/delete-node/ &slot1_lpcore_partition; -/delete-node/ &storage_partition; -/delete-node/ &scratch_partition; -/delete-node/ &coredump_partition; -/delete-node/ &slot0_partition; -/delete-node/ &slot1_partition; - -/ { - chosen { - zephyr,settings-partition = &storage_partition; - }; -}; - -&flash0 { - partitions { - /* App slots — both trimmed 8KB so slot0 == slot1 (16KB total freed - * for the NVS partition below), keeping MCUboot swap-mode compatible, - * not just overwrite-only. slot0 start (0x20000) unchanged. */ - slot0_partition: partition@20000 { - label = "image-0"; - reg = <0x20000 0x7BE000>; - }; - slot1_partition: partition@7de000 { - label = "image-1"; - reg = <0x7DE000 0x7BE000>; - }; - /* BLE bond store — 16KB NVS, isolated from /lfs (see esp32_common.conf). - * Carved from the end of slot1 so lfs stays byte-identical. */ - storage_partition: partition@f9c000 { - label = "storage"; - reg = <0xF9C000 0x4000>; - }; - /* LittleFS 384 KB for DataStore (identity, prefs, contacts) */ - lfs_partition: partition@fa0000 { - label = "lfs"; - reg = <0xFA0000 0x60000>; - }; - }; -}; /* LittleFS auto-mount — standard /lfs mount point */ #include "../../common/filesystem.dtsi" diff --git a/zephcore/boards/esp32/heltec_wifi_lora32_v4/partitions.overlay b/zephcore/boards/esp32/heltec_wifi_lora32_v4/partitions.overlay new file mode 100644 index 0000000..5a300ab --- /dev/null +++ b/zephcore/boards/esp32/heltec_wifi_lora32_v4/partitions.overlay @@ -0,0 +1,53 @@ +/* + * Flash partition layout — SHARED by the app image and MCUboot. + * + * Fed to BOTH images (app via EXTRA_DTC_OVERLAY_FILE, MCUboot via + * mcuboot_EXTRA_DTC_OVERLAY_FILE in sysbuild/CMakeLists.txt) so their flash maps + * are identical — otherwise MCUboot stages/looks for the OTA image at a different + * address than the app writes it to and OTA silently reverts on reboot. + * + * slot0 starts at 0x10000 (right after the 64KB MCUboot region), matching the + * Arduino/ESP-IDF app offset (Mesh America "flash-update" compatible). sys_partition + * is reclaimed. Slots are equal size and slot1 ends exactly on the unchanged + * storage/lfs offsets, so a -merged reflash keeps identity/prefs/contacts/BLE-bonds. + * + * 16MB layout. + */ +/delete-node/ &sys_partition; +/delete-node/ &slot0_lpcore_partition; +/delete-node/ &slot1_lpcore_partition; +/delete-node/ &storage_partition; +/delete-node/ &scratch_partition; +/delete-node/ &coredump_partition; +/delete-node/ &slot0_partition; +/delete-node/ &slot1_partition; + +/ { + chosen { + zephyr,settings-partition = &storage_partition; + }; +}; + +&flash0 { + partitions { + /* App slots — equal size (swap-mode compatible), slot0 at 0x10000. */ + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x10000 0x7C6000>; + }; + slot1_partition: partition@7D6000 { + label = "image-1"; + reg = <0x7D6000 0x7C6000>; + }; + /* BLE bond NVS — offset unchanged so bonds survive the reflash. */ + storage_partition: partition@F9C000 { + label = "storage"; + reg = <0xF9C000 0x4000>; + }; + /* LittleFS (identity/prefs/contacts) — offset unchanged. */ + lfs_partition: partition@FA0000 { + label = "lfs"; + reg = <0xFA0000 0x60000>; + }; + }; +}; diff --git a/zephcore/boards/esp32/heltec_wifi_lora32_v43/board.overlay b/zephcore/boards/esp32/heltec_wifi_lora32_v43/board.overlay index 71fcebe..c2bed37 100644 --- a/zephcore/boards/esp32/heltec_wifi_lora32_v43/board.overlay +++ b/zephcore/boards/esp32/heltec_wifi_lora32_v43/board.overlay @@ -83,50 +83,10 @@ }; /* - * Flash partitions — repartition 16 MB layout for ZephCore. - * Delete lpcore slots, storage, scratch, and coredump to reclaim space. - * Place LittleFS at 0xFA0000 - 0x1000000 (384 KB). + * Flash partitions live in partitions.overlay (this dir) so the identical map + * is fed to both the app and the MCUboot image — see that file and + * sysbuild/CMakeLists.txt. */ -/delete-node/ &slot0_lpcore_partition; -/delete-node/ &slot1_lpcore_partition; -/delete-node/ &storage_partition; -/delete-node/ &scratch_partition; -/delete-node/ &coredump_partition; -/delete-node/ &slot0_partition; -/delete-node/ &slot1_partition; - -/ { - chosen { - zephyr,settings-partition = &storage_partition; - }; -}; - -&flash0 { - partitions { - /* App slots — both trimmed 8KB so slot0 == slot1 (16KB total freed - * for the NVS partition below), keeping MCUboot swap-mode compatible, - * not just overwrite-only. slot0 start (0x20000) unchanged. */ - slot0_partition: partition@20000 { - label = "image-0"; - reg = <0x20000 0x7BE000>; - }; - slot1_partition: partition@7de000 { - label = "image-1"; - reg = <0x7DE000 0x7BE000>; - }; - /* BLE bond store — 16KB NVS, isolated from /lfs (see esp32_common.conf). - * Carved from the end of slot1 so lfs stays byte-identical. */ - storage_partition: partition@f9c000 { - label = "storage"; - reg = <0xF9C000 0x4000>; - }; - /* LittleFS 384 KB for DataStore (identity, prefs, contacts) */ - lfs_partition: partition@fa0000 { - label = "lfs"; - reg = <0xFA0000 0x60000>; - }; - }; -}; /* LittleFS auto-mount — standard /lfs mount point */ #include "../../common/filesystem.dtsi" diff --git a/zephcore/boards/esp32/heltec_wifi_lora32_v43/partitions.overlay b/zephcore/boards/esp32/heltec_wifi_lora32_v43/partitions.overlay new file mode 100644 index 0000000..5a300ab --- /dev/null +++ b/zephcore/boards/esp32/heltec_wifi_lora32_v43/partitions.overlay @@ -0,0 +1,53 @@ +/* + * Flash partition layout — SHARED by the app image and MCUboot. + * + * Fed to BOTH images (app via EXTRA_DTC_OVERLAY_FILE, MCUboot via + * mcuboot_EXTRA_DTC_OVERLAY_FILE in sysbuild/CMakeLists.txt) so their flash maps + * are identical — otherwise MCUboot stages/looks for the OTA image at a different + * address than the app writes it to and OTA silently reverts on reboot. + * + * slot0 starts at 0x10000 (right after the 64KB MCUboot region), matching the + * Arduino/ESP-IDF app offset (Mesh America "flash-update" compatible). sys_partition + * is reclaimed. Slots are equal size and slot1 ends exactly on the unchanged + * storage/lfs offsets, so a -merged reflash keeps identity/prefs/contacts/BLE-bonds. + * + * 16MB layout. + */ +/delete-node/ &sys_partition; +/delete-node/ &slot0_lpcore_partition; +/delete-node/ &slot1_lpcore_partition; +/delete-node/ &storage_partition; +/delete-node/ &scratch_partition; +/delete-node/ &coredump_partition; +/delete-node/ &slot0_partition; +/delete-node/ &slot1_partition; + +/ { + chosen { + zephyr,settings-partition = &storage_partition; + }; +}; + +&flash0 { + partitions { + /* App slots — equal size (swap-mode compatible), slot0 at 0x10000. */ + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x10000 0x7C6000>; + }; + slot1_partition: partition@7D6000 { + label = "image-1"; + reg = <0x7D6000 0x7C6000>; + }; + /* BLE bond NVS — offset unchanged so bonds survive the reflash. */ + storage_partition: partition@F9C000 { + label = "storage"; + reg = <0xF9C000 0x4000>; + }; + /* LittleFS (identity/prefs/contacts) — offset unchanged. */ + lfs_partition: partition@FA0000 { + label = "lfs"; + reg = <0xFA0000 0x60000>; + }; + }; +}; diff --git a/zephcore/boards/esp32/heltec_wireless_tracker/board.overlay b/zephcore/boards/esp32/heltec_wireless_tracker/board.overlay index 0a6b0bf..8fef42c 100644 --- a/zephcore/boards/esp32/heltec_wireless_tracker/board.overlay +++ b/zephcore/boards/esp32/heltec_wireless_tracker/board.overlay @@ -224,51 +224,10 @@ }; /* - * Flash partitions — reclaim unused space from 8MB layout (matches the - * Heltec V3, the same ESP32-S3-FN8 platform). Delete lpcore slots, storage, - * scratch, and coredump partitions. Repurpose 0x7A0000 - 0x800000 (384KB) - * for LittleFS. + * Flash partitions live in partitions.overlay (this dir) so the identical map + * is fed to both the app and the MCUboot image — see that file and + * sysbuild/CMakeLists.txt. */ -/delete-node/ &slot0_lpcore_partition; -/delete-node/ &slot1_lpcore_partition; -/delete-node/ &storage_partition; -/delete-node/ &scratch_partition; -/delete-node/ &coredump_partition; -/delete-node/ &slot0_partition; -/delete-node/ &slot1_partition; - -/ { - chosen { - zephyr,settings-partition = &storage_partition; - }; -}; - -&flash0 { - partitions { - /* App slots — both trimmed 8KB so slot0 == slot1 (16KB total freed - * for the NVS partition below), keeping MCUboot swap-mode compatible, - * not just overwrite-only. slot0 start (0x20000) unchanged. */ - slot0_partition: partition@20000 { - label = "image-0"; - reg = <0x20000 0x3BE000>; - }; - slot1_partition: partition@3de000 { - label = "image-1"; - reg = <0x3DE000 0x3BE000>; - }; - /* BLE bond store — 16KB NVS, isolated from /lfs (see esp32_common.conf). - * Carved from the end of slot1 so lfs stays byte-identical. */ - storage_partition: partition@79c000 { - label = "storage"; - reg = <0x79C000 0x4000>; - }; - /* LittleFS 384KB for DataStore (identity, prefs, contacts) */ - lfs_partition: partition@7a0000 { - label = "lfs"; - reg = <0x7A0000 0x60000>; - }; - }; -}; /* LittleFS auto-mount — standard /lfs mount point */ #include "../../common/filesystem.dtsi" diff --git a/zephcore/boards/esp32/heltec_wireless_tracker/partitions.overlay b/zephcore/boards/esp32/heltec_wireless_tracker/partitions.overlay new file mode 100644 index 0000000..7af2f00 --- /dev/null +++ b/zephcore/boards/esp32/heltec_wireless_tracker/partitions.overlay @@ -0,0 +1,53 @@ +/* + * Flash partition layout — SHARED by the app image and MCUboot. + * + * Fed to BOTH images (app via EXTRA_DTC_OVERLAY_FILE, MCUboot via + * mcuboot_EXTRA_DTC_OVERLAY_FILE in sysbuild/CMakeLists.txt) so their flash maps + * are identical — otherwise MCUboot stages/looks for the OTA image at a different + * address than the app writes it to and OTA silently reverts on reboot. + * + * slot0 starts at 0x10000 (right after the 64KB MCUboot region), matching the + * Arduino/ESP-IDF app offset (Mesh America "flash-update" compatible). sys_partition + * is reclaimed. Slots are equal size and slot1 ends exactly on the unchanged + * storage/lfs offsets, so a -merged reflash keeps identity/prefs/contacts/BLE-bonds. + * + * 8MB layout. + */ +/delete-node/ &sys_partition; +/delete-node/ &slot0_lpcore_partition; +/delete-node/ &slot1_lpcore_partition; +/delete-node/ &storage_partition; +/delete-node/ &scratch_partition; +/delete-node/ &coredump_partition; +/delete-node/ &slot0_partition; +/delete-node/ &slot1_partition; + +/ { + chosen { + zephyr,settings-partition = &storage_partition; + }; +}; + +&flash0 { + partitions { + /* App slots — equal size (swap-mode compatible), slot0 at 0x10000. */ + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x10000 0x3C6000>; + }; + slot1_partition: partition@3D6000 { + label = "image-1"; + reg = <0x3D6000 0x3C6000>; + }; + /* BLE bond NVS — offset unchanged so bonds survive the reflash. */ + storage_partition: partition@79C000 { + label = "storage"; + reg = <0x79C000 0x4000>; + }; + /* LittleFS (identity/prefs/contacts) — offset unchanged. */ + lfs_partition: partition@7A0000 { + label = "lfs"; + reg = <0x7A0000 0x60000>; + }; + }; +}; diff --git a/zephcore/boards/esp32/heltec_wireless_tracker_v2/board.overlay b/zephcore/boards/esp32/heltec_wireless_tracker_v2/board.overlay index 9039034..251487e 100644 --- a/zephcore/boards/esp32/heltec_wireless_tracker_v2/board.overlay +++ b/zephcore/boards/esp32/heltec_wireless_tracker_v2/board.overlay @@ -52,44 +52,10 @@ }; /* - * Flash partitions — ZephCore 8 MB layout matching the ESP32-S3-FN8 tracker - * class. Delete unused lpcore slots, storage, scratch, and coredump partitions. - * Place LittleFS at 0x7A0000 - 0x800000 (384 KB). + * Flash partitions live in partitions.overlay (this dir) so the identical map + * is fed to both the app and the MCUboot image — see that file and + * sysbuild/CMakeLists.txt. */ -/delete-node/ &slot0_lpcore_partition; -/delete-node/ &slot1_lpcore_partition; -/delete-node/ &storage_partition; -/delete-node/ &scratch_partition; -/delete-node/ &coredump_partition; -/delete-node/ &slot0_partition; -/delete-node/ &slot1_partition; - -/ { - chosen { - zephyr,settings-partition = &storage_partition; - }; -}; - -&flash0 { - partitions { - slot0_partition: partition@20000 { - label = "image-0"; - reg = <0x20000 0x3BE000>; - }; - slot1_partition: partition@3de000 { - label = "image-1"; - reg = <0x3DE000 0x3BE000>; - }; - storage_partition: partition@79c000 { - label = "storage"; - reg = <0x79C000 0x4000>; - }; - lfs_partition: partition@7a0000 { - label = "lfs"; - reg = <0x7A0000 0x60000>; - }; - }; -}; /* LittleFS auto-mount — standard /lfs mount point */ #include "../../common/filesystem.dtsi" diff --git a/zephcore/boards/esp32/heltec_wireless_tracker_v2/partitions.overlay b/zephcore/boards/esp32/heltec_wireless_tracker_v2/partitions.overlay new file mode 100644 index 0000000..7af2f00 --- /dev/null +++ b/zephcore/boards/esp32/heltec_wireless_tracker_v2/partitions.overlay @@ -0,0 +1,53 @@ +/* + * Flash partition layout — SHARED by the app image and MCUboot. + * + * Fed to BOTH images (app via EXTRA_DTC_OVERLAY_FILE, MCUboot via + * mcuboot_EXTRA_DTC_OVERLAY_FILE in sysbuild/CMakeLists.txt) so their flash maps + * are identical — otherwise MCUboot stages/looks for the OTA image at a different + * address than the app writes it to and OTA silently reverts on reboot. + * + * slot0 starts at 0x10000 (right after the 64KB MCUboot region), matching the + * Arduino/ESP-IDF app offset (Mesh America "flash-update" compatible). sys_partition + * is reclaimed. Slots are equal size and slot1 ends exactly on the unchanged + * storage/lfs offsets, so a -merged reflash keeps identity/prefs/contacts/BLE-bonds. + * + * 8MB layout. + */ +/delete-node/ &sys_partition; +/delete-node/ &slot0_lpcore_partition; +/delete-node/ &slot1_lpcore_partition; +/delete-node/ &storage_partition; +/delete-node/ &scratch_partition; +/delete-node/ &coredump_partition; +/delete-node/ &slot0_partition; +/delete-node/ &slot1_partition; + +/ { + chosen { + zephyr,settings-partition = &storage_partition; + }; +}; + +&flash0 { + partitions { + /* App slots — equal size (swap-mode compatible), slot0 at 0x10000. */ + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x10000 0x3C6000>; + }; + slot1_partition: partition@3D6000 { + label = "image-1"; + reg = <0x3D6000 0x3C6000>; + }; + /* BLE bond NVS — offset unchanged so bonds survive the reflash. */ + storage_partition: partition@79C000 { + label = "storage"; + reg = <0x79C000 0x4000>; + }; + /* LittleFS (identity/prefs/contacts) — offset unchanged. */ + lfs_partition: partition@7A0000 { + label = "lfs"; + reg = <0x7A0000 0x60000>; + }; + }; +}; diff --git a/zephcore/boards/esp32/lilygo_tlora_c6/board.overlay b/zephcore/boards/esp32/lilygo_tlora_c6/board.overlay index 596390a..20275dc 100644 --- a/zephcore/boards/esp32/lilygo_tlora_c6/board.overlay +++ b/zephcore/boards/esp32/lilygo_tlora_c6/board.overlay @@ -58,35 +58,10 @@ }; /* - * Flash partitions — repartition default ESP32 layout. - * Default storage_partition is 192KB at 0x3B0000. - * - * 0x3B0000 - 0x3E0000 (192KB) LittleFS (identity, contacts, channels, BLE bonds) + * Flash partitions live in partitions.overlay (this dir) so the identical map + * is fed to both the app and the MCUboot image — see that file and + * sysbuild/CMakeLists.txt. */ -/delete-node/ &storage_partition; -/delete-node/ &scratch_partition; - -/ { - chosen { - zephyr,settings-partition = &storage_partition; - }; -}; - -&flash0 { - partitions { - /* LittleFS 192KB for DataStore (identity, prefs, contacts) */ - lfs_partition: partition@3b0000 { - label = "lfs"; - reg = <0x3B0000 0x30000>; - }; - /* BLE bond store — 16KB NVS, isolated from /lfs (see esp32_common.conf). - * Placed in the unused scratch region just above lfs (lfs unchanged). */ - storage_partition: partition@3e0000 { - label = "storage"; - reg = <0x3E0000 0x4000>; - }; - }; -}; /* LittleFS auto-mount — standard /lfs mount point */ #include "../../common/filesystem.dtsi" diff --git a/zephcore/boards/esp32/lilygo_tlora_c6/partitions.overlay b/zephcore/boards/esp32/lilygo_tlora_c6/partitions.overlay new file mode 100644 index 0000000..b3f2b7c --- /dev/null +++ b/zephcore/boards/esp32/lilygo_tlora_c6/partitions.overlay @@ -0,0 +1,51 @@ +/* + * Flash partition layout — SHARED by the app image and MCUboot. + * + * Fed to BOTH images (app via EXTRA_DTC_OVERLAY_FILE, MCUboot via + * mcuboot_EXTRA_DTC_OVERLAY_FILE in sysbuild/CMakeLists.txt) so their flash maps + * are identical — otherwise MCUboot stages/looks for the OTA image at a different + * address than the app writes it to and OTA silently reverts on reboot. + * + * slot0 starts at 0x10000 (right after the 64KB MCUboot region), matching the + * Arduino/ESP-IDF app offset (Mesh America "flash-update" compatible). sys_partition + * is reclaimed. Slots are equal size; the reflash keeps identity/prefs/contacts. + * + * 4MB default layout: lpcore kept @0x3A0000, so slots fill 0x10000..0x3A0000; + * lfs (192KB) @0x3B0000 and storage @0x3E0000 unchanged. + */ +/delete-node/ &sys_partition; +/delete-node/ &slot0_partition; +/delete-node/ &slot1_partition; +/delete-node/ &storage_partition; +/delete-node/ &scratch_partition; + +/ { + chosen { + zephyr,settings-partition = &storage_partition; + }; +}; + +&flash0 { + partitions { + /* App slots — equal size (swap-mode compatible), slot0 at 0x10000, + * slots fill up to the kept LP-core slots at 0x3A0000. */ + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x10000 0x1C8000>; + }; + slot1_partition: partition@1d8000 { + label = "image-1"; + reg = <0x1D8000 0x1C8000>; + }; + /* LittleFS 192KB (identity/prefs/contacts) — offset unchanged. */ + lfs_partition: partition@3b0000 { + label = "lfs"; + reg = <0x3B0000 0x30000>; + }; + /* BLE bond NVS — offset unchanged so bonds survive the reflash. */ + storage_partition: partition@3e0000 { + label = "storage"; + reg = <0x3E0000 0x4000>; + }; + }; +}; diff --git a/zephcore/boards/esp32/station_g2/board.overlay b/zephcore/boards/esp32/station_g2/board.overlay index 1d2cb2f..1a506a1 100644 --- a/zephcore/boards/esp32/station_g2/board.overlay +++ b/zephcore/boards/esp32/station_g2/board.overlay @@ -85,58 +85,10 @@ }; /* - * Flash partitions — repartition default ESP32-S3 16 MB layout. - * Delete unused partitions (lpcore, scratch, coredump) to reclaim space. - * - * 0x7E0000 - 0xF9C000 (~7.7MB) OTA image-1 (slot1, trimmed 16KB) - * 0xF9C000 - 0xFA0000 (16KB) NVS BLE bonds (storage_partition) - * 0xFA0000 - 0x1000000 (384KB) LittleFS (identity, contacts, channels) - * - * Bonds live in the NVS storage_partition (isolated) instead of /lfs, so - * settings-write churn can't corrupt identity/prefs/contacts. The NVS - * region is carved from the end of slot1 (unused in the default simple-boot - * build) so lfs_partition stays byte-identical — existing user data survives. + * Flash partitions live in partitions.overlay (this dir) so the identical map + * is fed to both the app and the MCUboot image — see that file and + * sysbuild/CMakeLists.txt. */ -/delete-node/ &slot0_lpcore_partition; -/delete-node/ &slot1_lpcore_partition; -/delete-node/ &storage_partition; -/delete-node/ &scratch_partition; -/delete-node/ &coredump_partition; -/delete-node/ &slot0_partition; -/delete-node/ &slot1_partition; - -/ { - chosen { - zephyr,settings-partition = &storage_partition; - }; -}; - -&flash0 { - partitions { - /* App slots — both trimmed 8KB so slot0 == slot1 (16KB total freed - * for the NVS partition below), keeping MCUboot swap-mode compatible, - * not just overwrite-only. slot0 start (0x20000) unchanged. */ - slot0_partition: partition@20000 { - label = "image-0"; - reg = <0x20000 0x7BE000>; - }; - slot1_partition: partition@7de000 { - label = "image-1"; - reg = <0x7DE000 0x7BE000>; - }; - /* BLE bond store — 16KB NVS, isolated from /lfs. label "storage" - * so the existing formatter/factory-reset paths erase it too. */ - storage_partition: partition@f9c000 { - label = "storage"; - reg = <0xF9C000 0x4000>; - }; - /* LittleFS 384KB for DataStore (identity, prefs, contacts) */ - lfs_partition: partition@fa0000 { - label = "lfs"; - reg = <0xFA0000 0x60000>; - }; - }; -}; /* LittleFS auto-mount — standard /lfs mount point */ #include "../../common/filesystem.dtsi" diff --git a/zephcore/boards/esp32/station_g2/partitions.overlay b/zephcore/boards/esp32/station_g2/partitions.overlay new file mode 100644 index 0000000..5a300ab --- /dev/null +++ b/zephcore/boards/esp32/station_g2/partitions.overlay @@ -0,0 +1,53 @@ +/* + * Flash partition layout — SHARED by the app image and MCUboot. + * + * Fed to BOTH images (app via EXTRA_DTC_OVERLAY_FILE, MCUboot via + * mcuboot_EXTRA_DTC_OVERLAY_FILE in sysbuild/CMakeLists.txt) so their flash maps + * are identical — otherwise MCUboot stages/looks for the OTA image at a different + * address than the app writes it to and OTA silently reverts on reboot. + * + * slot0 starts at 0x10000 (right after the 64KB MCUboot region), matching the + * Arduino/ESP-IDF app offset (Mesh America "flash-update" compatible). sys_partition + * is reclaimed. Slots are equal size and slot1 ends exactly on the unchanged + * storage/lfs offsets, so a -merged reflash keeps identity/prefs/contacts/BLE-bonds. + * + * 16MB layout. + */ +/delete-node/ &sys_partition; +/delete-node/ &slot0_lpcore_partition; +/delete-node/ &slot1_lpcore_partition; +/delete-node/ &storage_partition; +/delete-node/ &scratch_partition; +/delete-node/ &coredump_partition; +/delete-node/ &slot0_partition; +/delete-node/ &slot1_partition; + +/ { + chosen { + zephyr,settings-partition = &storage_partition; + }; +}; + +&flash0 { + partitions { + /* App slots — equal size (swap-mode compatible), slot0 at 0x10000. */ + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x10000 0x7C6000>; + }; + slot1_partition: partition@7D6000 { + label = "image-1"; + reg = <0x7D6000 0x7C6000>; + }; + /* BLE bond NVS — offset unchanged so bonds survive the reflash. */ + storage_partition: partition@F9C000 { + label = "storage"; + reg = <0xF9C000 0x4000>; + }; + /* LittleFS (identity/prefs/contacts) — offset unchanged. */ + lfs_partition: partition@FA0000 { + label = "lfs"; + reg = <0xFA0000 0x60000>; + }; + }; +}; diff --git a/zephcore/boards/esp32/xiao_esp32c3/board.overlay b/zephcore/boards/esp32/xiao_esp32c3/board.overlay index cc5b4f3..a787b62 100644 --- a/zephcore/boards/esp32/xiao_esp32c3/board.overlay +++ b/zephcore/boards/esp32/xiao_esp32c3/board.overlay @@ -54,35 +54,10 @@ }; /* - * Flash partitions — repartition default ESP32 layout. - * Default storage_partition is 192KB at 0x3B0000. - * - * 0x3B0000 - 0x3E0000 (192KB) LittleFS (identity, contacts, channels, BLE bonds) + * Flash partitions live in partitions.overlay (this dir) so the identical map + * is fed to both the app and the MCUboot image — see that file and + * sysbuild/CMakeLists.txt. */ -/delete-node/ &storage_partition; -/delete-node/ &scratch_partition; - -/ { - chosen { - zephyr,settings-partition = &storage_partition; - }; -}; - -&flash0 { - partitions { - /* LittleFS 192KB for DataStore (identity, prefs, contacts) */ - lfs_partition: partition@3b0000 { - label = "lfs"; - reg = <0x3B0000 0x30000>; - }; - /* BLE bond store — 16KB NVS, isolated from /lfs (see esp32_common.conf). - * Placed in the unused scratch region just above lfs (lfs unchanged). */ - storage_partition: partition@3e0000 { - label = "storage"; - reg = <0x3E0000 0x4000>; - }; - }; -}; /* LittleFS auto-mount — standard /lfs mount point */ #include "../../common/filesystem.dtsi" diff --git a/zephcore/boards/esp32/xiao_esp32c3/partitions.overlay b/zephcore/boards/esp32/xiao_esp32c3/partitions.overlay new file mode 100644 index 0000000..b3f2b7c --- /dev/null +++ b/zephcore/boards/esp32/xiao_esp32c3/partitions.overlay @@ -0,0 +1,51 @@ +/* + * Flash partition layout — SHARED by the app image and MCUboot. + * + * Fed to BOTH images (app via EXTRA_DTC_OVERLAY_FILE, MCUboot via + * mcuboot_EXTRA_DTC_OVERLAY_FILE in sysbuild/CMakeLists.txt) so their flash maps + * are identical — otherwise MCUboot stages/looks for the OTA image at a different + * address than the app writes it to and OTA silently reverts on reboot. + * + * slot0 starts at 0x10000 (right after the 64KB MCUboot region), matching the + * Arduino/ESP-IDF app offset (Mesh America "flash-update" compatible). sys_partition + * is reclaimed. Slots are equal size; the reflash keeps identity/prefs/contacts. + * + * 4MB default layout: lpcore kept @0x3A0000, so slots fill 0x10000..0x3A0000; + * lfs (192KB) @0x3B0000 and storage @0x3E0000 unchanged. + */ +/delete-node/ &sys_partition; +/delete-node/ &slot0_partition; +/delete-node/ &slot1_partition; +/delete-node/ &storage_partition; +/delete-node/ &scratch_partition; + +/ { + chosen { + zephyr,settings-partition = &storage_partition; + }; +}; + +&flash0 { + partitions { + /* App slots — equal size (swap-mode compatible), slot0 at 0x10000, + * slots fill up to the kept LP-core slots at 0x3A0000. */ + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x10000 0x1C8000>; + }; + slot1_partition: partition@1d8000 { + label = "image-1"; + reg = <0x1D8000 0x1C8000>; + }; + /* LittleFS 192KB (identity/prefs/contacts) — offset unchanged. */ + lfs_partition: partition@3b0000 { + label = "lfs"; + reg = <0x3B0000 0x30000>; + }; + /* BLE bond NVS — offset unchanged so bonds survive the reflash. */ + storage_partition: partition@3e0000 { + label = "storage"; + reg = <0x3E0000 0x4000>; + }; + }; +}; diff --git a/zephcore/boards/esp32/xiao_esp32c6/board.overlay b/zephcore/boards/esp32/xiao_esp32c6/board.overlay index 6778f40..f906fab 100644 --- a/zephcore/boards/esp32/xiao_esp32c6/board.overlay +++ b/zephcore/boards/esp32/xiao_esp32c6/board.overlay @@ -54,35 +54,10 @@ }; /* - * Flash partitions — repartition default ESP32 layout. - * Default storage_partition is 192KB at 0x3B0000. - * - * 0x3B0000 - 0x3E0000 (192KB) LittleFS (identity, contacts, channels, BLE bonds) + * Flash partitions live in partitions.overlay (this dir) so the identical map + * is fed to both the app and the MCUboot image — see that file and + * sysbuild/CMakeLists.txt. */ -/delete-node/ &storage_partition; -/delete-node/ &scratch_partition; - -/ { - chosen { - zephyr,settings-partition = &storage_partition; - }; -}; - -&flash0 { - partitions { - /* LittleFS 192KB for DataStore (identity, prefs, contacts) */ - lfs_partition: partition@3b0000 { - label = "lfs"; - reg = <0x3B0000 0x30000>; - }; - /* BLE bond store — 16KB NVS, isolated from /lfs (see esp32_common.conf). - * Placed in the unused scratch region just above lfs (lfs unchanged). */ - storage_partition: partition@3e0000 { - label = "storage"; - reg = <0x3E0000 0x4000>; - }; - }; -}; /* LittleFS auto-mount — standard /lfs mount point */ #include "../../common/filesystem.dtsi" diff --git a/zephcore/boards/esp32/xiao_esp32c6/partitions.overlay b/zephcore/boards/esp32/xiao_esp32c6/partitions.overlay new file mode 100644 index 0000000..b3f2b7c --- /dev/null +++ b/zephcore/boards/esp32/xiao_esp32c6/partitions.overlay @@ -0,0 +1,51 @@ +/* + * Flash partition layout — SHARED by the app image and MCUboot. + * + * Fed to BOTH images (app via EXTRA_DTC_OVERLAY_FILE, MCUboot via + * mcuboot_EXTRA_DTC_OVERLAY_FILE in sysbuild/CMakeLists.txt) so their flash maps + * are identical — otherwise MCUboot stages/looks for the OTA image at a different + * address than the app writes it to and OTA silently reverts on reboot. + * + * slot0 starts at 0x10000 (right after the 64KB MCUboot region), matching the + * Arduino/ESP-IDF app offset (Mesh America "flash-update" compatible). sys_partition + * is reclaimed. Slots are equal size; the reflash keeps identity/prefs/contacts. + * + * 4MB default layout: lpcore kept @0x3A0000, so slots fill 0x10000..0x3A0000; + * lfs (192KB) @0x3B0000 and storage @0x3E0000 unchanged. + */ +/delete-node/ &sys_partition; +/delete-node/ &slot0_partition; +/delete-node/ &slot1_partition; +/delete-node/ &storage_partition; +/delete-node/ &scratch_partition; + +/ { + chosen { + zephyr,settings-partition = &storage_partition; + }; +}; + +&flash0 { + partitions { + /* App slots — equal size (swap-mode compatible), slot0 at 0x10000, + * slots fill up to the kept LP-core slots at 0x3A0000. */ + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x10000 0x1C8000>; + }; + slot1_partition: partition@1d8000 { + label = "image-1"; + reg = <0x1D8000 0x1C8000>; + }; + /* LittleFS 192KB (identity/prefs/contacts) — offset unchanged. */ + lfs_partition: partition@3b0000 { + label = "lfs"; + reg = <0x3B0000 0x30000>; + }; + /* BLE bond NVS — offset unchanged so bonds survive the reflash. */ + storage_partition: partition@3e0000 { + label = "storage"; + reg = <0x3E0000 0x4000>; + }; + }; +}; diff --git a/zephcore/boards/esp32/xiao_esp32s3/board.overlay b/zephcore/boards/esp32/xiao_esp32s3/board.overlay index 9f88a21..8784a64 100644 --- a/zephcore/boards/esp32/xiao_esp32s3/board.overlay +++ b/zephcore/boards/esp32/xiao_esp32s3/board.overlay @@ -62,52 +62,10 @@ }; /* - * Flash partitions — repartition default ESP32-S3 4 MB layout. - * Delete lpcore, storage, scratch, and coredump partitions to reclaim - * the 384 KB from 0x3A0000 onwards for LittleFS. - * - * 0x3A0000 - 0x3FFFFF (384KB) LittleFS (identity, contacts, channels, BLE bonds) + * Flash partitions live in partitions.overlay (this dir) so the identical map + * is fed to both the app and the MCUboot image — see that file and + * sysbuild/CMakeLists.txt. */ -/delete-node/ &slot0_lpcore_partition; -/delete-node/ &slot1_lpcore_partition; -/delete-node/ &storage_partition; -/delete-node/ &scratch_partition; -/delete-node/ &coredump_partition; -/delete-node/ &slot0_partition; -/delete-node/ &slot1_partition; - -/ { - chosen { - zephyr,settings-partition = &storage_partition; - }; -}; - -&flash0 { - partitions { - /* App slots — both trimmed 8KB so slot0 == slot1 (16KB total freed - * for the NVS partition below), keeping MCUboot swap-mode compatible, - * not just overwrite-only. slot0 start (0x20000) unchanged. */ - slot0_partition: partition@20000 { - label = "image-0"; - reg = <0x20000 0x1BE000>; - }; - slot1_partition: partition@1de000 { - label = "image-1"; - reg = <0x1DE000 0x1BE000>; - }; - /* BLE bond store — 16KB NVS, isolated from /lfs (see esp32_common.conf). - * Carved from the end of slot1 so lfs stays byte-identical. */ - storage_partition: partition@39c000 { - label = "storage"; - reg = <0x39C000 0x4000>; - }; - /* LittleFS 384KB for DataStore (identity, prefs, contacts) */ - lfs_partition: partition@3a0000 { - label = "lfs"; - reg = <0x3A0000 0x60000>; - }; - }; -}; /* LittleFS auto-mount — standard /lfs mount point */ #include "../../common/filesystem.dtsi" diff --git a/zephcore/boards/esp32/xiao_esp32s3/partitions.overlay b/zephcore/boards/esp32/xiao_esp32s3/partitions.overlay new file mode 100644 index 0000000..0221010 --- /dev/null +++ b/zephcore/boards/esp32/xiao_esp32s3/partitions.overlay @@ -0,0 +1,53 @@ +/* + * Flash partition layout — SHARED by the app image and MCUboot. + * + * Fed to BOTH images (app via EXTRA_DTC_OVERLAY_FILE, MCUboot via + * mcuboot_EXTRA_DTC_OVERLAY_FILE in sysbuild/CMakeLists.txt) so their flash maps + * are identical — otherwise MCUboot stages/looks for the OTA image at a different + * address than the app writes it to and OTA silently reverts on reboot. + * + * slot0 starts at 0x10000 (right after the 64KB MCUboot region), matching the + * Arduino/ESP-IDF app offset (Mesh America "flash-update" compatible). sys_partition + * is reclaimed. Slots are equal size and slot1 ends exactly on the unchanged + * storage/lfs offsets, so a -merged reflash keeps identity/prefs/contacts/BLE-bonds. + * + * 4MB layout. + */ +/delete-node/ &sys_partition; +/delete-node/ &slot0_lpcore_partition; +/delete-node/ &slot1_lpcore_partition; +/delete-node/ &storage_partition; +/delete-node/ &scratch_partition; +/delete-node/ &coredump_partition; +/delete-node/ &slot0_partition; +/delete-node/ &slot1_partition; + +/ { + chosen { + zephyr,settings-partition = &storage_partition; + }; +}; + +&flash0 { + partitions { + /* App slots — equal size (swap-mode compatible), slot0 at 0x10000. */ + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x10000 0x1C6000>; + }; + slot1_partition: partition@1D6000 { + label = "image-1"; + reg = <0x1D6000 0x1C6000>; + }; + /* BLE bond NVS — offset unchanged so bonds survive the reflash. */ + storage_partition: partition@39C000 { + label = "storage"; + reg = <0x39C000 0x4000>; + }; + /* LittleFS (identity/prefs/contacts) — offset unchanged. */ + lfs_partition: partition@3A0000 { + label = "lfs"; + reg = <0x3A0000 0x60000>; + }; + }; +}; diff --git a/zephcore/sysbuild/CMakeLists.txt b/zephcore/sysbuild/CMakeLists.txt index 96678a4..8018d1d 100644 --- a/zephcore/sysbuild/CMakeLists.txt +++ b/zephcore/sysbuild/CMakeLists.txt @@ -49,5 +49,27 @@ if(_board_conf_candidates) endif() endif() +# Share the app's flash partition layout with MCUboot. +# +# The app's board.overlay is applied to the app image only. Without this, MCUboot +# falls back to the upstream Espressif base partition table, whose slot0/slot1 +# differ from the app's customised layout. The two images then agree only on +# slot0's *start* (so the device boots), but their image-1 (OTA) slots land at +# different addresses: the app stages an update where MCUboot never looks, so OTA +# uploads report success and then silently boot the old image on reset. +# +# Feeding the same partitions.overlay to MCUboot keeps both flash maps identical. +file(GLOB_RECURSE _board_partitions + "${APP_DIR}/boards/*/${_board_base}/partitions.overlay") +if(NOT _board_partitions AND + EXISTS "${APP_DIR}/boards/${_board_base}/partitions.overlay") + set(_board_partitions "${APP_DIR}/boards/${_board_base}/partitions.overlay") +endif() +if(_board_partitions) + list(GET _board_partitions 0 _board_partitions_file) + set(mcuboot_EXTRA_DTC_OVERLAY_FILE "${_board_partitions_file}" + CACHE INTERNAL "MCUboot partitions overlay: shared with the app image") +endif() + find_package(Sysbuild REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(sysbuild LANGUAGES)