Skip to content

Releases: ajsb85/sprdflash-rs

SPRD Flash Tool v0.8.0

Choose a tag to compare

@github-actions github-actions released this 12 Jul 13:03
v0.8.0
451c61e

Standalone extraction — whole-flash backup and layout reconstruction, no matching PAC or on-device partition table required.

Highlights

💾 Whole-flash backup — dump --full

sprdflash dump --full --enter-download --pac any-rda8910.pac --out ./dump

Reads the entire flash into flash.bin, auto-discovering its size by
binary-searching READ_FLASH — this FDL2 has no geometry command, so an in-range
read replies READ_FLASH and an out-of-range one replies INVALID_CMD, and the
boundary is the flash size. Needs only any RDA8910 PAC for the FDL stages.
Hardware-verified on an Air724UG: size auto-found as 8 MiB, every partition
matching its offset in the image.

🧩 Reconstruct a layout from a dump — layout

sprdflash layout --flash ./dump/flash.bin --out layout.xml

Recovers a proposed <BMAConfig> from a full dump alone — no device, no
matching PAC. It classifies on-flash content: U-Boot uImage code regions (magic
0x27051956, exact size, header + payload CRC-32 verified), LuatOS luadb,
and the wear-levelled NOR filesystem back half (longest single-generation run =
the live FS). Hardware-verified: 5/5 flash-resident partition bases + reserved
sizes reproduced byte-exact vs the real PAC.

Region names are generic content-type defaults (uimage_0, luadb_0,
filesystem_0, nv_0) — the flash stores no partition role names, and roles are
firmware-specific. What a dump can't give (documented): role names, the FDL
loaders (they live in SRAM, not NOR), and the PAC's erase/control directives.

🔎 Capability probe — parts

Probes an FDL2's capabilities and flash extent. On the RDA8910, every
introspection command (READ_PARTITION, chip/flash info) replies INVALID_CMD,
which is why the layout has to be recovered from content rather than queried.

Verifying downloads

echo 'ajsb85@firechip.dev ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJXmKlNp62mfIFNHT4Duv6vcTwfqb/M6OUs34upSpN/L' > allowed_signers
ssh-keygen -Y verify -f allowed_signers -I ajsb85@firechip.dev -n file \
    -s sprdflash-v0.8.0-x86_64-unknown-linux-gnu.sig \
    < sprdflash-v0.8.0-x86_64-unknown-linux-gnu
gh attestation verify sprdflash-v0.8.0-x86_64-unknown-linux-gnu --repo ajsb85/sprdflash-rs

Changes

  • feat(cli): dump --full — standalone whole-flash backup with size discovery
  • feat(cli): layout — reconstruct a proposed <BMAConfig> from a dump
  • feat(cli): parts — probe FDL2 capabilities / flash extent
  • feat(core): crc32 (IEEE) + the reconstruct module

Full Changelog: v0.7.0...v0.8.0

SPRD Flash Tool v0.7.0

Choose a tag to compare

@github-actions github-actions released this 12 Jul 11:31
v0.7.0
8ee99a7

Golden-device cloning and flexible extraction, built on the proven read-back path.

Highlights

🧬 Clone a reference unit into a flashable golden PAC — clone

sprdflash clone --enter-download --pac reference.pac --out golden.pac

Reads a device's partitions off the flash (read-only) and splices them into a
copy of the reference PAC — same FDL stages, layout, markers, and XML — then
refreshes the header + payload CRC-16-ARC and validates the result before
writing. The output is a flashable .pac capturing a configured reference
unit's firmware, which you can flash to other units — no vendor tool.

Hardware-verified on an Air724UG (RDA8910): cloning a device that holds the
reference firmware produces a golden PAC byte-identical (SHA-256) to the
reference — a lossless round-trip.

🎯 Arbitrary-region dump — dump --region

sprdflash dump --enter-download --pac any-rda8910.pac \
    --region 0x60000000:42112 --region 0x60010000:2468352 --out ./dump

