[Bug] Inappropriate content policy block on firmware analysis task

Status Open
Reported on v2.1.231
Maintainer reply None cached
Activity 0 comments · opened Aug 13, 2026

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.dtbSTM32MP157A (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 by ni-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 KSMK3Updater is 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.md section 4.

Verification

  • Extraction: debugfs -R "ls /" payload lists 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.

View original on GitHub ↗