Skip to content

Stock nRF52 bootloader version audit

Checked 2026-09-29, against the 40 nRF52 variant families resolving to 26 board configurations in this checkout. This concerns get bootloader.ver, not bootloader installation or OTA eligibility. No devices were flashed, and no features, storage sizes, or partitions were changed.

Result

The real firmware reader successfully reads 26 distinct manufacturer-published bootloader images from 32 artifact records, including older RAK revisions, current and historical LilyGO images, and vendor HEX, UF2 and DFU ZIP packages. Repeated copies and identical normalized bootloader images are counted once. These are publicly supplied stock/recovery images, not proof that every manufacturing batch shipped identical bytes. No untouched live unit was read in this audit.

One format gap was fixed: Seeed's T1000-E LoRaWAN development-board bootloader declares UF2 Bootloader 1.00. The reader now accepts that two-component version and returns 1.00 unchanged. It does not invent 1.00.0. That development image is separate from Seeed's Meshtastic/MeshCore recovery image, which reports 0.9.1-5-g488711a and already worked.

All other tested images already expose a readable UF2 bootloader record. Generic bare dotted-number searches remain deliberately unsupported: TinyUSB, nrfx, and SoftDevice can embed their own versions inside the same bootloader. The bounded standalone fallback still requires the explicit OTAFIX version shape. Ambiguous records, invalid vectors, and corrupt canonical OTAFIX metadata retain the existing rejection rules.

Published images actually tested

The exact source URLs, download hashes, normalized-image hashes, extraction layout and expected strings are pinned in stock_images.json.

Manufacturer image family Version captured from the image
RAK4631/RAK4630 Arduino bootloader, historical through current 0.3.2-109-gd6b28e6, 0.4.1-13-g5e6690e-dirty, 0.4.2, 0.4.3, 0.4.4
Heltec HT-n5262, SDK and T114 vendor recovery HEX 0.9.0-2-g836c8dc-dirty
LilyGO T-Echo 0.6.1-2-g1224915
LilyGO T-Echo Lite, Card, T-Impulse Plus (including historical builds) 0.9.2-dirty
Seeed XIAO nRF52840 and Sense 0.6.1
Seeed XIAO nRF52840 Plus and Sense Plus 0.9.2-29-g6a9a6a3
Seeed Wio Tracker 1110 SDK/conversion bootloader 0.6.2-26-g949425a-dirty
Seeed Wio Tracker L1 vendor recovery ZIP 0.7.0-22-g277a0c8
Seeed T1000-E Meshtastic/MeshCore recovery ZIP 0.9.1-5-g488711a
Seeed T1000-E LoRaWAN development-board HEX 1.00 (newly supported)
Seeed MeshTracker X1 recovery ZIP 0.10.0-18-gb93789f
MTools Tec MeshTiny vendor bootloader UF2 0.4.5
BQ/Unit Engineering Nano G2 Ultra vendor HEX ZIP 0.6.4-dirty
Muzi Works R1 Neo release HEX 0.9.2-31-g990aa7f-dirty

Use the embedded version, not the filename. For example, Seeed's XIAO file named ...bootloader-0.6.2...hex reports 0.6.1, and its L1 ZIP named ...bootloader-0.10.0...zip reports 0.7.0-22-g277a0c8. These are actual tested bytes, not renamed or inferred release numbers.

All these normalized images use the Adafruit nRF52840 F4000..FE000 bootloader window. HEX/UF2 address records identify the bytes. The boot-only Seeed DFU packages omit MBR/UICR address words; their bootloader binary is extracted using the manifest's sd_size/bl_size and the Adafruit nRF52840 linker layout. The runtime reader independently selects the installed MBR/UICR boot address; this audit does not hardcode that layout into the firmware getter.

Coverage of every variant family

  • Image verified: a published bootloader for that named product/module was tested. Factory batch identification still requires reading the actual unit.
  • Representative only: a related module/SDK bootloader was tested; its exact factory image was not obtained. Shared build configuration alone does not establish identical factory bootloaders.
  • Unverified: no accessible factory bootloader image was obtained. This is not a demonstrated reader failure.
