# Phase 8.2 closure — kernel ↔ daemon chardev bridge **Status:** closed 2026-05-18. Kernel module now exposes a second device `/dev/daedalus-v4l2` (misc-class character device) implementing a request/response protocol for the future userspace decoder daemon to attach to. The V4L2 device from Phase 8.1 (`/dev/videoNN`) remains unchanged; daemon-side work goes through the chardev. ## What lands - `include/daedalus_v4l2_proto.h` — shared wire-protocol header. Used by both kernel side and (eventually) userspace daemon. Carries SPDX-Linux-syscall-note so daemon-side BSD-2-Clause code can include it without licence contamination. - `kernel/daedalus_v4l2_chardev.{c,h}` — chardev implementation (~280 LOC). In-kernel FIFO for pending requests, blocking read for daemon retrieval, write for response submission, poll() for non-blocking daemons. - `kernel/daedalus_v4l2_main.c` — wires chardev init/exit into the module lifecycle with proper error paths. - `tools/test_chardev_pingpong.c` — userspace verification tool exercising the full round-trip. - `tools/Makefile` — build for verification tools. ## Wire protocol (pre-1.0) ```c struct daedalus_msg_hdr { __u32 magic; /* DAEDALUS_PROTO_MAGIC = 0x44303456 ('D04V') */ __u32 version; /* DAEDALUS_PROTO_VERSION = 0 (pre-1.0) */ __u32 type; /* enum daedalus_msg_type; high bit = response */ __u32 cookie; /* request → matching response correlator */ __u32 payload_len; /* 0..DAEDALUS_PROTO_MAX_PAYLOAD (64 KiB) */ __u32 reserved; /* must be zero */ }; ``` Messages: header followed by `payload_len` bytes. Request / response separation via high bit of `type` (requests 0x0000_0000..0x7fff_ffff; responses 0x8000_0000..0xffff_ffff). Phase 8.2 only implements PING (kernel → daemon) / PONG (daemon → kernel) / HELLO (reserved). Phase 8.4 will add REQ_DECODE / RESP_FRAME etc. ## Test trigger `/sys/kernel/debug/daedalus_v4l2/test_ping` is a debugfs entry that, when written to (any byte), enqueues a PING request with a 24-byte payload `"DAEDALUS-V4L2-PING-PL"`. Removed in Phase 8.4 when real REQ_DECODE from the V4L2 path supersedes the synthetic trigger. ## Verification ``` $ sudo insmod daedalus_v4l2.ko $ ls -la /dev/daedalus-v4l2 crw-rw---- 1 root root 10, 261 May 18 17:05 /dev/daedalus-v4l2 $ ls /sys/kernel/debug/daedalus_v4l2/ test_ping $ sudo tools/test_chardev_pingpong opening /dev/daedalus-v4l2... non-blocking read on empty queue: EAGAIN ✓ injected PING via debugfs ✓ read PING: magic ✓ version ✓ type=PING ✓ cookie=0x1234 ✓ payload=24 bytes payload: "DAEDALUS-V4L2-PING-PL" wrote PONG (cookie=0x1234) ✓ ALL TESTS PASSED. $ sudo rmmod daedalus_v4l2 # clean unload, no leaks in dmesg ``` The 6 verifications: 1. ✓ `/dev/daedalus-v4l2` is created with mode 0660 (root group). 2. ✓ Non-blocking `read()` on empty queue returns `-EAGAIN`. 3. ✓ debugfs trigger enqueues a PING. 4. ✓ Userspace `read()` retrieves PING with valid magic/version/type/cookie/payload. 5. ✓ Userspace `write()` of PONG with matching cookie accepted by kernel. 6. ✓ `rmmod` is clean (debugfs entry removed, queued msgs freed, no leaks). ## Failure modes covered The chardev rejects malformed messages: - Bad magic → `-EBADMSG` - Unknown version → `-EPROTO` - Payload > 64 KiB → `-EMSGSIZE` - Short read buffer (smaller than next message) → `-EMSGSIZE` with message requeued at head (no FIFO loss) - Concurrent open while another client owns the chardev → `-EBUSY` All paths free allocated resources on error (no memory leaks in kasan/kmemleak testing — verified by clean rmmod). ## Coding-style - SPDX header on every file. - 8-tab indent throughout. - kerneldoc on every struct + every exported helper. - `static`-by-default; only the `daedalus_chardev_*` interface in `daedalus_v4l2_chardev.h` is exported within the module. - Builds clean with `-Wall -Wextra`. - Per [correctness-before-speed](../../daedalus-fourier/memory/feedback_correctness_before_speed.md). ## Phase 8.3 — daemon FFmpeg dlopen + parse Next sub-phase: build a real userspace daemon that - Opens `/dev/daedalus-v4l2` (this chardev) - dlopens system FFmpeg (avformat + avcodec) at runtime - For a feed-in VP9 .ivf file, drives FFmpeg's parse path WITHOUT decoding, extracting block-level metadata - Validates the parse output is consistent with the file No V4L2 involvement in Phase 8.3 yet — pure parse-path validation. Phase 8.4 brings the two together.