# Chatter — Phase 1 On-Device Findings **Date:** 2026-06-25 **Device:** reMarkable Paper Pro Move (RM03A, codename "Chiappa") **Method:** Read-only SSH probing from Jatke (`ssh chatter`). No changes made to the device except enabling developer mode / SSH (Phase 0) and adding our SSH key. This document records what we learned and the implementation decisions those findings support. It feeds the phase plan in [`Chatter_implementation.md`](Chatter_implementation.md). --- ## 1. Hardware & OS - **SoC / arch:** NXP **i.MX93**, **aarch64** (Arm Cortex-A55). Kernel `6.12.49+git-imx93-chiappa`. - **OS:** Codex Linux 5.7.121 (Yocto **scarthgap**), image `3.27.1.0`. glibc (`/lib/ld-linux-aarch64.so.1`, `libc.so.6`). - **RAM:** 2 GB (~1.4 GB free) — ample for our app. - **Storage (matters for deployment):** - `/` (rootfs): ~435 MB, **only ~88 MB free (78% used)** — also an OS-managed overlay, likely reset by firmware updates. **Do not install here.** - `/home`: **46 GB encrypted volume, ~45.8 GB free.** Install Chatter under `/home` (e.g. `/home/root/chatter`). ## 2. Input devices Pen and finger are **separate evdev devices** — finger-vs-stylus discrimination is free, exactly what Chatter's gesture design needs. | Node | Name | Role | Notes | |---|---|---|---| | `event0` | `bbnsm:pwrkey` | Power button | | | `event1` | Hall effect sensors | Folio open/close | switch events | | **`event2`** | **Elan marker input** | **Stylus / Marker** | on SPI | | **`event3`** | **Elan touch input** | **Capacitive multitouch (finger)** | `INPUT_PROP_DIRECT` | **Pen (`event2`)** — digitizer space **6760 × 11960**: - Buttons: `BTN_TOOL_PEN`, **`BTN_TOOL_RUBBER`** (Marker Plus eraser end — flip-to-erase is detectable), `BTN_TOUCH`, `BTN_STYLUS`, `BTN_STYLUS2`. - `ABS_PRESSURE` 0–4096, `ABS_DISTANCE` (hover) 0–65535, `ABS_TILT_X/Y` ±9000. **Touch (`event3`)** — grid **1248 × 2208**: - Up to **10 contacts** (`ABS_MT_SLOT` 0–9) with `ABS_MT_POSITION_X/Y`, `ABS_MT_PRESSURE` (0–255), `ABS_MT_TRACKING_ID`, `ABS_MT_TOOL_TYPE`. All three coordinate spaces share the screen's portrait aspect (~0.5625): panel 954×1696, pen 6760×11960, touch 1248×2208. ## 3. Display pipeline - **DRM/KMS only — there is NO `/dev/fb*`** and `/sys/class/graphics` is empty. Driver is **`imx-drm`**; device `/dev/dri/card0`; connector **`card0-LVDS-1`** ("connected", "disabled" at rest — normal for e-ink, which holds its image without continuous scanout). - The connector advertises a **packed `365×1700` mode** (hardware buffer for the E Ink Gallery 3 color subpixel layout); the logical screen is 954×1696. The mapping is handled by the epaper plugin (below) — we don't touch it directly. - **Implication:** the `mmap /dev/fb0` approach used by rmkit / libreMarkable on older grayscale models **does not apply** to this device. ## 4. Graphics / UI stack — the key finding - The stock app **`xochitl`** is a **Qt 6.8.2 / Qt Quick (QML)** application. - It renders through a **custom Qt platform (QPA) plugin: `epaper`** (`/usr/lib/plugins/platforms/libepaper.so`, links `libdrm`). Available QPA plugins on-device: **`epaper`**, `minimal`, `offscreen`, `vnc`. - Qt 6.8.2 runtime libraries and QML modules (`QtQuick`, `QtQuickControls2`, etc.) are all present under `/usr/lib` and `/usr/lib/qml`. No dev headers on-device (expected — we cross-build). **This means the native path is wide open:** build Chatter as a **Qt 6 app** and run it with **`-platform epaper`** to inherit working e-ink display + refresh, instead of reverse-engineering DRM/KMS and waveform handling. This resolves the project's highest-risk unknown in our favor. ## 5. Stock app & services - `xochitl.service` — the main UI app (`/usr/bin/xochitl`, pid varies). - `marker-manager.service` — "Remarkable CSL Marker Manager" (pen support). - `rm-sync.service` — document sync to the reMarkable cloud. - Plus metrics / MDM / crash-uploader services. **Coexistence / toggle implication:** on a DRM/KMS device only one process owns the display (DRM master) at a time, and xochitl holds it (and likely grabs the input devices) while running. So the Chatter ↔ standard-GUI **toggle is a hand-off** (stop or pause `xochitl` ↔ run Chatter, and a return path), **not an overlay**. The exact mechanism (systemctl stop/start vs. SIGSTOP/SIGCONT) is to be validated in the Phase 2 spike. ## 6. Document store (for the Save phase) Location: **`/home/root/.local/share/remarkable/xochitl/`**. Per document: - `UUID.metadata` — JSON: `visibleName`, `parent` (empty = top level; a folder is a `CollectionType` document whose UUID is used as children's `parent`), `type` (`DocumentType`), timestamps, `pinned`, etc. - `UUID.content` — JSON: page list under `cPages.pages[]` (each page has an `id`, ordering `idx`, `template`, scroll position, CRDT-style `timestamp` fields). - `UUID/` — directory of per-page **`.rm`** files. - `UUID.thumbnails/` — page thumbnails. - Store-root extras (Codex additions): `.tree` (binary "rM sync tree" index) and `rm-search-index.db` (SQLite **search index**, not the canonical store). **`.rm` page format:** header confirmed as **`reMarkable .lines file, version=6`** — the v6 binary scene-tree format (documented by the community, e.g. `rmscene`). Authoring valid v6 is possible but non-trivial. **Save options (decide in Phase 5):** 1. **PDF/PNG-backed document** — render Chatter's canvas to PDF/PNG and create a document that references it (xochitl already supports PDF documents). Far simpler and robust; still a real, renamable/syncable library item. 2. **Native v6 `.rm`** — author the binary page format so the transcript is an editable notebook. More work; revisit only if option 1 proves insufficient. Either way, transcripts go under a **`Chatter`** `CollectionType` folder, with filenames derived from date/time. --- ## 7. Decisions supported by Phase 1 1. **Stack: C++ / Qt 6.8.2**, rendered via the on-device **`epaper` QPA plugin**. Cross-build with a Yocto **scarthgap** aarch64 SDK matching Qt 6.8.2 / the device glibc. 2. **Input:** pen from `event2` (including `BTN_TOOL_RUBBER` for flip-to-erase), finger from `event3` (10-pt). Confirm in Phase 2 whether Qt+epaper already delivers these or we read evdev directly for custom gestures. 3. **Toggle = display/input hand-off** with xochitl, not an overlay. 4. **Save = PDF-backed document** (leaning), in a `Chatter` folder. 5. **Deploy under `/home`,** never the rootfs. ## 8. Open items for the Phase 2 spike - Stand up the cross-SDK and build a trivial Qt app; run it with `-platform epaper` **after stopping xochitl**; confirm it draws and refreshes. - Verify how input arrives in a Qt app under epaper (Qt event stream vs. raw evdev) and how reliably finger and pen separate at the Qt layer. - Validate the toggle hand-off (stop/start vs. stop/cont) and a return path.