nander-rs 0.5.0

Modern SPI NAND/NOR Flash programmer for CH341A with cross-platform GUI and comprehensive diagnostics
Documentation

nander-rs

๐Ÿฆ€ A modern SPI NAND/NOR Flash programmer written in Rust

A complete rewrite of SNANDer in Rust, designed for maximum portability and reliability.

โœจ Features

  • Pure Rust USB - Uses nusb for native USB communication, no libusb DLL required
  • Cross-platform - Works on Windows, Linux, and macOS
  • Single binary - No runtime dependencies, just one executable
  • Memory safe - Rust's ownership system prevents buffer overflows and memory corruption
  • Rich CLI - Modern command-line interface with progress bars and clear error messages
  • Cross-platform GUI - Intuitive graphical interface for interactive flash operations
  • Extensible - Trait-based architecture makes it easy to add new programmers or chips

๐Ÿ›  Supported Hardware

Programmers

  • CH341A - The ubiquitous USB-SPI programmer (fully supported)
  • More programmers can be added by implementing the Programmer trait

Flash Types

  • SPI NAND - Full support including OOB/spare area and bad block management
  • SPI NOR - Standard JEDEC SPI NOR flash

Chips

See src/database/chips.rs for the full list. Common chips include:

  • GigaDevice: GD5F1GQ5UEYIG, GD25Q128C, etc.
  • Winbond: W25N01GV, W25Q128JV, etc.
  • Macronix: MX35LF1GE4AB, MX25L12833F, etc.
  • Micron: MT29F1G01, etc.
  • XTX, FORESEE, and more...

๐Ÿ“ฆ Installation

From Source

cargo install --path .

Pre-built Binaries

Download from the Releases page.

๐Ÿš€ Usage

Launch Graphical User Interface

nander gui

Detect Flash Chip (CLI)

nander info

Output includes JEDEC ID, chip details, and for NAND chips, ECC status.

List Supported Chips

nander list

Read Flash to File

nander read -o backup.bin

nander read -o partial.bin -l 0x100000 -s 0x0   # Read 1MB from start

nander read -o raw.bin -d                        # Raw read with ECC disabled (NAND)

Write File to Flash

nander write -i firmware.bin

nander write -i firmware.bin --no-verify   # Skip verification

nander write -i raw.bin -d                 # Raw write with ECC disabled (NAND)

Erase Flash

nander erase                    # Erase entire chip

nander erase -l 0x200000        # Erase first 2MB

Verify Flash

nander verify -i firmware.bin

ECC Control (NAND only)

The -d / --no-ecc flag disables internal ECC for raw operations:

  • Reads full page data including ECC bytes
  • Useful for complete flash dumps including OOB area
  • Required for external ECC software processing

๐Ÿ”ง Development

Building

cargo build --release

Running Tests

cargo test

Linting

cargo clippy -- -D warnings

๐Ÿ“ Architecture

ๆœฌ้กน็›ฎ้‡‡็”จๅˆ†ๅฑ‚ๆžถๆž„๏ผŒๆญฃๅœจไปŽ้—็•™ๅ•ไฝ“็ป“ๆž„่ฟ็งปๅˆฐๆ–ฐๆžถๆž„๏ผš

