v0.2.3 (2026-05-06)

Routine upstream bump.

  • nerves_system_br 1.33.4 → 1.33.7
    • Erlang/OTP 28.4.1 → 28.5
    • fwup 1.14.0 → 1.16.0
    • Buildroot 2025.11.2 → 2025.11.3

No system-side changes required.

v0.2.2 (2026-04-09)

mix burn support via OpenWrt's NOR full-recovery mode.

  • mix burn now prepares a FAT32 USB recovery stick that OpenWrt's SPI NOR recovery U-Boot can use to flash the entire SPI NAND — no serial console, no TFTP server, no typing of U-Boot commands. The stick contains the snand-preloader.bin (BL2) and our openwrt-one-nand.ubi (renamed to factory.ubi). See README.md "Initial install" for the full procedure.
  • Ship prebuilt/openwrt-one-snand-preloader.bin from OpenWrt 24.10 (same source + license as the FIP).
  • fwup.conf: replace the erroring complete task with one that mbr_writes + fat_mkfses + fat_writes the recovery files. The .fw file grows by ~33 MiB (the .ubi) + 234 KiB (preloader) but mix burn now Just Works with no per-app config.
  • post-createfs.sh: stage the preloader into images/ so fwup can find it at firmware-build time.
  • README: document USB stick recovery as the primary initial-install path; serial + TFTP demoted to "alternative".

v0.2.1 (2026-04-08)

USB mass storage support.

  • Linux: enable CONFIG_SCSI, CONFIG_BLK_DEV_SD, CONFIG_USB_STORAGE, CONFIG_FAT_FS + CONFIG_VFAT_FS, CONFIG_EXFAT_FS, and the matching NLS tables (CP437, ISO8859-1, UTF-8). USB sticks now enumerate as /dev/sdN and FAT/exFAT partitions mount and read.

v0.2.0 (2026-04-08)

OTA + A/B slot support, kernel bump, several bug fixes that turned session-1 workarounds into proper fixes.

Added

  • A/B FIT slots: UBI layout now uses fit_a (vol 3) and fit_b (vol 4) instead of a single fit volume. Each slot is sized at 50 MiB. Active slot is selected at boot via fit_${nerves_fw_active} substitution in ubi_read_production.
  • Image-level boot fallback: if bootm fails on the active slot, U-Boot's boot_production flips nerves_fw_active, saveenvs, and retries the other slot.
  • Bootcount-based runtime rollback: OTA sets upgrade_available=1
    • bootcount=0; U-Boot's nerves_count_attempt script swaps slots once bootcount > bootlimit (default 3). Nerves.Runtime.StartupGuard clears the counters once the app is healthy.
  • scripts/upload-ota.sh + scripts/apply-ota.exs: volume-level OTA via SFTP + ubiupdatevol + fw_setenv. Designed to be aliased as mix upload from the user app.
  • NervesSystemOpenwrtOne.UBootEnvKVBackend: custom Nerves.Runtime.KVBackend that reads via the Erlang UBootEnv library and writes via the C fw_setenv (which issues UBI_IOCVOLUP). Without this the default backend returns :eperm on every KV.put and breaks validate_firmware/0.
  • Full OpenWrt 24.10 default U-Boot env baked into ubootenv volumes via prebuilt/uboot-env-template.txt, with the 0x1F000 env size matching CONFIG_ENV_SIZE in OpenWrt's mt7981 U-Boot. Eliminates the cosmetic boardid: U-boot environment CRC32 mismatch warning that was caused by sizing our env smaller than what U-Boot writes back.
  • CONFIG_IP_ADVANCED_ROUTER=y, CONFIG_IP_MULTIPLE_TABLES=y, CONFIG_IP_ROUTE_MULTIPATH=y so VintageNet's policy-routing setup doesn't crash with RTNETLINK answers: Operation not supported.

Changed

  • Linux 6.12 → 6.18.12.
  • SPI NAND driver path: dropped the spi-mtk-snfi attempt and the Etron 0x77-shifted-manufacturer-ID workaround. Now uses spi-mt65xx with the OpenWrt SPI calibration patch stack (patches 121, 330, 431-435, 930) plus mtk_bmt. The chip is actually a Winbond 256 MiB part, not the 128 MiB Etron we initially guessed.
  • U-Boot env path in fw_env.config: /dev/ubi0_0 and /dev/ubi0_1 instead of /dev/ubi0:ubootenv. The Erlang uboot_env library uses plain File.open and doesn't understand the :volname shorthand that fwup-tool's fw_printenv accepts.

Fixed

  • mkimage invocation in wrap-firmware.sh now prefers /usr/bin/mkimage over Buildroot's host build, because the latter ships with MKIMAGE_DTC="" and explodes with sh: 1: -I: not found whenever it tries to run dtc internally.

v0.1.0 (2026-04-07)

Initial Nerves system for the OpenWRT One.

  • Linux 6.12 mainline kernel with small patches
  • Custom DTS based on mainline mt7981b-openwrt-one.dts with full peripheral enablement
  • WiFi 2.4 / 5 GHz with proper calibration from factory partition
  • Both Ethernet ports (1 GbE LAN + 2.5 GbE WAN with EN8811H PHY)
  • RTC, GPIO watchdog, LEDs, buttons
  • NAND boot via UBI volumes (fip + fit + ubootenv + rootfs_data)
  • Pre-built FIP from official OpenWrt 24.10 release