Skip to content

fix(device): route developer input through SDL console - #588

Merged
boburning merged 1 commit into
mainfrom
fix/device-input-injection
Aug 30, 2026
Merged

boburning merged 1 commit into
mainfrom
fix/device-input-injection

Conversation

@boburning

@boburning boburning commented Aug 30, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • add an explicit sendkeys --sdl mode for developer automation against Bloom Shell's actual SDL console input path
  • require the regular no-symlink /mnt/SDCARD/.bloom-dev marker before console injection
  • require the exact /dev/tty2 character device and open it no-follow, close-on-exec, and without acquiring a controlling terminal
  • accept only numeric key codes 0-127 and press/release values in SDL mode, converting release to the kernel medium-raw high bit
  • preserve the inherited /dev/input/event0 behavior for existing non-Shell callers
  • replace permissive atoi parsing with bounded full-string parsing in both modes
  • scope future sendkeys changes to its owning ARM target, source directory, and Shell contract instead of unrelated native/visual work

Root cause

Read-only Mini Plus inspection showed the corrected Bloom Shell PID has /dev/tty2 open through SDL and no /dev/input/event0 descriptor. The physical GPIO keyboard is registered with both kbd and event0 handlers. The inherited helper writes the evdev node, but writing that node does not feed the already-open console keyboard path, so it returned success while Bloom Shell saw no START, D-pad, A, or B event.

The device kernel exposes no /dev/uinput, /dev/misc/uinput, uinput sysfs class, loaded module, or available module. The bounded console-injection mode therefore uses the same Linux medium-raw scan-code path that SDL reads, but only when explicitly requested in developer mode.

Host validation

  • GNU C18 -Wall -Wextra -Werror syntax compile: pass
  • clang-format 21.1.8: pass
  • focused cppcheck 2.19 warning/performance/portability gate: pass
  • sendkeys Shell contracts: 3/3 pass
  • complete CI-scope policy tests: pass
  • exact affected scope: ARM sendkeys, static src/sendkeys, no native/visual selector, focused sendkeys_contract.bats
  • git diff --check: pass

Device gate

  • signed hardware workflow: https://github.com/boburning/BloomOS/actions/runs/33330828779 (pass, 7m47s)
  • exact source/head: cd6ddfe00afd38ee7cd8700d74e03cd742d87f4a
  • signed release: BloomOS-v0.1.0-dev-cd6ddfe0.zip, 199,852,213 bytes, SHA-256 25e455a3ab4cf2bff35ecfa2f285c1f01e0422b96d9b64945198c9841fab0bc0
  • release manifest SHA-256: 603adc2432487c74e1db4ad92953467595518e01500a78078e352b49dca36a10; Ed25519 signature verified against the repository release public key
  • payload manifest SHA-256: 1dcbb004e50ec7af47e2a5589ea50cdb031ed2be31c72a73c30703291bc80fff; repository metadata/payload validator passed
  • packaged onion.pak: 87,968,260 bytes, SHA-256 8e5642441f6abdfcca904792197e624da14ab295deb71d7d9c6b85495699b38d, exactly matching the signed payload manifest
  • extracted candidate sendkeys: 18,084 bytes, SHA-256 572736c120a0ad08c2da02d3af3d9c2176297d97defd1b14f5a7ac23306282a1
  • strict pinned-host, key-only SSH transfer to fixed /tmp/bloom-sendkeys-cd6ddfe0; remote byte count and SHA-256 matched before execution
  • preflight required the update phase known_good, canonical session IDLE, network transaction idle with inactive recovery lease, associated Wi-Fi, clean listener audit, one Shell PID, and no pending Shell signal
  • one START press/release opened Quick Settings; a second START press/release returned to the PICO-8 root; privacy-safe framebuffer captures record before/open/closed states
  • the open capture showed Wi-Fi: On / Connected; the gate never selected or changed the Wi-Fi row
  • postflight retained Shell PID 3582, canonical session IDLE, associated Wi-Fi, and a clean listener audit with only reviewed key-only SSH
  • the fixed /tmp candidate was removed; installed sendkeys remained exactly 18,080 bytes with SHA-256 c244bff7f442a5e8e44b97b2db4a4b634d404ad116b45dfd80a2329b20098677 before and after

Safety and limitations

  • base: current main after docs(program): record NET-05 recovery evidence #587
  • no Wi-Fi radio/profile/credential, listener, key, route, update, reboot, save, ROM, BIOS, or installed-device mutation
  • no password or arbitrary path/command interface
  • legacy event0 behavior remains the default; console injection requires explicit --sdl
  • Mini Plus remote input/framebuffer evidence will not certify tactile controls, physical LCD, audio, gameplay, saves, Original Mini revisions, or Flip
  • TIOCSTI behavior is kernel-specific; this gate qualifies only the current Mini Plus kernel/runtime, not Original Mini revisions, Flip, or unrelated kernels

Related: #442, #544, #584, #585.

@boburning
boburning merged commit 629e8d5 into main Aug 30, 2026
7 checks 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.

1 participant