nander-rs/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ main.rs              # CLI ๅ…ฅๅฃ็‚น
โ”‚   โ”œโ”€โ”€ lib.rs               # ๅบ“ๅฏผๅ‡บ
โ”‚   โ”œโ”€โ”€ error.rs             # ๅ…จๅฑ€้”™่ฏฏ็ฑปๅž‹
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ domain/              # ๐Ÿ’Ž ้ข†ๅŸŸๅฑ‚ - ๆ ธๅฟƒไธšๅŠก้€ป่พ‘
โ”‚   โ”‚   โ”œโ”€โ”€ types.rs         # ๆ ธๅฟƒ็ฑปๅž‹ (Capacity, Address, JedecId ็ญ‰)
โ”‚   โ”‚   โ”œโ”€โ”€ chip.rs          # ่Šฏ็‰‡่ง„ๆ ผๆจกๅž‹
โ”‚   โ”‚   โ”œโ”€โ”€ flash_operation.rs # Flash ๆ“ไฝœๆŠฝ่ฑกๆŽฅๅฃ
โ”‚   โ”‚   โ”œโ”€โ”€ bad_block.rs     # ๅๅ—็ฎก็†็ญ–็•ฅ
โ”‚   โ”‚   โ””โ”€โ”€ ecc.rs           # ECC ๆŽงๅˆถ็ญ–็•ฅ
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ application/         # ๐Ÿ“ฆ ๅบ”็”จๅฑ‚ - ็”จไพ‹็ผ–ๆŽ’
โ”‚   โ”‚   โ”œโ”€โ”€ use_cases/       # ๅ…ทไฝ“ไธšๅŠก็”จไพ‹ (ๅพ…่ฟ็งป)
โ”‚   โ”‚   โ””โ”€โ”€ services/        # ๅบ”็”จๆœๅŠก (ๅพ…่ฟ็งป)
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ infrastructure/      # ๐Ÿ”ง ๅŸบ็ก€่ฎพๆ–ฝๅฑ‚ - ๆŠ€ๆœฏๅฎž็Žฐ
โ”‚   โ”‚   โ”œโ”€โ”€ programmer/      # ็กฌไปถ็ผ–็จ‹ๅ™จ้ฉฑๅŠจ
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ ch341a/      # CH341A USB ้ฉฑๅŠจ
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ traits.rs    # Programmer trait ๅฎšไน‰
โ”‚   โ”‚   โ”œโ”€โ”€ flash_protocol/  # Flash ๅ่ฎฎๅฎž็Žฐ
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ nand/        # SPI NAND ๅ่ฎฎ
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ nor/         # SPI NOR ๅ่ฎฎ
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ commands.rs  # SPI ๅ‘ฝไปคๅธธ้‡
โ”‚   โ”‚   โ””โ”€โ”€ chip_database/   # ่Šฏ็‰‡ๆ•ฐๆฎๅบ“
โ”‚   โ”‚       โ”œโ”€โ”€ nand/        # NAND ่Šฏ็‰‡ๅฎšไน‰ (ๆŒ‰ๅˆถ้€ ๅ•†)
โ”‚   โ”‚       โ””โ”€โ”€ nor/         # NOR ่Šฏ็‰‡ๅฎšไน‰ (ๆŒ‰ๅˆถ้€ ๅ•†)
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ presentation/        # ๐Ÿ–ฅ๏ธ ่กจ็Žฐๅฑ‚ - ็”จๆˆทไบคไบ’
โ”‚   โ”‚   โ””โ”€โ”€ cli/             # CLI ๅฎž็Žฐ (ๅพ…่ฟ็งป)
โ”‚   โ”‚       โ””โ”€โ”€ handlers/    # ๅ‘ฝไปคๅค„็†ๅ™จ
โ”‚   โ”‚
โ”‚   โ””โ”€โ”€ [Legacy Modules]     # ้—็•™ๆจกๅ— (้€ๆญฅๆท˜ๆฑฐ)
โ”‚       โ”œโ”€โ”€ cli/             # ๅฝ“ๅ‰ CLI ๅฎž็Žฐ
โ”‚       โ”œโ”€โ”€ database/        # ๅฝ“ๅ‰่Šฏ็‰‡ๆ•ฐๆฎๅบ“
โ”‚       โ”œโ”€โ”€ flash/           # ๅฝ“ๅ‰ Flash ๅ่ฎฎ
โ”‚       โ””โ”€โ”€ hardware/        # ๅฝ“ๅ‰็กฌไปถ้ฉฑๅŠจ

่ฏฆ่ง ARCHITECTURE.md ไบ†่งฃๅฎŒๆ•ดๆžถๆž„่ฎพ่ฎกใ€‚

๐Ÿ“ Adding New Chips

Edit src/database/chips.rs and add your chip:

ChipInfo::nand(
    "YOUR_CHIP_NAME",
    "Manufacturer",
    [0xXX, 0xYY, 0xZZ],  // JEDEC ID
    CAPACITY_BYTES,
    PAGE_SIZE,
    OOB_SIZE,
    BLOCK_SIZE,
),

Run nander info to see the JEDEC ID of your chip.

๐Ÿ”— Related Projects

๐Ÿ“„ License

Licensed under either of:

at your option.

Note: This is a clean-room implementation. While inspired by SNANDer's functionality and interface design, nander-rs contains no GPL-licensed code. All code was written from scratch in Rust.

๐Ÿ™ Acknowledgments

  • SNANDer by McMCC - The original C implementation that inspired this project's feature set and CLI design. SNANDer is GPL-licensed; nander-rs is an independent reimplementation.
  • The OpenIPC community for testing and feedback
  • The Rust embedded community for excellent libraries (nusb, clap, indicatif, etc.)
  • JEDEC and flash chip manufacturers for public documentation