Skip to content

feat(tools): add a Mac-side UBOOT rescue for a crash-looping BlackBox - #14

Merged
isod89 merged 4 commits into
isod89:mainfrom
VinSpee:fm/openpocket-upstream-uboot-rescue-tool
Nov 8, 2026
Merged

isod89 merged 4 commits into
isod89:mainfrom
VinSpee:fm/openpocket-upstream-uboot-rescue-tool

Conversation

@VinSpee

@VinSpee VinSpee commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

This adds a Mac-side rescue for a pedal that is stuck crash-looping, such as after a bad test image, without SD-card hardware. Between crashes the pedal sits in the JieLi mask-ROM USB boot state (WL80UBOOT1.00), and tools/uboot_rescue.py speaks its USB protocol through libusb to restore the official firmware from the official package.

It is run as node tools/op.mjs rescue, make rescue or make rescue-write. It is read-only by default and writes only with --write, only inside the app area, with a verified read-back of each sector; it never erases the chip or burns a key. op.mjs doctor checks and explains the libusb and sudo prerequisites. docs/RESCUE.md documents the procedure and the recorded real run, the README Install section lists the Mac route before the SD-card route, the installer page gains a hint, and the openpocket-rescue skill lists the safety rules.

The protocol, guards and resume behaviour are tested on host against a simulated pedal (tests/uboot_sim.py, tests/test_uboot_rescue.py), and the full host suite passes. It was proven on a real crash-looping BlackBox, which it restored.

…ckBox

tools/uboot_rescue.py waits for the pedal in its JieLi mask-ROM USB boot state (4C4A:8057),
loads the pinned wl82loader.bin into RAM, backs up the whole flash, checks the head against
the official package and, only with --write, rewrites the differing 4 KiB sectors in
[0x4000, end of image) with read-back. It is read-only by default, whitelists the loader
commands (no chip erase, no key burn), refuses a wrong chip key or flash size, and resumes
on rerun. libusb is called through ctypes; no pip packages.

Tested against a simulated UBOOT pedal (make rescue-check, part of make test); the protocol
has not yet been run on the real pedal beyond finding it and reading its descriptor.
…ake rescue, make rescue-write)

node tools/op.mjs rescue [--write] runs tools/uboot_rescue.py through sudo, read-only unless
--write; make rescue and make rescue-write call it. op.mjs doctor now reports the rescue
prerequisites (libusb, official package, cached loader, root) through uboot_rescue.py --check.

docs/RESCUE.md records what the captain's first real run left behind (two identical pre-write
backups: BlackBox_936, head matching, 159 of 160 sectors differing) and marks the rest unknown.
The installer page and the README point a looping pedal at the Mac route first and the SD-card
route second. A new project skill, openpocket-rescue, tells an agent when and how to rescue,
the safety rules and who runs the sudo write. tests/test_op.mjs covers the op.mjs and Makefile
wiring and the doctor call; test_uboot_rescue.py covers --check.
@isod89
isod89 merged commit 8a6c625 into isod89:main Nov 8, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants