[Bug] Inappropriate content policy block on firmware analysis task
Bug Description
I am working on understanding the firmware to my personal, owned music keyboard. Fable is triggering a block which does not seem appropriate for the actions I'm taking, creating educational piano playing software.
Environment Info
- Platform: darwin
- Terminal: ghostty
- Version: 2.1.231
- Feedback ID: 5d322d80-0584-41ff-93de-801d0a737263
---
Plan Fable blocked on:
Plan: Extract & analyze the MK3 renderer software (avenue 4)
Purpose & scope
Interoperability research on the operator's own hardware: understand how the
MK3's on-device renderer accepts screen content so this project's own host-side
software can drive the operator's keyboard screen through supported paths. This
is read-only inspection of software the operator already owns and installed, and
performs no writes to the device (see Hard boundary).
Context
MK3_VIDEO_RESEARCH.md avenue 4 wants to statically analyze the MK3 keyboard's
system image to find a supported (documented or not-yet-documented) host-to-renderer
interface for driving the screen (ideally something richer than the proven
8-knob / animated-WebP paths).
The 2026-08-13 handoff briefing named the blocker plainly: "No firmware image
exists anywhere on this machine" and "No prior work has identified the MK3's
display/main controller chip."
Both are now resolved by inspecting /Users/skylershaw/Downloads/KSMK3Updater.app
(the "latest firmware download"). Read-only findings this session:
Contents/Resources/payload(396 MB) is the device image: a Linux
ext4 filesystem, volume "rootfs". The MK3 runs embedded Linux. This is the
image the handoff said didn't exist.
- SoC identified:
stm32mp157a-ni-kks-mk3.dtb→ STM32MP157A (Cortex-A7
armv7 + Cortex-M4), integrated DRM/KMS display controller (STM32 LTDC).
- Display stack:
/dev/dri/card0,/dev/fb0, Wayland + DRM + EGL + GBM. - On-device renderer:
/usr/bin/ni-roda, launched byni-roda.service— the
device end of the ODR protocol this project already drives from the host.
armv7, built with some debug source paths under renderer/komplete_kontrol_common/.
- Image codecs: libpng, libjpeg, libwebp + libwebpdemux + libwebpmux
(animated WebP). No ffmpeg/avcodec → no general video codec on device;
animated WebP is the richest bitmap primitive present.
- Updater
KSMK3Updateris a Qt app (bundle version 4.2.0). Its update-write
mechanism is out of scope: static analysis only, no writes to the device.
Goal of executing this plan: cleanly extract the rootfs read-only, then study/usr/bin/ni-roda to catalog the ODR messages it accepts and see which
screen-update paths it supports (the documented parameter model, WebP assets,
or anything else reaching /dev/fb0 or a DRM plane).
Hard boundary (unchanged from the research doc)
Static analysis only. No firmware writes, no DFU/reboot, no device contact of any
kind under this plan. Nothing here touches the real MK3, so no per-experiment
operator confirmation is needed for the extraction/analysis steps themselves. A
firmware modification remains a separate decision the operator makes on its own.
Approach
1. Extract the rootfs read-only (no kernel mount)
macOS can't mount ext4 and has no ext4 tooling installed. Use debugfs from
e2fsprogs — a userspace, read-only reader, no mount, no macFUSE kext:
brew install e2fsprogs # provides debugfs (keg-only, not symlinked)
DEBUGFS=/opt/homebrew/opt/e2fsprogs/sbin/debugfs # or /usr/local/... on Intel
PAYLOAD="/Users/skylershaw/Downloads/KSMK3Updater.app/Contents/Resources/payload"
"$DEBUGFS" -R "ls -l /" "$PAYLOAD" # sanity check
"$DEBUGFS" -R "rdump / <destdir>" "$PAYLOAD" # full read-only extract
Extract to the scratchpad or a working dir under the repo's ignored paths — do
not commit 396 MB of image. debugfs rdump preserves the tree without ever
mounting or writing the image. (Fallback if rdump misbehaves on symlinks:fuse-ext2 -o ro via macFUSE, or 7z x which reads ext4 — but prefer debugfs.)
2. Recon the extracted tree
usr/lib/systemd/system/ni-roda.service+98-ni-roda-support.preset— how the
renderer starts, its args, environment, socket/device it opens, dependencies.
boot/dtb (stm32mp157a-ni-kks-mk3.dtb) — confirm LTDC display node, panel
timings, the 1280x480 config, any second display/overlay planes.
etc/os-release, build manifest, package list — confirm exact image version and
the Yocto/BSP it came from (source-path strings say 1.0-r0/git, a Yocto recipe).
- Any Wayland compositor unit (weston/custom) and its config — decides whether
ni-roda draws to a compositor surface or straight to KMS//dev/fb0.
3. Analyze /usr/bin/ni-roda (the core work)
This binary is the device-side counterpart to NIHardwareConnectionService's ODR
client already mapped in avenue 4. Load into Ghidra as ARM v7 little-endian.
Reuse the avenue-4 field-name trick where applicable; the payoff here is the
message-dispatch table:
- Catalog the ODR messages it accepts (mirror of the host's
client_parameter_page_*, client_mixer_set_meters, client_plugin_chain_*,
display/model RPCs). Note any message not present in the public symbol
registry, i.e. a supported message that simply isn't documented yet.
- Follow how each message updates the screen: calls into libwebp/libpng/libjpeg,
EGL/GLES draw calls, GBM/DRM plane commits, or writes to /dev/fb0.
- Specifically confirm/deny a full-image screen-update path: does any host message
update the display as a whole image rather than through the parameter/asset
model? Check the animated-WebP path (libwebpdemux) end to end — how a WebP
asset is fed, decoded, and presented, and whether the host controls frame timing
or just hands over a file.
- Check
client_mixer_set_meters(avenue 4's one untested lead) on the device
side to see its real widget/count ceiling without needing a DAW session.
4. Cross-reference & write up
Fold results back into MK3_VIDEO_RESEARCH.md avenue 4: correct the "no image
exists" / "chip unidentified" statements, record the STM32MP157A + Linux/Wayland
architecture, and document any new primitive (or a definitive negative: "the only
host-reachable screen-update paths are X, Y, Z"). Keep the extracted image out of git.
Critical files / artifacts
- Source image:
~/Downloads/KSMK3Updater.app/Contents/Resources/payload(ext4, read-only). - Primary target: extracted
usr/bin/ni-roda(armv7). - Supporting:
ni-roda.service, the.dtb, os-release/manifest, Wayland unit. - Write-up target:
MK3_VIDEO_RESEARCH.mdsection 4.
Verification
- Extraction:
debugfs -R "ls /" payloadlists a normal Linux root
(bin etc lib usr ...); file usr/bin/ni-roda reports an ARM EABI ELF; extracted
tree size ≈ image content. No mount appears in mount/diskutil list (proves
read-only, no kernel involvement).
- Analysis: produce a concrete list of the ODR messages ni-roda accepts and, for
each, its screen-update sink (webp/gl/drm/fb). Success = either a named
not-yet-documented host-reachable path, or an evidence-backed statement that none
exists beyond the already-known parameter-model + WebP-asset paths.
Notes / open decisions
- Requires
brew install e2fsprogs(read-only tool, no device contact) and Ghidra
for step 3. If either is unavailable, strings/nm/objdump on the extracted
ni-roda still yields the message vocabulary, just without full Ghidra analysis.
- Scope this round can stop after step 2 (extract + recon + confirm architecture)
if a full Ghidra pass isn't wanted yet; steps 3–4 are the deep dive.