Read any flash range(s) as ADDR:SIZE (hex or decimal, repeatable) instead of
the PAC's partition layout — the PAC is then used only for the FDL stages.

🔁 Any RDA8910 PAC works for the FDL stages

The FDL1/FDL2 download agents are interchangeable across firmware versions for
the same chip. Hardware-verified: dumping an Air-firmware device using a LuatOS-
HMI
PAC's FDLs yields byte-identical bytes to a dump with the matching PAC. So
you don't need a device's exact firmware to extract or clone it — any PAC for the
chip supplies the FDLs.

Note: fully PAC-free extraction (no PAC at all) is intentionally not shipped
— it would require redistributing Unisoc's proprietary FDL blobs (a licensing
problem) and reverse-engineering on-device partition-table discovery. Bring any
RDA8910 PAC for the FDLs instead.

Verifying downloads

echo 'ajsb85@firechip.dev ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJXmKlNp62mfIFNHT4Duv6vcTwfqb/M6OUs34upSpN/L' > allowed_signers
ssh-keygen -Y verify -f allowed_signers -I ajsb85@firechip.dev -n file \
    -s sprdflash-v0.7.0-x86_64-unknown-linux-gnu.sig \
    < sprdflash-v0.7.0-x86_64-unknown-linux-gnu
gh attestation verify sprdflash-v0.7.0-x86_64-unknown-linux-gnu --repo ajsb85/sprdflash-rs

Changes

  • feat(cli): clone — capture a device into a flashable golden PAC
  • feat(cli): dump --region ADDR:SIZE for arbitrary flash ranges

Full Changelog: v0.6.0...v0.7.0

SPRD Flash Tool v0.6.0

Choose a tag to compare

@github-actions github-actions released this 12 Jul 11:18
v0.6.0
8fe3868

Read-back extraction, and diagnostics hardened by real-device recovery testing.

Highlights

📤 Extract partitions off a device — dump

sprdflash dump --enter-download --pac firmware.pac --out ./dump

Reads every partition straight off the flash with READ_FLASH and writes one
<file_id>.bin per partition — read-only, no writes to the device. The PAC
supplies this device's FDL1/FDL2 stages and the partition layout (addresses +
sizes); the bytes come off the device.

Hardware-verified on an Air724UG (RDA8910): all four partitions (5.72 MiB) dump
byte-identical (SHA-256) to the flashed PAC — proving READ_FLASH reads
persistent flash, not just data written in the same session. A real
backup/clone/forensics primitive.

♻️ flash auto-recovers a module stuck in FDL2

If a previous flash aborted after loading FDL2 (e.g. a genuine read-back verify
failure), the module is left in FDL2 and a fresh flash's PDL handshake would
fail. flash now detects that, sends a NORMAL_RESET, waits for the module to
re-enumerate and its firmware to settle, and retries once — no manual reset
needed. Also available standalone as sprdflash reset.

🔎 Honest timeouts

Read timeouts reported deadline - now, which is always ~0 once the deadline has
passed, so every timeout read "after 0ns". They now report the real time waited
(e.g. after 5.00s).

Verifying downloads

Every binary ships with a detached SSH signature (.sig, Ed25519, namespace
file, key SHA256:1wCKrSPq3V4q7DkiomqRJKzr6Vc1bY+eKU1qRvEvGKk) and keyless
Sigstore build provenance:

echo 'ajsb85@firechip.dev ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJXmKlNp62mfIFNHT4Duv6vcTwfqb/M6OUs34upSpN/L' > allowed_signers
ssh-keygen -Y verify -f allowed_signers -I ajsb85@firechip.dev -n file \
    -s sprdflash-v0.6.0-x86_64-unknown-linux-gnu.sig \
    < sprdflash-v0.6.0-x86_64-unknown-linux-gnu
gh attestation verify sprdflash-v0.6.0-x86_64-unknown-linux-gnu --repo ajsb85/sprdflash-rs

