Phase 8.1: kernel V4L2 device skeleton (out-of-tree module)

Out-of-tree Linux kernel module registering /dev/videoNN. Phase
8.1 scope: skeleton only — VIDIOC_QUERYCAP works, no codec
ioctls / no vb2_queue / no controls yet.

Real V4L2 plumbing throughout per "correctness before speed":
platform_device + v4l2_device + video_device, properly nested
with error paths and devm_kzalloc-managed lifetime. Per-cycle 9
discipline ports to kernel code: SPDX header, kernel coding
style (8-tab, static-by-default), kerneldoc on structs, no
shortcuts.

Files (~250 LOC total):
- kernel/Makefile — out-of-tree kbuild with checkpatch target
- kernel/daedalus_v4l2_main.c — module init/exit + probe/remove

Verification on hertz (Pi 5, 6.12.75+rpt-rpi-2712):
- Builds clean with -Wall -Wextra. No warnings.
- modprobe / rmmod round-trip clean. No dmesg taints beyond
  the expected "out-of-tree taint" line.
- v4l2-ctl --list-devices shows: "daedalus-fourier V3D7+NEON
  (platform:daedalus_v4l2): /dev/video0"
- VIDIOC_QUERYCAP returns driver/card/bus/caps as specified.
- v4l2-compliance: 44/48 passing. The 4 failures are exactly
  the format/buffer ioctls Phase 8.2 will implement
  (ENUM_FMT, G_FMT, Scaling, REQBUFS) — not skeleton bugs,
  legitimately-absent features.

Documentation: docs/phase_8_1_closure.md captures full
verification output + Phase 8.2 plan.

Phase 8.1 acceptance criteria met:
- ✓ /dev/videoNN appears via v4l2-ctl --list-devices
- ✓ VIDIOC_QUERYCAP responds with sensible values
- ✓ rmmod is clean (no kref leaks)
- ✓ v4l2-compliance passes except for explicit Phase 8.2 work

Next: Phase 8.2 chardev bridge for kernel ↔ daemon IPC.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-18 15:03:22 +00:00
parent 89f56e4b49
commit 9415b7e0f7
3 changed files with 390 additions and 0 deletions
+129
View File
@@ -0,0 +1,129 @@
# Phase 8.1 closure — kernel module skeleton
**Status:** closed 2026-05-18.
Out-of-tree Linux kernel module `daedalus_v4l2` that registers a
`/dev/videoNN` V4L2 device on a synthesised platform device.
Phase 8.1's scope: skeleton only — no actual decoder ioctls, no
buffer queue, no controls. Subsequent phases (8.2 chardev
bridge, 8.3 daemon parse, 8.4 VP9 end-to-end, etc.) build on
this base.
## What lands
- `kernel/Makefile` — out-of-tree kbuild stub. `make` against
the running kernel via `/lib/modules/$(uname -r)/build`.
Includes `make checkpatch` target for kernel coding-style
verification.
- `kernel/daedalus_v4l2_main.c` — ~190 lines. Real V4L2
plumbing: `platform_device` + `v4l2_device` +
`video_device`. Implements `VIDIOC_QUERYCAP`; everything
else falls through to `v4l2-core` defaults.
## Verification
On hertz (Pi 5, 6.12.75+rpt-rpi-2712):
### Build
```
$ cd ~/src/daedalus-v4l2/kernel && make
make -C /lib/modules/6.12.75+rpt-rpi-2712/build M=... modules
CC [M] daedalus_v4l2_main.o
LD [M] daedalus_v4l2.o
MODPOST Module.symvers
CC [M] daedalus_v4l2.mod.o
LD [M] daedalus_v4l2.ko
```
Builds clean with `-Wall -Wextra`. No warnings.
### Load + dmesg
```
$ sudo insmod daedalus_v4l2.ko
$ sudo dmesg | tail -2
daedalus_v4l2: loading out-of-tree module taints kernel.
daedalus_v4l2 daedalus_v4l2: daedalus-v4l2 registered as /dev/video0
(Phase 8.1 skeleton)
```
### v4l2-ctl --list-devices
```
daedalus-fourier V3D7+NEON (platform:daedalus_v4l2):
/dev/video0
```
(Appears alongside the existing `pispbe` and `rpi-hevc-dec`
devices.)
### VIDIOC_QUERYCAP
```
$ sudo v4l2-ctl --device /dev/video0 --info
Driver Info:
Driver name : daedalus_v4l2
Card type : daedalus-fourier V3D7+NEON
Bus info : platform:daedalus_v4l2
Driver version : 6.12.75
Capabilities : 0x84204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
```
### v4l2-compliance
```
$ sudo v4l2-compliance --device /dev/video0
Total for daedalus_v4l2 device /dev/video0: 48, Succeeded: 44,
Failed: 4, Warnings: 0
```
44/48 passing. The 4 failures are exactly what Phase 8.2 implements:
- `VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS`: no formats yet
- `VIDIOC_G_FMT`: no format negotiated
- `Scaling`: no output format negotiated (no `g_fmt_vid_out_mplane`)
- `VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF`: no `vb2_queue`
These are all Phase 8.2 + 8.4 work and are intentionally absent
from Phase 8.1.
### Unload
```
$ sudo rmmod daedalus_v4l2
```
Clean unload; no leak in dmesg.
## Coding-style note
Module written in kernel style (8-tab indent, `static`-by-default,
SPDX header, kerneldoc on `struct daedalus_dev`). Builds clean
with the kernel's `-Wall -Wextra` defaults. Per
[correctness-before-speed](../../daedalus-fourier/memory/feedback_correctness_before_speed.md)
session memory.
## What's next — Phase 8.2
Add a chardev bridge so a userspace daemon can talk to the
kernel module over `/dev/daedalus-v4l2`. Protocol stub:
```c
struct daedalus_req {
u32 type; /* DAEDALUS_REQ_DECODE, DAEDALUS_REQ_QUERY, ... */
u32 stream_id;
u32 frame_idx;
u32 bitstream_len;
/* followed by bitstream blob + control structs */
};
```
The kernel side becomes a thin marshal layer; all decoding work
moves to the daemon.
After 8.2 lands, Phase 8.3 adds the daemon's FFmpeg parse path
(dlopen at runtime, Option γ).