Projects / OpenBoot
OpenBoot
An 8 KiB IAP bootloader for WCH RISC-V microcontrollers — one protocol over USB HID or UART, and A/B updates a power cut can’t turn into a brick.
8 KiB of flash
The bootloader lives in the bottom 8 KiB and hands the entire rest of flash to the application.
A/B slots
Updates are written into the slot the device is not running, so a power cut mid-update leaves the working application untouched.
One protocol, two transports
The same OBP frames run over USB HID or UART, so a board can be updated through whichever pin or port it exposes.
Cross-platform CLI
A Rust host tool for Linux, macOS, and Windows that learns each device’s flash geometry from the wire.
What is OpenBoot?
OpenBoot is an in-application-programming bootloader: it occupies the bottom 8 KiB of flash, and splits everything above it into two equally sized A/B slots. An application is linked for one slot base, and updates are written into the other one. That is what makes an update survivable — the image being replaced is never the image currently keeping the device alive.
It is the bootloader OpenController runs under, which is what lets a keyboard take a firmware update over its own UART instead of a debug probe.
Why an update can’t brick the device
Four rules do the work, and they hold regardless of what the host sends:
- Protocol requests cannot modify the bootloader itself.
- A block must be erased before it can be written.
- An image becomes bootable only after COMMIT verifies its CRC.
- Updates land in the slot the device is not running, so power loss part-way through leaves the previous application intact and the device comes back up on it unaided.
Supported chips
Each chip and transport combination produces a separate bootloader image. The device reports its own flash geometry, slot layout, and identity when the host connects, so the flashing tool needs no per-chip database.
| Chip | App region | RAM | Transports |
|---|---|---|---|
| CH570 / CH572 | [0x2000, 0x3C000) | 12 KiB | USBUART |
| CH591 | [0x2000, 0x30000) | 26 KiB | USBUART |
| CH592 | [0x2000, 0x70000) | 26 KiB | USBUART |
The protocol
OBP is specified normatively enough that a third-party client can be written from the document alone. Every frame fits in 64 bytes — one USB HID report — and carries a CRC-32 over its own header and payload. The exchange is strict ping-pong, and the golden frame vectors in the repository are themselves normative: an implementation that can’t round-trip them is wrong.
The host tool
openboot is a Rust CLI that runs on Linux, macOS, and Windows. Probing is read-only by default, and flash and erase print a plan rather than acting unless you pass --force. It also handles bundles that carry both slot builds at once, picking the right one for the slot the device isn’t running.
Repository layout
protocol/Shared protocol constants and golden frames.firmware/Bootloader, ports, transports, boards, and tests.tools/The openboot host CLI.docs/Protocol, architecture, and A/B update design.third_party/Pinned WCH SDK submodules.
Licensing
OpenBoot is released under the Apache License 2.0. The pinned WCH SDK submodules under third_party/ remain under their own upstream terms.