View this page on MeshCore Docs.
# nRF52 bootloader updates over LoRa For **MeshCore 1.18.0.1**, choose the exact board and storage layout in the [firmware picker](firmware_picker.md). The matching bootloader release is [OTAFIX 2.4.12](https://github.com/mikecarper/Adafruit_nRF52_Bootloader_OTAFIX/releases/tag/v0.11.0-OTAFIX2.4.12). Firmware and bootloader versions are separate. See the [1.18.0.1 update guide](ota_user_guide.md) for ordinary application updates. For an application image that carries its own board-matched 2.4.12 replacement, see [embedded nRF52 bootloader updates](nrf52_embedded_bootloader.md). A separate `with-bootloader-2.4.12` image checks once after 70 seconds of startup and updates a recognized compatible older bootloader when radio and OTA activity are idle. The authenticated admin activation command remains available for manual retry. Selected nRF52840 Repeater and Room Server LoRa-OTA builds can replace their matching OTAFIX bootloader without replacing the running application. This is a privileged maintenance path, not a normal firmware update. A stock bootloader must first be replaced with the exact ABI-3 self-update-capable OTAFIX build over USB/BLE DFU or SWD. MeshTower SD also requires the BLM2 retained-auth version to be provisioned locally before either application or bootloader OTA. The released adaptive RAK3401 and RAK4631 OTAFIX 2.4.8/2.4.9 profiles support application full and delta updates, but not bootloader self-update over LoRa. USB UF2 and local Bluetooth/serial Legacy DFU bootloader updates still work. Their running bootloader protects `0xF4000..0x100000` with the nRF52840 ACL before starting MeshCore. This includes the MBR parameter page at `0xFE000`, so an application cannot initiate `COPY_BL` even after verifying a signed bootloader package. Hardware testing on a RAK3401 confirmed the MBR SVC enters a bus fault and leaves the installed bootloader unchanged. For new RAK installations use the normal OTAFIX 2.4.12 `wiscore_rak3401_auto` or `wiscore_rak4631_auto` image. These retain the standard `3401_DFU` / `4631_DFU` identities. A compatible standard installation can receive the exact signed bootloader `.mota` over LoRa. Historical `3401_AUTO_DFU` / `4631_AUTO_DFU` and dedicated external-storage identities need the matching local recovery bridge before moving to the normal image; select it from the separate `OTAFIX-2.4.12-R_recovery.zip` and follow the release's recovery instructions. Recovery images are migration tools, not the normal download. ## Storage layouts | Layout | Application limit | Staged boot package | Work area | Handoff / capability | | --- | ---: | ---: | ---: | --- | | XIAO-module raw QSPI | below `0xE0000` | external QSPI offset 0 | dedicated internal `0xE0000..0xEA000` scratch | source `0x51`, flags `0x0E` | | Qualified internal-flash target | normal `0xED000` flash limit; top 64 KiB SRAM reserved for application-delta staging | shared internal slot, exact start `0xE2000` | the same eleven-page slot; no second flash reservation | source `0xED`, flags `0x0A` | | MeshTower V2 microSD | normal `0xED000` limit | contiguous `/meshcore-ota.mota` | dynamic internal `0xE0000..0xEA000` scratch; live image must end by `0xE0000` | source `0x53`, flags `0x09` | The exact SD target is `Heltec_tower_v2_sdcard_repeater_lora_ota_no_external_sensors`. Its normal application FULL and delta updates continue to use the SD file without the bootloader-update scratch restriction. For a bootloader package only, both MeshCore and OTAFIX require a hash-valid live `EndF` proving the complete running image ends at or below `0xE0000`. If boot settings carry a nonzero app bank CRC, the recorded bank size must also cover that full EndF-inclusive image and stop by `0xE0000`; erased or explicitly CRC-disabled settings remain valid. OTAFIX then copies the verified 40 KiB payload from SD into `0xE0000..0xEA000` and uses the MBR copy operation to replace `0xF4000..0xFE000`. The application linker remains at `0xED000`; a future application extending above `0xE0000` can still use application mOTA but must update its bootloader through local DFU/SWD. The removable SD authorization is fail-closed for both application and bootloader packages. MeshCore directly authenticates one exact signed manifest, requires the streamed copy to remain byte-identical, verifies all leaves/payload/image bytes, and computes a normalized full-container SHA-256 in that same pass (`APRV` bytes are treated as zero). After syncing `APRV`, it publishes a 72-byte `MOTASDA2` record in reset-retained RAM at `0x20006008`. That record binds purpose/format, first LBA, sector count, total length, card sector count, and the normalized digest. OTAFIX copies, validates, and clears the record before SD access. A card swap/mutation or a power cycle therefore fails closed; there is no general sector-1 ownership inference. For fmt3, MeshCore also writes and readback-verifies a 64-byte `MOTASDBL` token at `0xE0000`. That token contains the exact container length and the exact authenticated signed manifest `image_hash`. OTAFIX requires the same hash in the parsed manifest, streamed payload, and final scratch image. The page is consumed as scratch during success and is not permanently reserved. The first BLM2-capable MeshTower bootloader cannot be delivered to preview.12 through the retained-RAM protocol that preview.12 predates. MeshCore does not 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. The internal path does not change the application's `0xED000` 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. 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 `0xED000` store ceiling it bottom-aligns at `0xE2000`. Admission requires a hash-valid live `EndF` proving the current application, including its trailer, ends at or before `0xE2000`. OTAFIX then reads each source window before erasing and compacts the payload forward in place to the page-aligned raw range `0xE2000..0xEC000`; it verifies every page and the whole image before asking the MBR to copy that image over `0xF4000..0xFE000`. An ordinary application delta can be smaller or larger than this eleven-page shape. On the qualified profile, a delta larger than one page uses the minimum page-aligned flash prefix ending at `0xED000` 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 `0xED000`. The two package kinds are mutually exclusive because they use the same flash store, and a bootloader package never uses the volatile SRAM suffix. For internal-self-update builds, an absent or corrupt live `EndF` disables **all** internal staging before the first erase. The older 608 KiB rescue estimate is unsafe when a normally linked application may extend to `0xED000`. Builds without this feature retain the legacy rescue behavior. ## Internal-flash target inventory The release builder consumes the allowlist in `tools/mota/nrf52_internal_bootloader_targets.txt`. It includes literal PlatformIO environments and release aliases; build aliases through `build.sh` so the common pre-build guard receives the same storage/layout decision. The inventory includes lean repeaters and bridges plus the explicitly listed adaptive RAK receiver roles. Their bootloader identities are listed below; use the picker for current application names and downloads. | Build target(s) | Installed OTAFIX identity | Boot target ID | | --- | --- | ---: | | Historical internal-only MeshTower V2 layout; current releases use the combined SD target | `239A0071 / TOWER_V2_OTA` | `1150F50E` | | T096 lean repeater and RS232 bridge | `239A0071 / T096_DFU` | `42354C85` | | `Heltec_t1_repeater_lora_ota_no_external_sensors` | `239A0071 / T1_DFU` | `FC556FFC` | | T114 display and without-display lean repeaters | `239A0071 / T114_DFU` | `0C3F2902` | | `Mesh_pocket_repeater_lora_ota_no_external_sensors` | `239A0071 / MESH_POCKET_OTA` | `059277F4` | | `KeepteenLT1_repeater_lora_ota_no_external_sensors` | `239A00B3 / KeepteenLT1_OTA` | `DB2E7B51` | | `Minewsemi_me25ls01_repeater_lora_ota_no_external_sensors` | `239A0029 / MX25_DFU` | `026AA982` | | `ProMicro_repeater_lora_ota_no_external_sensors` | `239A00B3 / PROM_DFU` | `AF79E8CC` | | `t1000e_repeater_lora_ota_no_external_sensors` | `28860057 / T1KE_DFU` | `E6F5F03F` | | `ThinkNode_M3_repeater_lora_ota_no_external_sensors` | `239A00DA / TNM3_DFU` | `0CA41DB2` | | RAK3401 reduced repeater and unified repeater | `239A0029 / 3401_DFU` | `23818A80` | | RAK4631 reduced/unified repeater, both reduced RS232 bridges, and listed reduced Room/Sensor roles | `239A0029 / 4631_DFU` | `2D0DF000` | | GAT562 30S/Tracker Pro/EVB Pro lean targets | `239A0029 / GAT562_DFU` | `D50D2D44` | | `R1Neo_repeater_lora_ota_no_external_sensors` | `239A0029 / 4631_DFU` | `2D0DF000` | | `RAK_WisMesh_Tag_repeater_lora_ota_no_external_sensors` | `239A0029 / RTAG_DFU` | `C72E9C9C` | Board IDs are not globally unique. For generic targets, the signed hardware ID is the exact NUL-padded 32-byte value `NRF_BL_