PM_K-1: add firmware-protect helper (hide files so users only see editor + programs)
protect-firmware.sh sets the FAT hidden attribute on the firmware files (code.py, boot.py, font_*.bin, README) on a mounted CIRCUITPY drive, so an end user sees only editor.html + programs.json and can't accidentally delete the program — the hidden files keep running and Save to device still works. Documented in pico-cp/README (incl. the read-only boot.py hard-lock alternative) and bundled into pm_k1_circuitpy.zip. README.md verified accurate. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4ceb80b4f4
commit
09b20a9e69
3 changed files with 43 additions and 1 deletions
3
build.sh
3
build.sh
|
|
@ -39,7 +39,8 @@ pathlib.Path("dist/pico-main.py").write_text(pathlib.Path("pico/main.py").read_t
|
||||||
print("copied pico-main.py")
|
print("copied pico-main.py")
|
||||||
import zipfile # PM_K-1 CircuitPython drive bundle (download → unzip onto CIRCUITPY)
|
import zipfile # PM_K-1 CircuitPython drive bundle (download → unzip onto CIRCUITPY)
|
||||||
with zipfile.ZipFile("dist/pm_k1_circuitpy.zip", "w", zipfile.ZIP_DEFLATED) as z:
|
with zipfile.ZipFile("dist/pm_k1_circuitpy.zip", "w", zipfile.ZIP_DEFLATED) as z:
|
||||||
for f in ("code.py", "boot.py", "programs.json", "font_s.bin", "font_m.bin", "font_l.bin", "README.md"):
|
for f in ("code.py", "boot.py", "programs.json", "font_s.bin", "font_m.bin", "font_l.bin",
|
||||||
|
"README.md", "protect-firmware.sh"):
|
||||||
z.write("pico-cp/" + f, f)
|
z.write("pico-cp/" + f, f)
|
||||||
z.write("dist/editor.html", "editor.html") # offline copy of the editor, on the drive
|
z.write("dist/editor.html", "editor.html") # offline copy of the editor, on the drive
|
||||||
print("zipped pm_k1_circuitpy.zip")
|
print("zipped pm_k1_circuitpy.zip")
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,21 @@ If the editor says **no MIDI input is connected**, copy **`boot.py`** onto `CIRC
|
||||||
**power-cycle** the Pico (`boot.py` only runs on a full reset). It frees a USB endpoint (drops the
|
**power-cycle** the Pico (`boot.py` only runs on a full reset). It frees a USB endpoint (drops the
|
||||||
unused HID interface) so the MIDI port is guaranteed to appear alongside the drive.
|
unused HID interface) so the MIDI port is guaranteed to appear alongside the drive.
|
||||||
|
|
||||||
|
## Protect the firmware (so end users only see the editor + their tracks)
|
||||||
|
|
||||||
|
To stop someone accidentally deleting the firmware, **hide it** — the files keep running and
|
||||||
|
"Save to device" still works, but only `editor.html` + `programs.json` show in the file browser.
|
||||||
|
On the host, with the drive mounted, run the included helper (needs `fatattr`):
|
||||||
|
|
||||||
|
```
|
||||||
|
./protect-firmware.sh /media/$USER/CIRCUITPY # hides code.py, boot.py, font_*.bin, README, itself
|
||||||
|
```
|
||||||
|
|
||||||
|
(Reveal again with `fatattr -h <file>`.) For a **hard lock** — nothing on the drive can be changed
|
||||||
|
from the computer at all — put `storage.remount("/", readonly=True)` in `boot.py`; but then the
|
||||||
|
editor's *Save to device* can't write either, so you'd reprogram by temporarily removing that line
|
||||||
|
(or gating it behind a held button at power-on). Hiding is usually the right balance.
|
||||||
|
|
||||||
## Controls (same as the MicroPython build)
|
## Controls (same as the MicroPython build)
|
||||||
|
|
||||||
- **Touch:** on‑screen `◀◀ / ▶ / ▶▶` (prev · play/stop · next) and `− / TAP / +`.
|
- **Touch:** on‑screen `◀◀ / ▶ / ▶▶` (prev · play/stop · next) and `− / TAP / +`.
|
||||||
|
|
|
||||||
26
pico-cp/protect-firmware.sh
Executable file
26
pico-cp/protect-firmware.sh
Executable file
|
|
@ -0,0 +1,26 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Hide the PM_K-1 firmware files on a CIRCUITPY drive so an end user only sees
|
||||||
|
# editor.html + programs.json — the two files they're meant to touch. The hidden
|
||||||
|
# files keep running, and the editor's "Save to device" still works (programs.json
|
||||||
|
# stays writable). This just prevents *accidental* deletion of the firmware.
|
||||||
|
#
|
||||||
|
# Run it on the HOST, pointing at the mounted drive:
|
||||||
|
# ./protect-firmware.sh /media/$USER/CIRCUITPY
|
||||||
|
# (defaults to the current directory if run from inside the drive). Needs `fatattr`
|
||||||
|
# (sudo apt install fatattr) — or use the mtools fallback printed below.
|
||||||
|
#
|
||||||
|
# To reveal them again: fatattr -h <file>
|
||||||
|
set -euo pipefail
|
||||||
|
DIR="${1:-.}"
|
||||||
|
HIDE=(code.py boot.py font_s.bin font_m.bin font_l.bin README.md protect-firmware.sh boot_out.txt)
|
||||||
|
|
||||||
|
if command -v fatattr >/dev/null 2>&1; then
|
||||||
|
for f in "${HIDE[@]}"; do
|
||||||
|
if [ -e "$DIR/$f" ]; then fatattr +h "$DIR/$f" && echo "hidden: $f"; fi
|
||||||
|
done
|
||||||
|
echo "Done — the drive now shows only editor.html + programs.json."
|
||||||
|
else
|
||||||
|
echo "fatattr not found. Install it: sudo apt install fatattr (or dnf/pacman equivalent)"
|
||||||
|
echo "Or, with mtools, run e.g.: mattrib -i /dev/sdX1 +h ::code.py ::boot.py ::font_*.bin"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
Loading…
Reference in a new issue