Variant family Status Evidence or remaining gap
gat562_30s_mesh_kit Unverified GAT documentation/firmware repository checked; no product-specific stock bootloader found.
gat562_mesh_evb_pro Unverified Same GAT gap; RAK board configuration is not factory-image proof.
gat562_mesh_tracker_pro Unverified Same GAT gap; custom vendor/OTAFIX builds also exist.
gat562_mesh_watch13 Unverified Same GAT gap.
heltec_mesh_solar Representative only HT-n5262 SDK image passes; Solar downloads found application images, not a board-specific stock bootloader.
heltec_t096 Representative only HT-n5262 SDK image passes; T096 factory revision not established.
heltec_t1 Representative only SDK image passes; vendor F&T archive contains application-only UF2s.
heltec_t114 Image verified Both SDK HEX and T114-specific vendor recovery HEX pass.
heltec_tower_v2 Representative only SDK image passes; vendor matching-firmware archive contains applications, not the stock bootloader.
ikoka_handheld_nrf Representative only XIAO board configuration; XIAO module images pass, exact installed factory image not obtained.
ikoka_nano_nrf Representative only Same XIAO representative coverage.
ikoka_stick_nrf Representative only Same XIAO representative coverage.
keepteen_lt1 Unverified Manufacturer product/download search did not yield a factory bootloader binary.
lilygo_t_impulse_plus Image verified Both historical and newer vendor bootloader HEX images pass.
lilygo_techo Image verified Vendor T-Echo bootloader passes.
lilygo_techo_card Image verified Three distinct vendor historical/current bootloader images pass. NFC UICR repair application excluded.
lilygo_techo_lite Image verified Vendor bootloader HEX passes.
mesh_pocket Representative only HT-n5262 SDK image passes; exact Pocket factory revision not established.
meshtiny Image verified Direct manufacturer bootloader UF2 passes; newer ADV/factory revisions require their actual image.
meshtracker_x1 Image verified Seeed product-specific recovery ZIP passes.
minewsemi_me25ls01 Unverified Manufacturer module page lists firmware as none; no stock bootloader binary found. OEM/dev-kit installations can differ.
muzi_base Unverified Manufacturer publishes bootloader source, but its release assets found were for R1 Neo, not BASE.
muziworks_r1_neo Image verified Manufacturer R1 Neo release HEX passes; do not substitute a generic RAK version.
nano_g2_ultra Image verified Manufacturer's preinstalled-bootloader recovery HEX ZIP passes.
promicro Unverified Nologo documents a Nice!Nano UF2 drive; its linked download requires Baidu access. Generic clones need separate factory images.
rak3401 Representative only RAK4631 Arduino images pass; RAK3401-specific untouched image not obtained.
rak4631 Image verified Five distinct published stock Arduino bootloader revisions pass. RAK4631-R/RUI3 is a different bootloader family.
rak_wismesh_tag Representative only RAK core images pass; exact Tag factory image not obtained.
sensecap_solar Representative only Seeed documentation identifies XIAO DFU; XIAO images pass, exact Solar factory image not obtained.
t1000-e Image verified Both vendor recovery ZIP and separate LoRaWAN development-board HEX pass.
thinknode_m1 Unverified Manufacturer repository checked; no factory bootloader binary found.
thinknode_m3 Unverified Published factory UF2 is application-only (26000..52BFF), not a bootloader image.
thinknode_m4 Unverified Published factory UF2 is application-only (26000..521FF).
thinknode_m6 Unverified Published factory UF2 is application-only (26000..46CFF).
thinknode_m8 Unverified No accessible product-specific factory bootloader binary found.
wio-tracker-l1 Image verified Seeed's L1 recovery ZIP passes.
wio-tracker-l1-1w Representative only L1 recovery image passes; exact 1W/ADV factory revision not established.
wio-tracker-l1-eink Representative only L1 recovery image passes; exact e-ink factory revision not established.
wio_wm1110 Representative only Published Wio Tracker 1110 and XIAO SDK images pass; the variant's XIAO config does not prove the shipped module's image.
xiao_nrf52 Image verified XIAO, Sense, Plus and Sense Plus vendor images pass.

Representative/unverified products use the same shared reader and should report a version if their installed bootloader exposes one of the recognized records. There is no evidence yet for claiming an exact version or success on every untouched unit. ESP32, RP2040 and STM32 are outside this nRF52 flash reader; their getters were not changed and this report does not claim stock-version capture on those architectures.

Reproduce the artifact tests

Normal tests are offline and include all observed version strings, malformed and conflicting versions, dependency-version false positives, region/vector bounds, and the existing OTAFIX metadata/CRC/fallback cases:

python3 test/test_nrf52_bootloader_version.py -v

To replay the real images, download each url in stock_images.json into a cache directory using its file name, then run:

MESHCORE_STOCK_BOOTLOADER_CACHE=/absolute/path/to/cache \
  python3 test/test_nrf52_bootloader_version.py -v

This checks the exact download SHA-256, extracts only the bootloader window, checks the normalized-image SHA-256, and invokes the actual C++ reader with an exact expected version. It never downloads automatically or flashes a device. The ordinary regression cases cover every captured format even without the optional cached artifacts. RAK4631 and T1000-E repeater firmware builds passed.

What is needed to close the remaining gaps

For each untouched unit, collect its DFU drive's INFO_UF2.TXT if present. To prove the application's flash reader can capture that exact revision, also obtain a read-only bootloader dump plus the MBR word at 0xFF8, UICR NRFFW[0], and flash geometry (or a full vendor HEX including those address records). Keep the bootloader unchanged while collecting this evidence. Only the identified bootloader region is needed; private application keys/configuration are not. If no version bytes or startup register value exist, report unknown; a regex cannot recover a version that was never embedded.

Manufacturer sources