Changes

  • feat(cli): dump — extract partitions off the device (read-only)
  • fix(cli): auto-recover a flash from FDL2 (reset + retry)
  • fix(transport): report the real read-timeout duration, not 0ns
  • refactor(flash): shared FDL bring-up for run and dump

Full Changelog: v0.5.0...v0.6.0

SPRD Flash Tool v0.5.0

Choose a tag to compare

@github-actions github-actions released this 12 Jul 05:32
v0.5.0
a8cf68d

Full Changelog: v0.4.0...v0.5.0

SPRD Flash Tool v0.4.0

Choose a tag to compare

@github-actions github-actions released this 12 Jul 04:44
v0.4.0
8d69f80

High-assurance flashing and unattended line operation.

This release adds a byte-for-byte read-back check for units that need it, a
continuous "run all shift" line mode, and a hardware-free test path that
exercises the entire flash protocol in CI with no device attached.

Highlights

🔎 Post-write read-back verify — --verify-readback

After each partition is written, its bytes are read straight back off the device
with the BSL READ_FLASH command and compared to the source image. Any
difference fails the flash immediately with read-back verify failed for <partition>, so a marginal cable, a flaky USB hub, or a bad flash block is
caught on the line instead of in the field.

It roughly doubles flash time, so it is off by default — reserve it for
high-assurance builds or fixture bring-up.

sprdflash flash firmware.pac --format --verify-readback

♾️ Continuous line mode — --loop

Runs the line unattended: each station keeps flashing units, waiting for the
operator to swap in the next module between cycles, until you press Ctrl-C.
The stop is graceful — in-flight units finish and their records are written
before exit. Pair it with --metrics-addr so a Prometheus/Grafana board watches
yield and throughput live for the whole shift.

sprdflash line firmware.pac \
    --station fixture-1:COM12 --station fixture-2:COM22 \
    --format --loop --metrics-addr 0.0.0.0:9184 \
    --records /var/log/flash/units.jsonl

Memory stays bounded no matter how long it runs: records stream to the JSONL
sink and fold into the metrics counters, with only a recent tail kept in memory
for the summary. A short floor between cycles keeps a misconfigured or empty line
from busy-spinning.

🧪 Hardware-free end-to-end tests

The serial byte stream now sits behind a Transport trait, and a new
MockTransport speaks just enough of the PDL and BSL protocols to drive a
complete PDL → BSL → partitions → format → reset flash with no device
attached
. CI now covers the happy path, adaptive-retry recovery after a
dropped ack, and both the passing and corruption-detected read-back paths.

Verifying downloads

Every binary ships with a detached SSH signature (.sig) made with the
maintainer's Ed25519 key (SHA256:1wCKrSPq3V4q7DkiomqRJKzr6Vc1bY+eKU1qRvEvGKk,
signature namespace file):

# one-time: trust the signing key
echo 'ajsb85@firechip.dev ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJXmKlNp62mfIFNHT4Duv6vcTwfqb/M6OUs34upSpN/L' > allowed_signers

ssh-keygen -Y verify -f allowed_signers -I ajsb85@firechip.dev -n file \
    -s sprdflash-v0.4.0-x86_64-unknown-linux-gnu.sig \
    < sprdflash-v0.4.0-x86_64-unknown-linux-gnu
# -> Good "file" signature for ajsb85@firechip.dev

Each binary also carries keyless Sigstore build provenance
from GitHub Actions, verifiable with gh attestation verify <file> --repo ajsb85/sprdflash-rs.

Changes

  • feat(flash): optional post-write read-back verification (--verify-readback)
  • feat(line): continuous unattended mode with graceful stop (--loop)
  • test(flash): protocol mock and end-to-end flash tests
  • refactor(transport): abstract the byte stream behind a Transport trait

Assets

