A modular, transparent, safety-first flasher/dumper for ESP microcontroller boards.
chipforge is built around three principles: read before you write, fail loudly rather than silently, and no opaque magic. Every protocol byte is documented and every decision is traceable. Write and erase operations are available in a --stub build and are always backup-gated and post-write MD5-verified.
ESP8266 flash read/backup with no GPL. Reading ESP8266 flash needs a small RAM stub (the ROM has no flash-read command). chipforge ships its own from-scratch, MIT/Apache-licensed stub (
--features stub-own) — hardware-validated to produce a backup byte-identical to the reference Espressif stub. The legacy GPL stub remains available as an opt-in alternative. See Stub options.
espflash (the esp-rs Rust ecosystem tool) targets the ESP32 family and has never supported the ESP8266 — the ESP8266 is not a supported Rust-on-chip target in that ecosystem. Any tool that wants to serve a NodeMCU V3 (ESP8266) from Rust must implement the ROM serial protocol itself. chipforge does exactly that. See docs/research/03-tooling-prior-art.md for the full prior-art survey.
| Feature | Status | Notes |
|---|---|---|
| List serial ports + detect converter | yes | chipforge ports |
| Chip identify (kind, MAC) | yes | chipforge -p <PORT> info |
| Flash JEDEC id + size | yes (with --stub) |
chipforge -p <PORT> --stub info |
| Firmware image header inspection (offline) | yes | chipforge image-info <fw.bin> |
| Compare two binary dumps (offline) | yes | chipforge diff <a.bin> <b.bin> |
| Read / dump flash | yes (with --stub) |
Own MIT stub or opt-in GPL stub — see below |
| Full verified backup | yes (with --stub) |
Dual MD5 verified; .json sidecar — see below |
| Own MIT ESP8266 stub | yes (--features stub-own) |
From-scratch, no GPL; HW-validated byte-match — see below |
| Flash write | yes (with --stub, backup-gated) |
Deflate by default; post-write MD5 verified — see below |
| Erase (chip/region) | yes (with --stub, backup-gated) |
Whole-chip or 4 KB-aligned region — see below |
| Verify | yes (with --stub) |
Compares flash region to file by MD5 |
| Interactive TUI | yes | chipforge tui |
| ESP32 family (optional backend) | yes (--features backend-espflash) |
Via espflash — see below |
Delivered in slices 1.0 → 1.5 (tags v0.1.0–v0.1.5), each independently shippable.
Why is write/erase gated on backup? Before any flash or erase operation, chipforge automatically reads the current flash MD5 and either reuses a matching backup in ~/.chipforge/backups/ or creates a fresh verified backup. Pass --i-have-backup to skip the gate (you receive a warning). This is a hard policy, not a soft warning.
Reading ESP8266 flash requires uploading a small stub loader to RAM first — the ROM bootloader has no flash-read command. chipforge offers two stubs; both run entirely in RAM and speak the same host protocol, so usage is identical.
| Stub | Feature flag | License of that build | Source |
|---|---|---|---|
| Own MIT stub (recommended) | --features stub-own |
MIT OR Apache-2.0 | chipforge-esp-stub — from-scratch C (Xtensa LX106), in this repo |
| Legacy GPL stub | --features stub-gpl |
GPL-2.0-or-later | chipforge-esp-stub-gpl — derived from Espressif's stub |
The own MIT stub is written from scratch and is hardware-validated: on a real NodeMCU V3 its full 4 MB backup is byte-identical (same MD5) to the GPL/Espressif stub's backup. Use it to keep your whole build permissively licensed:
cargo build -p chipforge-cli --release --features stub-own
The legacy GPL stub lives in the separate crate chipforge-esp-stub-gpl (GPL-2.0-or-later), which is not a default workspace member. Enabling --features stub-gpl makes that build GPL-2.0-or-later:
cargo build -p chipforge-cli --release --features stub-gpl
The default build (no stub feature) stays MIT OR Apache-2.0 and can identify chips and inspect/diff images offline, but cannot read flash. Building the stub blob from source needs the xtensa-lx106 toolchain; the prebuilt blob is checked in, so building chipforge itself does not require it. See docs/superpowers/specs/2026-06-26-chipforge-1.3-own-stub-design.md for the stub's design and the four ESP8266 ROM-loader gotchas its bring-up uncovered.
Usage once built with a stub (identical for stub-own and stub-gpl):
# Show flash size and JEDEC id (requires stub)
chipforge -p <PORT> --stub info
# Full flash backup — dual MD5 verified (device MD5 + local MD5), .json sidecar written
chipforge -p <PORT> --stub backup
chipforge -p <PORT> --stub backup -o my-backup.bin
# Dump a specific flash region
chipforge -p <PORT> --stub dump --addr 0x0 --size 0x10000 -o region.bin
flash and erase require --stub (build with --features stub-own or --features stub-gpl). Before any write or erase, chipforge runs the auto backup gate: it reads the current flash MD5, then either reuses a matching backup already in ~/.chipforge/backups/ or makes a fresh verified backup. Only after the gate passes does the write or erase proceed. Pass --i-have-backup to skip the gate — you receive a prominent warning.
# Write firmware (deflate-compressed by default, post-write MD5 verified, backup-gated)
chipforge -p <PORT> --stub flash --addr 0x0 firmware.bin
# Write without compression, then reboot
chipforge -p <PORT> --stub flash --addr 0x0 fw.bin --no-compress --reboot
# Erase whole chip (backup-gated)
chipforge -p <PORT> --stub erase
# Erase a 4 KB-aligned region (backup-gated)
chipforge -p <PORT> --stub erase --region 0x3fc000:0x4000
# Verify a flash region against a file (no gate — read-only)
chipforge -p <PORT> --stub verify --addr 0x0 firmware.bin
chipforge 1.4 adds an optional second backend for the ESP32 family via the espflash library (MIT OR Apache-2.0). It is off by default — the default build is unchanged and remains MIT OR Apache-2.0 with no extra dependencies.
Supported chips: ESP32, ESP32-S2, ESP32-S3, ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-C61, ESP32-H2, ESP32-P4.
Build with espflash backend:
cargo build -p chipforge-cli --release --features backend-espflash
Select the backend at runtime:
chipforge --backend espflash -p <PORT> info
chipforge --backend espflash -p <PORT> backup
chipforge --backend espflash -p <PORT> dump --addr 0x0 --size 0x10000 -o region.bin
chipforge --backend espflash -p <PORT> flash --addr 0x0 firmware.bin
chipforge --backend espflash -p <PORT> erase
chipforge --backend espflash -p <PORT> verify --addr 0x0 firmware.bin
Key notes:
- The ESP8266 is not supported by espflash and stays on the default
--backend nativepath. --backend espflashis incompatible with--sim(the simulator targets the ESP8266 native protocol only).- The espflash library is MIT OR Apache-2.0; enabling
--features backend-espflashdoes not change chipforge's own license. - Flag behavior on this backend:
flash --no-compressandflash --rebootare not honored by the espflash backend — espflash manages compression internally and performs a hard reset after its operations. Those flags apply to the native backend only. - Validation caveat: the espflash backend is validated against real ESP32 hardware only. chipforge's built-in simulator exercises the ESP8266 native protocol and does not exercise the espflash code path. If you do not have an ESP32 device, use
--backend native(ESP8266) or treat the espflash backend as untested in your environment.
Prerequisites: Rust toolchain (stable, 1.88+ — edition 2024 + let-chains).
cargo build --release
The binary is at target/release/chipforge. No extra dependencies are required on Linux or Windows; the serialport crate bundles what it needs.
chipforge's own stub crate chipforge-esp-stub is MIT OR Apache-2.0, so a --features stub-own build — including full flash read/backup/dump — is entirely permissively licensed. The GPL-licensed Espressif stub is isolated in the separate, optional, default-off crate chipforge-esp-stub-gpl; it is only linked if you opt in with --features stub-gpl, which makes that build GPL. All other workspace crates (chipforge-core, chipforge-esp, chipforge-cli, chipforge-esp-stub, chipforge-espflash) are MIT OR Apache-2.0. See the "Stub options" subsection above for details.
List ports and detect converters:
chipforge ports
chipforge ports --json
Identify connected chip (put the board in download mode first — see below):
chipforge -p /dev/ttyUSB0 info # Linux
chipforge -p COM6 info # Windows
chipforge -p /dev/ttyUSB0 info --json
Parse a firmware image header (no board needed):
chipforge image-info firmware.bin
Diff two binary dumps (no board needed):
chipforge diff before.bin after.bin
- Windows: ports appear as
COMx(e.g.COM6). Install the CH340 driver from WCH if Windows doesn't recognise the board. - Linux: ports are typically
/dev/ttyUSB0. Add your user to thedialoutgroup (sudo usermod -aG dialout $USER) and log out/in. - WSL2: WSL2 cannot see USB serial devices directly. Either use
usbipd-winto forward the COM port into WSL2, or build and run the Windows binary natively against the COM port — no usbipd required.
| Variable | Equivalent flag | Example |
|---|---|---|
CHIPFORGE_PORT |
-p / --port |
/dev/ttyUSB0 or COM6 |
CHIPFORGE_BAUD |
-b / --baud |
115200 |
CHIPFORGE_BACKEND |
--backend |
native or espflash (via --features backend-espflash opt-in) |
| Flag | Default | Description |
|---|---|---|
-p / --port |
auto-detect | Serial port |
-b / --baud |
115200 |
Initial baud rate |
--backend native|espflash |
native |
Protocol backend; native always available, espflash via --features backend-espflash opt-in |
--json |
off | Emit machine-readable JSON |
-v / --verbose |
off | Increase log verbosity (repeat for more) |
The NodeMCU V3 (LoLin) uses a CH340G USB-UART converter with DTR and RTS wired to GPIO0 and EN respectively. chipforge triggers download mode automatically via the "classic reset" sequence: RTS pulses EN low while DTR holds GPIO0 low, then both release.
Manual fallback (if auto-reset doesn't work):
- Hold the FLASH button (pulls GPIO0 low).
- Tap the RST button briefly (pulses EN).
- Release FLASH.
The board is now in ROM download mode. Run your chipforge command within a few seconds.
See docs/research/04-nodemcu-v3-hardware.md for the full hardware reference including boot strapping pins, CH340G wiring, and flash chip details.
- Writes are stub-only, post-write MD5-verified, and backup-gated. Flash write and erase require
--stub(opt-in GPL build). Before any write or erase, chipforge runs the auto backup gate. After every write, the written region is read back and MD5-verified against the source. - Backup-before-write gate: chipforge automatically reads the current flash MD5 and reuses a matching backup in
~/.chipforge/backups/or creates a fresh verified one before any write or erase. Pass--i-have-backupto skip with a warning. - Flash-size guard: write operations (1.2+) will refuse to write beyond the detected flash size.
- No silent failures: every protocol error surfaces as a typed
Errorvariant. chipforge never swallows a CRC mismatch or an unexpected response.
chipforge tui opens a full-screen terminal UI (built with ratatui) that lets you explore ports, connect to a chip, and run read/backup/dump actions — all without typing individual commands. It works on Windows consoles as well as Linux and macOS terminals.
Rendered from the actual TUI buffer (90×24): port + detected converter on the left, chip info and actions on the right, a live log and progress gauge below.
# Launch with auto-detected port
chipforge tui
# Specify a port explicitly
chipforge tui -p <PORT>
# Hardware-free exploration — runs the built-in ESP8266 simulator
chipforge tui --sim
# Use a stub for full flash-read support on a real ESP8266
chipforge tui -p <PORT> --stub
--stub is required for Backup and Dump on a real ESP8266 (the ROM has no flash-read command). Build with --features stub-own (MIT) or --features stub-gpl first — see the "Stub options" section above. --sim implies the native ESP8266 path and is incompatible with --backend espflash.
| Key | Action |
|---|---|
| ↑ / ↓ | Move selection up / down |
| Tab | Switch focus between Ports list and Actions menu |
| Enter | Execute the selected action |
| q or Esc | Quit |
| Action | Description |
|---|---|
| Connect / Info | Open the selected port in download mode and display chip info (kind, MAC, flash JEDEC id + size with --stub) |
| Backup | Run a full verified backup (backup-gated — auto MD5 check reuses a matching backup or creates a fresh one; requires --stub on a real ESP8266) |
| Dump 64 KB @ 0x0 | Dump the first 64 KB of flash to a file (requires --stub on a real ESP8266) |
- Busy during long operations: while a Backup or Dump is running the UI does not accept input. A live progress gauge and scrolling log are shown in-panel until the operation completes.
- Read/backup/dump only: the TUI does not expose erase or flash-write actions in 1.5. The first interactive surface is intentionally safe — destructive operations remain CLI-only for now.
- Serial monitor: deferred to a future increment.
- Windows consoles: the TUI renders correctly in Windows Terminal, cmd.exe, and PowerShell via crossterm's Windows console backend.
| Feature | esptool.py | espflash | chipforge 1.5 |
|---|---|---|---|
| ESP8266 support | yes | no | yes |
| ESP32 family support | yes | yes | yes (with --backend espflash) |
| Flash dump / backup | yes | yes | yes (with --stub) |
| Flash write / erase | yes | yes | yes (with --stub, backup-gated) |
| Chip identify (offline-safe reads) | yes | yes | yes |
| List ports + converter detect | yes | yes | yes |
| Offline image-info inspect | yes | partial | yes |
| Diff two dumps | no | no | yes |
| Pure Rust, no Python runtime | no | yes | yes |
| MIT / Apache-2.0 license | no (GPL-2) | Apache-2.0 | yes |
| ESP8266 flash read in a GPL-free build | no | n/a | yes (own MIT stub) |
| Safety-first backup gate | no | no | yes (1.2+) |
espflash's board-info / list-ports require the ESP32 family — it does not speak to ESP8266 at all. See docs/research/03-tooling-prior-art.md.
Licensed under either of:
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
- Apache License, Version 2.0 (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
at your option.
chipforge's own ESP8266 stub (chipforge-esp-stub) is MIT OR Apache-2.0 like the rest of the project, so flash read/backup/dump are available in a fully permissive --features stub-own build.
The optional alternative stub loader crate chipforge-esp-stub-gpl, which incorporates GPL-licensed Espressif stub code, is a separate crate that is not a default workspace member and not linked unless you opt in with --features stub-gpl. Enabling that feature makes that build GPL-2.0-or-later; the default and stub-own builds stay MIT OR Apache-2.0.
- docs/research/01-esp-rom-protocol.md — SLIP framing and ROM bootloader protocol
- docs/research/02-usb-uart-converters.md — CH340, CP210x, FT232R, and auto-reset wiring
- docs/research/03-tooling-prior-art.md — esptool.py, espflash, and prior-art flashers
- docs/research/04-nodemcu-v3-hardware.md — NodeMCU V3 hardware reference
- docs/design/architecture.md — crate graph and trait seams
- docs/superpowers/specs/2026-06-26-chipforge-1.3-own-stub-design.md — own MIT ESP8266 stub: design, ROM bring-up, and the four root-cause gotchas
- docs/design/adding-a-chip.md — how to add a new chip family
- docs/design/adding-a-converter.md — how to add a USB-UART converter