Platform Binary
Windows x86-64 sprdflash-v0.4.0-x86_64-pc-windows-msvc.exe
Linux x86-64 sprdflash-v0.4.0-x86_64-unknown-linux-gnu
macOS Apple Silicon sprdflash-v0.4.0-aarch64-apple-darwin
macOS Intel sprdflash-v0.4.0-x86_64-apple-darwin

Full Changelog: v0.3.0...v0.4.0

SPRD Flash Tool v0.3.0

Choose a tag to compare

@github-actions github-actions released this 12 Jul 04:13
v0.3.0
bd09a7a

Full Changelog: v0.2.0...v0.3.0

SPRD Flash Tool v0.2.0

Choose a tag to compare

@github-actions github-actions released this 12 Jul 03:45
v0.2.0
f822510

Full Changelog: v0.1.0...v0.2.0

SPRD Flash Tool v0.1.0

Choose a tag to compare

@ajsb85 ajsb85 released this 12 Jul 02:18
v0.1.0
bc0d0ef

Pure-Rust, cross-platform (Windows 11 + Linux/WSL) native flasher for
SPRD/UNISOC .pac firmware — RDA8910 / UIS8910 (Air724UG and friends) — built
for the manufacturing line and verified end-to-end on real hardware.

Highlights

  • No vendor tool. Speaks the full download protocol directly: PDL (loads
    FDL1) → BSL/FDL2 → partitions → optional cross-SDK --format → reset.
  • Hardware-verified on a real Air724UG (RDA8910): a same-SDK reflash and
    a cross-SDK change (LuatOS V4035 ⇄ CSDK V302340) that boots directly on the
    soft reset with IMEI and NV intact.
  • Manufacturing line orchestrator: one thread per fixture, flashing and
    boot-verifying in parallel, each unit boot-verified (ATI/IMEI) and written as
    one JSON-lines record for the MES/ERP, with yield + throughput metrics and
    automatic recovery of a wedged agent.
  • Sans-I/O core (#![forbid(unsafe_code)]), Rust 2024 edition, MSRV
    1.85, clippy -D warnings clean, CI on Windows + Linux.

What's in the box

Crate Role
sprdflash-core Pure protocol: PAC parse, PDL + BSL framing, checksums, cross-SDK plan
sprdflash-transport serialport byte stream, USB discovery, beacon-window connect, recovery
sprdflash-flash Device driver: PDL → BSL → partitions → format → reset
sprdflash-line Parallel stations, boot-verify, JSON-lines records, metrics
sprdflash-cli The sprdflash binary: info, list-ports, flash, line

Measured speed

6 MB in ~33 s (chunk = 2048), 22% faster than the reference Python (~42 s).
The device is flash-write-bound (~186 KiB/s), so line throughput comes from
per-fixture parallelism (~110 units/hour each) → thousands/day across a bank
of stations.

Usage

# one device, auto mode-switch, boots into the new firmware
sprdflash flash --enter-download firmware.pac
# cross-SDK change (formats FS, refreshes NV, keeps IMEI)
sprdflash flash --enter-download --format firmware.pac
# manufacturing line: parallel stations + MES records
sprdflash line firmware.pac --station f1:COM12 --station f2:COM22 \
    --format --records units.jsonl

ERP / MES integration

Every flashed unit emits one JSON line (schema, PostgreSQL DDL with KPI views,
and a report catalog under docs/). See
docs/erp-mes-data-model.md.

Verification

  • The v0.1.0 tag is SSH-signed (git tag -v v0.1.0).

  • The Windows binary is shipped with a detached SSH signature
    (sprdflash-v0.1.0-x86_64-windows.exe.sig). Verify with:

    ssh-keygen -Y verify -f allowed_signers -I ajsb85@firechip.dev \
        -n file -s sprdflash-v0.1.0-x86_64-windows.exe.sig \
        < sprdflash-v0.1.0-x86_64-windows.exe
    

Signed-off-by: Alexander Salas Bastidas <ajsb85@firechip.dev>