e289904852
- STUBS-AUDIT-AND-REWRITE-PLAN.md: master plan, 20 drivers audited - USB-STUBS-AUDIT.md: USB stack focus, xhcid/usbhubd/usbctl/usbhidd/usbscsid/ucsid - HID-STUBS-AUDIT.md: HID focus, usbhidd/i2c-hidd/intel-thc-hidd/ps2d/inputd/evdevd - LOWLEVEL-STUBS-AUDIT.md: ACPI/PCI/IRQ/IOMMU/boot/init, 50+ row coverage - BOOT-AND-HW-ENABLEMENT-ASSESSMENT.md: kernel to display chain, NO VESA policy - DESKTOP-SERVICES-ASSESSMENT.md: D-Bus, session, audio, network - CONFIG-AND-INIT-ASSESSMENT.md: configs, init.d, recipes, layering - GPU-MESA-KDE-CHAIN-ASSESSMENT.md: Mesa to Plasma build chain These documents track the v6.0 stub-fix campaign and the comprehensive Phase 1-5 implementation work. All cited paths and line numbers are real. Documents are durable in local/docs/ which survives make distclean.
1560 lines
94 KiB
Markdown
1560 lines
94 KiB
Markdown
# Boot and Hardware Enablement Assessment — KERNEL → INITFS → INIT → DISPLAY → WAYLAND → KDE
|
||
|
||
**Document version:** 1.0
|
||
**Date:** 2026-06-09
|
||
**Scope:** Every link in the chain that turns cold metal into a Wayland/SDDM login prompt on `redbear-full` (QEMU virtio-gpu, AMD64).
|
||
**Audience:** Red Bear OS maintainers planning the next 12 weeks of integration work.
|
||
**Method:** Direct code-level inspection of every layer in `local/sources/` and `local/recipes/`, cross-referenced against `local/docs/STUBS-AUDIT-AND-REWRITE-PLAN.md`, `local/docs/LOWLEVEL-STUBS-AUDIT.md`, `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` (v6.0), `local/docs/QUIRKS-SYSTEM.md`, `local/docs/DBUS-INTEGRATION-PLAN.md`, `local/docs/GREETER-LOGIN-IMPLEMENTATION-PLAN.md`, and the local kernel/init/initfs source.
|
||
|
||
**Important:** This document is **read-only**. No source files are modified. It is an audit, not a fix.
|
||
|
||
---
|
||
|
||
## Executive Summary
|
||
|
||
| Metric | Value |
|
||
|--------|-------|
|
||
| Stage coverage | 6/6 (kernel, initfs, init, pcid, display, quirk system) |
|
||
| `unimplemented!()` macro panics in chain | 6 (vesad 1, pcid fallback 2, ihdgd 1, ps2d 2) |
|
||
| `expect("TODO")` panic strings in chain | 2 (`init/src/service.rs:98,100`) |
|
||
| `// TODO` / `// FIXME` in chain (excluding upstream KWin/SDDM/dbus) | ~500+ |
|
||
| Anti-pattern: `*-stub` recipes installed to satisfy KWin/SDDM/CMake | 5 (`libudev-stub`, `libdisplay-info-stub`, `libepoxy-stub`, `libxcvt-stub`, `lcms2-stub`) |
|
||
| Anti-pattern: `vesad` registered as `display.vesa` primary display | YES (policy violation, see §5.1) |
|
||
| Display handoff (vesad → DRM/KMS) actually implemented | NO (de facto app-level only; no daemon-level unregister) |
|
||
| Quirks fully compiled-in + TOML-loaded + DMI-matched | YES (R0–R22 landed 2026-06-07; 131 host-buildable unit tests) |
|
||
| Quirks actually consumed by every relevant driver | NO — kernel, network drivers, audio, panel rotation all deferred (see §6) |
|
||
| Init service order matches the canonical plan | PARTIAL — most services exist but two target references are unresolved |
|
||
| Init auto-restart on failure | NO (`enum JobKind { Start }` only; no Restart/Stop/Reload) |
|
||
| KWin real build (QML/Quick on) | BLOCKED — 10 `KWIN_BUILD_*=OFF` flags and the `lib*-stub` chain block it |
|
||
| SDDM real build (Qt6 + Wayland greeter) | Compiles with multiple disabled paths; 4 `// TODO: IMPLEMENT` remain in `daemon/DisplayManager.cpp:156,160,164,195` |
|
||
| Mesa → Qt6 CMake config chain | Compiles; feature gates at the Qt6 detection layer require explicit `-DQT_FEATURE_*=ON` overrides |
|
||
| Estimated LoC to add to reach **Wayland/SDDM login on QEMU** | ~3,500–5,000 |
|
||
| Estimated time to fix (2 devs) | 12–18 weeks |
|
||
|
||
### Top blockers for the user's stated goal (boot to Wayland/SDDM on QEMU)
|
||
|
||
1. **`vesad` still registers `display.vesa` as a primary display scheme** (`vesad/src/main.rs:87`). Per project policy (`AGENTS.md` "NO VESA POLICY") vesad must hand off to `redox-drm` and not be the primary surface. The code does not implement this handoff. KWin/SDDM are told to use `/scheme/drm/card0` (good) but if `redox-drm` is slow to register (or fails on a non-virtio GPU) the boot falls back to vesad as the visible surface, contradicting the policy.
|
||
2. **KWin recipe disables 10+ build features via `KWIN_BUILD_*=OFF`** (`local/recipes/kde/kwin/recipe.toml:155-165`) — auto-rotation, X11, X11 backend, KCMS, screenlocker, tabbox, globalshortcuts, runners, notifications, activities, EIS. This is the "honest build" policy from the project AGENTS.md but it means the resulting KWin binary is a compositor shell, not the full KWin that SDDM expects to spawn.
|
||
3. **5 `*-stub` recipes are wired into the build chain** for KWin (`libepoxy-stub`, `libxcvt-stub`, `libdisplay-info-stub`, `lcms2-stub`, `libudev-stub`). These exist only to satisfy KWin's CMake `find_package` calls and provide empty/no-op symbols. Per project policy this is a violation: "Implement the missing functionality properly" rather than stub.
|
||
4. **Init has no auto-restart** (`init/src/scheduler.rs:14-17` defines `enum JobKind { Start }` only; no Restart, no Stop, no Reload). If `redox-drm` dies after registering `/scheme/drm/card0`, the user gets a frozen desktop and no recovery.
|
||
5. **The `redbear-compositor` Wayland protocol is bounded** (`redbear-compositor/source/src/main.rs:1-15`: "bounded proof scaffold, not a real compositor runtime proof"). The canonical plan v6.0 says it is for the greeter only and KWin takes over for the user session, but the integration step (handoff from compositor → KWin) is not specified and not implemented in either binary.
|
||
|
||
### Phase blockers (canonical plan v6.0 mapping)
|
||
|
||
The CONSOLE-TO-KDE-DESKTOP-PLAN.md v6.0 defines 10 phases. Real status against current code:
|
||
|
||
| Phase | Status | Evidence |
|
||
|-------|--------|----------|
|
||
| 0 — Pre-flight: QML JIT + kf6-kdeclarative QML re-enable | NOT STARTED | `redbear-full.toml:96` kirigami is not even listed; plasma-framework / plasma-workspace / plasma-desktop are commented out |
|
||
| 1 — Single evdev producer | PARTIAL | evdevd + `redbear-input-headers` exist; no integrated plan in `redbear-full.toml` to retire inputd |
|
||
| 2 — redbear-compositor real-or-honest | HONEST STUB | `redbear-compositor/src/main.rs:1-15` is explicit about being a bounded scaffold |
|
||
| 3 — Mesa + libdrm + libepoxy (Mesa is the boundary) | COMPILES | mesa = {} in config; libdrm = {}; libepoxy = "stub" (anti-pattern) |
|
||
| 4 — KWin QML-free build | COMPILES via KWIN_BUILD_*=OFF | recipe.toml:155-165 |
|
||
| 5 — KWin real QML/Quick build | BLOCKED on QML gate | recipe.toml:1 `#TODO: KWin — full build with Qt6Quick/QML` |
|
||
| 6 — SDDM activation | COMPILES with 4 TODO:IMPLEMENT in DisplayManager | `sddm/source/src/daemon/DisplayManager.cpp:156,160,164,195` |
|
||
| 7 — Compositor + SDDM integration | NOT STARTED | No `/etc/sddm.conf` matches the daemon's compiled-in paths; `/usr/share/wayland-sessions/plasmawayland.desktop` is hand-installed via `redbear-full.toml:592-601` |
|
||
| 8 — Plasma framework/workspace/desktop | BLOCKED on QML gate | 3 packages commented out in `redbear-full.toml:147-150` |
|
||
| 9 — KDE apps (Dolphin, Kate, Gwenview) | NOT STARTED | No recipes in `local/recipes/kde/` for them |
|
||
| 10 — Polish / integration | NOT STARTED | — |
|
||
|
||
|
||
---
|
||
|
||
## Per-Stage Assessment
|
||
|
||
### 1. Kernel Boot
|
||
|
||
**Location**: `local/sources/kernel/`
|
||
**Total LoC audited**: ~21,555 (per LOWLEVEL-STUBS-AUDIT.md)
|
||
**Relevant files**: `src/acpi/{mod,rsdp,rsdt,rxsdt,xsdt,sdt,hpet,gtdt,srat,slit,spcr}.rs`, `src/arch/x86_64/`, `src/arch/x86_shared/`, `src/startup/mod.rs`, `src/scheme/acpi.rs`, `src/syscall/mod.rs`
|
||
|
||
#### What works (per LOWLEVEL-STUBS-AUDIT.md, confirmed by code)
|
||
|
||
| Feature | Status | File:line |
|
||
|---------|--------|-----------|
|
||
| RSDP search (x86 BIOS, EFI, RSDP_ADDR forwarded) | ✅ | `acpi/mod.rs:95-170` |
|
||
| RSDT/XSDT parsing | ✅ | `rxsdt.rs`, `xsdt.rs` |
|
||
| FADT, MADT, SRAT, SLIT, SPCR (aarch64), HPET, GTDT (aarch64) | ✅ | per-file `init()` |
|
||
| `enumerate_pci_class` from pcid-spawner handoff | ✅ | `redox-drm/source/src/main.rs:217-228` |
|
||
| `setrens(0,0)` syscall | ✅ | `init/src/main.rs:178` |
|
||
| Symmetric Multiprocessing (x2APIC) | ✅ (per plan v6.0 + LOWLEVEL-STUBS-AUDIT.md Phase P0) | `arch/x86_64/interrupt/` |
|
||
| Syscall interface for schemes (irq, memory, pci, event, debug) | ✅ | `scheme/{irq,memory,debug,proc,sys}.rs` |
|
||
| DMI scheme (`/scheme/acpi/dmi`) | ✅ (Blocker 2, 2026-06) | `scheme/acpi.rs` + `acpid/dmi.rs` |
|
||
|
||
#### Stubs / half-impls
|
||
|
||
1. **HPET initialization is hard-coded; userspace cannot reconfigure** — `acpi/mod.rs:163`:
|
||
```rust
|
||
// TODO: Let userspace setup HPET, and then provide an interface to specify which timer to
|
||
// use?
|
||
Hpet::init();
|
||
```
|
||
Impact: When `redbear-quirks` flags a clocksource issue (e.g. `PMTMR_BLACKLIST` on PIIX4<3, ICH4, ServerWorks LE), the kernel has no path to read the flag and pick a different clocksource. The flag exists in `redox-driver-sys` and is loaded by the TOML (R15), but the kernel-side consumer is missing.
|
||
|
||
2. **Processor enumeration is in the kernel** — `acpi/mod.rs:149`:
|
||
```rust
|
||
// TODO: Enumerate processors in userspace, and then provide an ACPI-independent interface
|
||
// to initialize enumerated processors to userspace?
|
||
```
|
||
Impact: kernel-side enumeration couples the boot to ACPI; for a DTB/AAarch64 future this will need a refactor. Not blocking QEMU.
|
||
|
||
3. **aarch64 SPCR parsing is gated** — `acpi/mod.rs:159-167`:
|
||
```rust
|
||
//TODO: support this on any arch
|
||
#[cfg(target_arch = "aarch64")]
|
||
spcr::Spcr::init();
|
||
```
|
||
x86_64 SPCR is not parsed; the kernel picks 0x3F8 serial port from a hard-coded fallback. Adequate for QEMU, blocks headless server debugging with custom baud.
|
||
|
||
4. **Start-up still touches ACPI tables directly** — `acpi/mod.rs:134`:
|
||
```rust
|
||
// TODO: Don't touch ACPI tables in kernel?
|
||
for sdt in rxsdt.iter() {
|
||
get_sdt(sdt, &mut KernelMapper::lock_rw());
|
||
}
|
||
```
|
||
The kernel's responsibility is to expose the RSDP address + raw SDT bytes to userspace; acpid does the parsing. The current implementation parses enough to find the MADT/SRAT in the kernel. Not blocking, but contributes to the asymmetric "kernel does too much, userspace duplicates" pattern.
|
||
|
||
5. **IOMMU interrupt remapping is open** (per LOWLEVEL-STUBS-AUDIT.md "Critical Gaps"). The kernel has the IOMMU page-table code (per `local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md`) but the redbear-quirks R21 flag `SUPPRESS_IVRS` for the `iommu` daemon to consult is not yet wired into the kernel side.
|
||
|
||
6. **Total of 330 `TODO|FIXME` markers across the kernel tree** (`find ... | xargs grep -c "TODO\|FIXME" | awk '{s+=$2}END{print s}'` = 330) — most are localised in `context/memory.rs:67` (memory layout) and `context/signal.rs:7` (signal delivery). These are tracked in the LOWLEVEL-STUBS-AUDIT but they do not block boot to a Wayland login.
|
||
|
||
#### Missing wirings
|
||
|
||
- **DMI-to-clocksource handoff**: `redox-driver-sys` exports `ClocksourceQuirkFlags::PMTMR_BLACKLIST/PMTMR_GRAYLIST/HPET_BROKEN/TSC_UNSTABLE` (R15), but the kernel `Hpet::init()` does not consume them. To close this: kernel must read `/scheme/acpi/dmi` (or an analogous publisher) at `Hpet::init()` time and skip a flagged source.
|
||
- **TOML quirk consumer for chipset-early entries (R17)**: 11 entries in `55-chipset-early.toml` (`redbear-quirks/source/quirks.d/`) sit behind a documented "kernel-side follow-up" gate. The R17 phase explicitly defers consumer wiring.
|
||
- **CPU bug flag consumer (R14)**: 27 `X86_BUG_*` flags defined; the kernel context-switch path does not consume them. Spectre/Meltdown mitigations are nominally supported but unwired.
|
||
|
||
#### Stale code
|
||
|
||
- The `acpi/slit.rs` and `acpi/srat.rs` exist but `numad` (per `redbear-full.toml:59`) is included for "NUMA topology discovery" without an obvious consumer in the kernel. For a single-socket QEMU run this is inert; for dual-socket AMD Threadripper (per AGENTS.md header) the SRAT data is published but not used to bias scheduler placement.
|
||
- `src/scheme/acpi.rs:1` `smbios` parsing feeds the DMI scheme (Blocker 2), but the `DmiInfo` struct is missing some fields that newer kernels (Linux 7.1 `drivers/firmware/dmi_scan.c`) parse. Resolved 2026-06 (`b56b810c0` added `bios_vendor` / `bios_date`).
|
||
|
||
#### Quirks used by kernel
|
||
|
||
- **DMI table** (R11 / Blocker 2): kernel `SmbiosScheme` → acpid `dmi::parse_smbios_table` → `/scheme/acpi/dmi` + `/scheme/acpi/dmi/{field}`. End-to-end chain landed 2026-06.
|
||
- **No direct kernel consumer** for `PciQuirkFlags`, `UsbQuirkFlags`, `HidQuirkFlags`, `AcpiQuirkFlags`, `DrmPanelOrientation`, `PlatformDmiQuirkFlags`, `CpuBugFlags`, `ClocksourceQuirkFlags`, `ChipsetQuirkFlags`, `UsbAudioQuirkFlags`. All ten flag families have data + lookup; only DMI is actually consumed.
|
||
|
||
#### LoC estimate
|
||
|
||
- HPET/DMI clocksource handoff: ~300 LoC kernel + 200 LoC tests
|
||
- CPU bug context-switch consumer: ~600 LoC kernel
|
||
- Chipset-early handler: ~1200 LoC kernel
|
||
- SPCR for x86_64: ~150 LoC
|
||
|
||
**Total**: ~2,450 LoC kernel-side. 4–6 weeks with 1 kernel developer.
|
||
|
||
#### Time estimate
|
||
|
||
4–6 weeks (1 dev) for a "kernel exposes data; consumers live in userspace drivers" refactor consistent with the LOWLEVEL-STUBS-AUDIT.md P5 plan.
|
||
|
||
|
||
### 2. Init Filesystem (initfs)
|
||
|
||
**Location**: `local/sources/base/initfs/`
|
||
**Library LoC**: 413 (`lib.rs:287`, `types.rs:126`)
|
||
**Tools LoC**: 769 (`tools/src/lib.rs:590`, `bin/archive.rs:67`, `bin/dump.rs:112`)
|
||
**Test LoC**: 108 (`tools/tests/archive_and_read.rs`)
|
||
|
||
#### What works
|
||
|
||
- The initfs image format is a self-describing bin (MAGIC=`"RedoxFtw"`, 4 KiB page size assumption; see `types.rs:4`) with a header, an inode table, and string-offset dir entries. The library can be compiled to `no_std` and used inside the bootloader (`initfs/src/lib.rs:1-30`).
|
||
- `archive` and `dump` tools exist for assembling the initfs image and inspecting it. The tests exercise the round trip (archive → read → dump).
|
||
- The `initfs.toml` `[[drivers]]` table in `local/sources/base/drivers/initfs.toml` lists the early-boot drivers that need to live in the initfs: `ahcid`, `ided`, `nvmed`, `virtio-blkd`, `virtio-gpud` (yes, virtio-gpud is in initfs — see §5).
|
||
- `initfs-pcid-storage.toml` and `initfs-storage.toml` provide driver-manager-style initfs manifest variants for storage.
|
||
|
||
#### What is bundled into the initfs
|
||
|
||
The actual contents of the initfs image at build time are not visible from the `initfs/` source — they are produced by the cookbook tool at build time by following the `[[drivers]]` entries in the `initfs*.toml` files. Based on `initfs.toml`:
|
||
|
||
| Driver | Class | Subclass | Vendor | Device | Purpose |
|
||
|--------|-------|----------|--------|--------|---------|
|
||
| `ahcid` | 0x01 (storage) | 0x06 (SATA) | any | any | Boot rootfs from SATA |
|
||
| `ided` | 0x01 | 0x01 (IDE) | any | any | Boot rootfs from IDE |
|
||
| `nvmed` | 0x01 | 0x08 (NVMe) | any | any | Boot rootfs from NVMe |
|
||
| `virtio-blkd` | 0x01 | 0x00 (SCSI) | 0x1AF4 | 0x1001 | Boot rootfs from virtio |
|
||
| `virtio-gpud` | 0x03 (display) | any | 0x1AF4 | 0x1050 | QEMU graphics |
|
||
|
||
Note that `vesad`, `fbcond`, `fbbootlogd` are **not** in the initfs drivers list — they come from the base package's `init.initfs.d/` service files and run as userland daemons.
|
||
|
||
#### Manifest source
|
||
|
||
**Hybrid (TOML list + service file list)**:
|
||
- The image is built by the cookbook's `initfs::tools::archive` consuming the TOML manifest.
|
||
- The **service definitions** that run inside the initfs (using `/scheme/initfs/lib/init.d/...`) come from the base source fork: `local/sources/base/init.initfs.d/` (20 service files, 243 LoC).
|
||
|
||
#### Stubs / half-impls
|
||
|
||
None found in the initfs **format** itself. The format is well-tested and the `archive_and_read` round trip is exercised by the test suite. The initfs library and tools have 0 `TODO`/`FIXME`/`unimplemented!` in the source.
|
||
|
||
#### Missing wirings
|
||
|
||
- **No formal manifest schema** — the TOML is informal and is read by the cookbook's recipe generator. A regression that drops a driver from `initfs.toml` is silent. There is no equivalent of `cargo metadata` to list the inits-image contents.
|
||
- **No way to add custom initfs-only drivers without modifying the base source**. A Red Bear-specific driver that needs to be in the initfs would have to either be added to `local/sources/base/init.initfs.d/` (which the base fork does) or come from a recipe-time-generated override.
|
||
|
||
#### Stale code
|
||
|
||
None observed. The `initfs` source is small, focused, and stable.
|
||
|
||
#### LoC estimate
|
||
|
||
0 LoC. The initfs library and tools are complete for the use case.
|
||
|
||
#### Time estimate
|
||
|
||
0 days. The initfs is a solved sub-problem.
|
||
|
||
### 3. Init System
|
||
|
||
**Location**: `local/sources/base/init/`
|
||
**Total LoC**: 846 (`main.rs:184`, `scheduler.rs:116`, `script.rs:163`, `service.rs:132`, `unit.rs:251`)
|
||
|
||
#### What works
|
||
|
||
| Feature | Status | File:line |
|
||
|---------|--------|-----------|
|
||
| TOML unit parsing (`*.service`, `*.target`) | ✅ | `unit.rs:174-228` |
|
||
| Legacy script parsing (no extension) | ✅ | `script.rs:18-38` |
|
||
| `requires_weak` dep tracking | ✅ | `unit.rs:31-95` |
|
||
| `condition_architecture` / `condition_board` filtering | ✅ | `unit.rs:230-250` |
|
||
| Templated unit IDs (`ramfs@.service` with `$INSTANCE` substitution) | ✅ | `unit.rs:153-172, 31-40` |
|
||
| Service `cmd`, `args`, `envs`, `inherit_envs` | ✅ | `service.rs:13-35` |
|
||
| `ServiceType` variants: `Notify`, `Scheme(name)`, `Oneshot`, `OneshotAsync` | ✅ | `service.rs:27-35` |
|
||
| Init switch_root (initfs → rootfs) | ✅ | `main.rs:51-113, 120-148` |
|
||
| Init logging redirect to `logd` | ✅ | `main.rs:131-133` |
|
||
| Service status reporting on failures | ✅ | `scheduler.rs:33-35` |
|
||
| `setrens(0, 0)` final namespace closure | ✅ | `main.rs:178` |
|
||
|
||
#### Stubs / half-impls
|
||
|
||
1. **`expect("TODO")` panic in `Service::spawn` when a `Scheme(type)` service starts** — `service.rs:98, 100`:
|
||
```rust
|
||
let current_namespace_fd = libredox::call::getns().expect("TODO");
|
||
libredox::call::register_scheme_to_ns(current_namespace_fd, scheme, new_fd)
|
||
.expect("TODO");
|
||
```
|
||
The `getns` call and the `register_scheme_to_ns` call are best-effort at boot — they succeed on the host but a build that ever runs init in a non-namespace environment will panic. This is a real `todo!()` disguised as `.expect("TODO")` (2 of them in this section).
|
||
|
||
2. **No auto-restart loop** — `scheduler.rs:14-17`:
|
||
```rust
|
||
enum JobKind {
|
||
Start,
|
||
}
|
||
```
|
||
No `Stop`, no `Restart`. A scheme service that registers its scheme and then dies (e.g. `redox-drm` panic) leaves `/scheme/drm/card0` in a stale state with no recovery. Per LOWLEVEL-STUBS-AUDIT.md "Init auto-restart on failure: 2 weeks".
|
||
|
||
3. **Multi-user target is a comment, not a unit** — `main.rs:150-151`:
|
||
```rust
|
||
// FIXME introduce multi-user.target unit and replace the config dir iteration
|
||
// scheduler.schedule_start_and_report_errors(&mut unit_store, UnitId("multi-user.target".to_owned()));
|
||
```
|
||
The rootfs boot path iterates every file in `/usr/lib/init.d/` and `/etc/init.d/` (line 153-173) and schedules all of them. This means services with side effects (like `99_diag_serial.service`) get scheduled even if their dep chain has not yet reached them. The `default_dependencies = false` workaround in service files is the only guard.
|
||
|
||
4. **No poweroff/reboot handling** — `init/src/main.rs:180-183`:
|
||
```rust
|
||
loop {
|
||
let mut status = 0;
|
||
libredox::call::waitpid(0, &mut status, 0).unwrap();
|
||
}
|
||
```
|
||
Waitpid is called but the status is discarded. There is no `reboot()` syscall on power-button or `SIGINT` from a logged-in user. The user can only poweroff from inside the kernel debug scheme or by ACPI power button (per ACPI-IMPROVEMENT-PLAN.md §3).
|
||
|
||
5. **No on-failure service policy** — `unit.rs:117-128` defines `UnitInfo` with `description`, `default_dependencies`, `requires_weak`, `condition_architecture`, `condition_board` but no `restart`, `restart_sec`, `start_limit_burst`, `start_limit_interval_sec` (systemd-equivalent). The deserializer also has `#[serde(deny_unknown_fields)]` (line 118), so any future field must be added deliberately.
|
||
|
||
6. **`unit.rs:126`** `// FIXME replace this with hwd reading from the devicetree` — `condition_board` is board-name based and is fed by an env var; the kernel's hwd is supposed to publish this via scheme. The hwd-side producer is open (see §4.5).
|
||
|
||
7. **The `00_*.service` / `90_*.service` numeric ordering is implicit** — `unit.initfs.d/90_initfs.target` exists as a target but `init.d/00_*.service` files in the rootfs come from the cookbook and have no ordering key beyond file name. systemd has `Before=`/`After=`; this init has no equivalent (only `requires_weak`).
|
||
|
||
#### Missing wirings
|
||
|
||
- **No `Reload` job** for services whose state file changes (e.g. SDDM config, seatd policy).
|
||
- **No `ConditionPathExists`** / `ConditionKernelCommandLine` for env-gated activation. Right now a service that should only run on `redbear-full` must be excluded from `redbear-mini.toml` manually.
|
||
- **No graceful shutdown of dependent services** before a reboot. The current `waitpid` loop just reaps zombies.
|
||
|
||
#### Stale code
|
||
|
||
- `main.rs:181` reads `let mut status = 0;` but the variable is `mut`-declared and never mutated. Likely a `cargo clippy` `unused_mut` warning. The `waitpid(0, &mut status, 0).unwrap()` then overwrites it but the compiler may not see that.
|
||
- The `condition_board` field is a `FIXME` and is read from `option_env!("BOARD")` (compile time) at `unit.rs:243` — it is effectively dead. No recipe sets `BOARD` at compile time.
|
||
|
||
#### LoC estimate
|
||
|
||
- Auto-restart loop + start-limit: ~400 LoC
|
||
- Multi-user target + filter iteration: ~150 LoC
|
||
- poweroff/reboot wiring: ~250 LoC
|
||
- Oneshot-as-dependency cleanup: ~200 LoC
|
||
|
||
**Total**: ~1,000 LoC. 2–3 weeks with 1 dev.
|
||
|
||
#### Time estimate
|
||
|
||
2–3 weeks. The init system is small (846 LoC) and the changes are localised; the main risk is the no-restart + no-shutdown issue, which together explain the "frozen desktop after a panic" failure mode that CONSOLE-TO-KDE-DESKTOP-PLAN.md references.
|
||
|
||
|
||
### 4. PCID and Driver Spawner
|
||
|
||
**Location**:
|
||
- `local/sources/base/drivers/pcid/` (3,083 LoC, 7 files)
|
||
- `local/sources/base/drivers/pcid-spawner/` (101 LoC, 1 file)
|
||
- `local/recipes/system/driver-manager/` (recipe-level)
|
||
- `local/sources/base/drivers/pcid/src/driver_interface/` (8 sub-files)
|
||
- `local/sources/base/drivers/pcid/src/cfg_access/` (PCIe MMIO + I/O port fallback)
|
||
|
||
#### What works
|
||
|
||
| Feature | Status | File:line |
|
||
|---------|--------|-----------|
|
||
| PCIe MMIO extended config access | ✅ | `cfg_access/mod.rs` |
|
||
| PCI 3.0 I/O port fallback (x86_64 only) | ✅ | `cfg_access/fallback.rs:58-83` |
|
||
| Multi-bus enumeration (R1 fixed 2026-06) | ✅ | `main.rs:299` (per STUBS-AUDIT) |
|
||
| BAR parsing (32/64-bit, prefetchable) | ✅ | `main.rs:38-82` |
|
||
| Capability list walk | ✅ | `main.rs`, `driver_interface/cap.rs` |
|
||
| MSI / MSI-X enablement | ✅ | `driver_handler.rs:71-200` |
|
||
| ROM BAR reading | ✅ | `main.rs:84-115` |
|
||
| `pcid-spawner` reads driver TOML config and spawns matched drivers | ✅ | `pcid-spawner/src/main.rs:22-32` |
|
||
| Handoff of PCI client channel via `PCID_CLIENT_CHANNEL` env | ✅ | `pcid-spawner/src/main.rs:92-93` |
|
||
| `redox_driver_sys::pci::PciDeviceInfo` + quirk lookup | ✅ | `pcid/src/quirks.rs:42-200` |
|
||
| `apply_pci_quirks` wired into `handle_parsed_header` | ✅ | `pcid/src/quirks.rs` (Blocker 1 resolved 2026-06) |
|
||
| `QuirkAction::execute` for imperative config-space writes | ✅ | `redox-driver-sys/src/quirks/mod.rs:779-857` |
|
||
|
||
#### Stubs / half-impls
|
||
|
||
1. **`todo!()` panic on non-x86 PCI access** — `pcid/src/cfg_access/fallback.rs:89, 94`:
|
||
```rust
|
||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||
impl ConfigRegionAccess for Pci {
|
||
unsafe fn read(&self, addr: PciAddress, offset: u16) -> u32 {
|
||
let _guard = self.lock.lock().unwrap();
|
||
todo!("Pci::CfgAccess::read on this architecture")
|
||
}
|
||
...
|
||
}
|
||
```
|
||
On aarch64/RISC-V the kernel would panic on the first PCI access. There is no PCIe ECAM fallback for non-x86 yet. Not a QEMU x86_64 blocker; a blocker for aarch64 server class.
|
||
|
||
2. **`unimplemented!()` panics in `pcid::scheme::SchemeImpl::pcilink` path** — `pcid/src/scheme.rs:329`:
|
||
```rust
|
||
log::trace!("TODO: Support disabling device (called on {})", addr);
|
||
```
|
||
This is a `log::trace!` (not a `todo!()`), but the underlying handler returns success without doing anything. Disabling a PCI device is "supported" via the scheme call but the function is a no-op. Per LOWLEVEL-STUBS-AUDIT.md "PCIe AER support: 3 weeks" (related).
|
||
|
||
3. **pcid-spawner has zero ACPI / DMI matching** — `pcid-spawner/src/main.rs:65-72`:
|
||
```rust
|
||
let Some(driver) = config
|
||
.drivers
|
||
.iter()
|
||
.find(|driver| driver.match_function(&full_device_id))
|
||
else {
|
||
log::debug!("no driver for {}, continuing", handle.config().func.addr);
|
||
continue;
|
||
};
|
||
```
|
||
The match is purely PCI (vendor/device/class). The plan section "PCID and DMI" suggests that the spawner should also consult `/scheme/acpi/dmi` to pick a different driver for a known-bad implementation. This is not implemented; for QEMU virtio-gpu the match works because the table is `vendor=0x1AF4, device=0x1050` (per `redbear-full.toml:621-630`).
|
||
|
||
4. **pcid-spawner `--initfs` flag selects the initfs config directory** — `pcid-spawner/src/main.rs:11, 22-30`:
|
||
```rust
|
||
let initfs = args.contains("--initfs");
|
||
...
|
||
for path in if initfs {
|
||
config::config_for_initfs("pcid")?
|
||
} else {
|
||
config::config("pcid")?
|
||
} { ... }
|
||
```
|
||
The initfs and rootfs use the same `pcid` key. The `initfs-pcid-storage.toml` and `initfs-storage.toml` use a different format (`[[drivers]]` with `command` as a single string, vs. the new `[[driver]]` with `command` as a list — `redbear-full.toml:206-226` uses the new format with `[[driver.match]]`). There is a real risk that the `initfs-pcid-storage.toml` and the new manifest format are not interchangeable; the spawner would not parse the new format if started from initfs.
|
||
|
||
5. **10 `// TODO` / `// FIXME` in `pcid/src/scheme.rs`**:
|
||
- `scheme.rs:39` `// TODO: capability rather than root` — the scheme exposes PCI functions but not the capability list directly.
|
||
- `scheme.rs:86` `// TODO: Check flags are correct` — argument validation is best-effort.
|
||
- `scheme.rs:95` `// FIXME remove replacement of : once the old scheme format is no longer supported` — backwards-compat glue.
|
||
- `scheme.rs:384` `// XXX: Why can't VecDeque support dequeueing into slices?` — Rust std limitation, harmless.
|
||
- `scheme.rs:431, 435` `// FIXME use : instead of -- as separator` — the `:` character is reserved in scheme names, hence the historical `--` replacement. Per project policy, `--` in path is the legacy compat; the new paths use `:` (e.g. `/scheme/drm/card0`).
|
||
|
||
6. **8 `// TODO` / `// FIXME` in `pcid/src/driver_interface/`**:
|
||
- `irq_helpers.rs:42` `// TODO: Perhaps read the MADT instead?` — the IRQ override allocator hard-codes the LAPIC vector; it should consult the kernel's MADT for delivery mode (per `local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md`).
|
||
- `irq_helpers.rs:120` `// TODO: fcntl F_SETLK on /scheme/irq/` — no advisory locking on the IRQ scheme; multiple drivers can race.
|
||
- `irq_helpers.rs:254` `// TODO: Allow allocation of up to 32 vectors.` — MSI-X vectors are capped at the Linux default of 8; some modern NICs need more.
|
||
- `irq_helpers.rs:308` `// FIXME move MSI-X IRQ allocation to pcid` — currently in pcid-handler but the kernel could provide a dedicated scheme.
|
||
- `irq_helpers.rs:428` `// FIXME support MSI on non-x86 systems` — same as the `cfg_access` fallback aarch64 issue.
|
||
- `msi.rs:161` `// TODO: should the reserved field be preserved?` — MSI-X cap walk may clobber reserved bits.
|
||
|
||
#### Missing wirings
|
||
|
||
- **DMI-matched driver spawner**: not implemented (item 3 above).
|
||
- **Hot-plug events for PCIE**: the kernel `interrupt::pci` scheme supports hot-plug but pcid does not listen for new device notifications; it polls at boot only.
|
||
- **Quirk-action loop in xhcid**: per QUIRKS-SYSTEM.md Blocker 4, the QuirkAction loop that applies imperative config-space writes is wired into pcid (`PcidConfigWriter`) but xhcid has a documented "1-2 day wiring task" to use it. The flags are set, the dispatcher in pcid runs, but xhcid's QuirkAction loop is the last step.
|
||
|
||
#### Stale code
|
||
|
||
- `pcid/src/scheme.rs:431, 435` `--` → `:` translation is documented as legacy. The new format is everywhere (e.g. `/scheme/drm/card0` in `redbear-full.toml:295`). The translation is dead code in practice.
|
||
- `cfg_access/fallback.rs:30-35` warns that "PCIe extended configuration is not available" and falls back to PCI 3.0 ports. On modern Q35 + i440fx the MMIO path is always available, so the fallback rarely fires.
|
||
|
||
#### Quirks applied
|
||
|
||
Per pcid/src/quirks.rs (Blocker 1) and the data path:
|
||
|
||
```
|
||
PciDevice::full_info() // pcid internal
|
||
→ build_device_info // quirks.rs:120-200
|
||
→ PciDeviceInfo::quirks() // redox-driver-sys/src/quirks/pci_table.rs + toml_loader.rs + dmi.rs
|
||
→ PciQuirkFlags (bitwise OR of all matching entries)
|
||
→ apply_pci_quirks // pcid/src/quirks.rs (Blocker 1, 12 unit tests)
|
||
```
|
||
|
||
In pcid, the PciConfigWriter loop executes `QuirkAction::execute` for each matching entry with a non-`None` action. The first action wins per device. Per QUIRKS-SYSTEM.md R4, ~30% of Linux PCI quirks are imperative config-space writes; this is the gate for that.
|
||
|
||
#### LoC estimate
|
||
|
||
- Hot-plug pcid: ~600 LoC
|
||
- DMI-matched spawner: ~300 LoC
|
||
- aarch64 PCIe ECAM: ~500 LoC
|
||
- Cap-walk improvements: ~200 LoC
|
||
|
||
**Total**: ~1,600 LoC. 4–6 weeks with 1 dev.
|
||
|
||
#### Time estimate
|
||
|
||
4–6 weeks. Most changes are non-urgent for QEMU x86_64 (which is the user's primary path); the aarch64 fallback is future-proofing.
|
||
|
||
|
||
### 5. Display Chain (CRITICAL)
|
||
|
||
This is the longest section because it is the user's primary blocker. The display chain is the only place where the project's stated policy ("vesad only as early-boot FB handoff; primary display is /scheme/drm/card0") is in tension with the code.
|
||
|
||
#### 5.1 vesad
|
||
|
||
**Location**: `local/sources/base/drivers/graphics/vesad/` (408 LoC: main.rs:133, scheme.rs:275)
|
||
**Purpose**: Boot framebuffer handoff from bootloader (linear framebuffer set up by UEFI/BIOS) to userspace daemons.
|
||
|
||
**What works**:
|
||
- Parses `FRAMEBUFFER_{WIDTH,HEIGHT,ADDR,STRIDE}` env vars from bootloader (`vesad/src/main.rs:25-44`).
|
||
- Supports up to 1024 `FRAMEBUFFER1..1023` env entries for multi-display boot (`vesad/src/main.rs:60-84`).
|
||
- Registers the scheme as `display.vesa` (`vesad/src/main.rs:86-87`):
|
||
```rust
|
||
let mut scheme =
|
||
GraphicsScheme::new(FbAdapter { framebuffers }, "display.vesa".to_owned(), true);
|
||
```
|
||
- Implements `GraphicsAdapter` with `DumbBuffer` and `Sync` (via `vesad/src/scheme.rs:83-138`).
|
||
- Forwards input events from `inputd` via `inputd_event_handle` (`vesad/src/main.rs:99-104`).
|
||
- Uses `setrens(0,0)` to detach from the root namespace once registered (`vesad/src/main.rs:113`).
|
||
|
||
**Stubs / half-impls**:
|
||
1. **`unimplemented!()` panic on cursor plane operations** — `vesad/src/scheme.rs:146`:
|
||
```rust
|
||
fn handle_cursor(&mut self, _cursor: &CursorPlane<Self::Buffer>, _dirty_fb: bool) {
|
||
unimplemented!("Vesad does not support this function");
|
||
}
|
||
```
|
||
Any client that sets a DRM cursor will trigger this panic. The boot does not use cursors so this is dormant in `redbear-full`, but `redox-drm` might try to use `drmModeSetCursor` and propagate through the same `GraphicsAdapter` trait.
|
||
|
||
2. **`GraphicsScheme::new(..., true)` — the third `true` argument** — `vesad/src/main.rs:87`:
|
||
This passes `block = true` (or similar) to the scheme constructor. Means `vesad` accepts a `block` flag where clients can wait for the device. Compatible with the early-boot handoff.
|
||
|
||
3. **`//TODO: ideal maximum number of outputs?`** at `vesad/src/main.rs:59` — 1024 is hard-coded. Cosmetic.
|
||
|
||
4. **No handover logic to `redox-drm`** — `vesad/src/scheme.rs` has no path that says "if DRM scheme registers, drop my scheme". The user must rely on the application (KWin/SDDM/redbear-compositor) to prefer `/scheme/drm/card0` over `/scheme/display.vesa`.
|
||
|
||
**Policy violation (project AGENTS.md "NO VESA POLICY")**:
|
||
|
||
> All display output goes through the DRM/KMS path via real GPU drivers. ... vesad is allowed ONLY as an early-boot framebuffer handoff. ... Once redox-drm initializes and registers scheme:drm/card0, vesad must hand off and NOT register scheme:display.vesa as the primary display surface.
|
||
|
||
The code does NOT implement this handoff. `vesad` registers `display.vesa` as a full scheme and never unregisters it. The intended design is that an app (KWin, redbear-compositor) should refuse to use `display.vesa` and only use `drm/card0`. The initfs order in `init.initfs.d/`:
|
||
|
||
| Order | Service | Purpose |
|
||
|-------|---------|---------|
|
||
| 10 | `inputd` | Input multiplexer |
|
||
| 20 | `vesad` | FB handoff |
|
||
| 20 | `fbcond` | Text console on FB |
|
||
| 20 | `fbbootlogd` | Boot log on FB |
|
||
|
||
→ there is NO `redox-drm` service in `init.initfs.d/`. The initfs is intentionally VESA-only for early text console output.
|
||
|
||
For rootfs (`redbear-full.toml`):
|
||
| Order | Service | Source |
|
||
|-------|---------|--------|
|
||
| 5 | `boot-essential.target` | `redbear-full.toml:258-266` |
|
||
| 4 | `drivers.target` | inherited (rootfs `/usr/lib/init.d/04_drivers.target` — in base pkg) |
|
||
| 5 | `boot-essential.target` | includes drivers.target |
|
||
| 10 | `redox-drm.service` | `redbear-full.toml:283-297` — starts if `/scheme/drm/card0` is not registered yet |
|
||
| 12 | `dbus.service` | `redbear-full.toml:299-313` |
|
||
| 12 | `sddm.service` | `redbear-full.toml:448-467` |
|
||
| 13 | `redbear-sessiond.service` | `redbear-full.toml:315-327` |
|
||
| 13 | `seatd.service` | `redbear-full.toml:329-343` |
|
||
| 11 | `redbear-authd.service` | `redbear-full.toml:433-446` |
|
||
| 30 | `console.service` | `redbear-full.toml:469-482` |
|
||
|
||
`10_redox-drm.service` is a shell wrapper that does:
|
||
```bash
|
||
if ! head -c 1 /scheme/drm/card0 >/dev/null 2>&1; then exec /usr/bin/redox-drm; fi
|
||
```
|
||
This is a one-shot startup; once `redox-drm` is alive the file is in `/scheme/drm/`. The initfs-side `vesad` continues to run (no exit), and continues to expose `display.vesa` for the lifetime of the initfs. The rootfs is a different scheme tree.
|
||
|
||
For the **transition** initfs → rootfs, what happens:
|
||
- Init's `switch_root` at `init/src/main.rs:143-148` re-mounts the rootfs.
|
||
- The initfs daemons (`vesad`, `fbcond`, `fbbootlogd`, `acpid`, `hwd`, `pcid-spawner --initfs`) are not killed by `switch_root` (Redox `switch_root` is implemented as a logical remount, not a process kill).
|
||
- The rootfs daemons (same names, plus `redox-drm`) start fresh.
|
||
- The result is two parallel `vesad`s — one from initfs, one from rootfs (if it's in the rootfs service set; it isn't in `redbear-full.toml`).
|
||
|
||
This is a real issue. There is no per-scheme-generation governance; only `redox-drm` has the "don't register if already exists" check (`redox-drm/src/main.rs:62-66`).
|
||
|
||
**Missing wirings**:
|
||
- No `vesad` shutdown signal in the rootfs init sequence.
|
||
- No DRM scheme handoff acknowledgement.
|
||
- The initfs's `vesad` registers `display.vesa` and the rootfs's apps have no way to know that "DRM is now available, please use that instead of me".
|
||
|
||
**Stale code**:
|
||
- `vesad/src/scheme.rs:9-12` imports from `drm_sys::` — this is the legacy pre-2024 `drm` crate namespace. The `drm` crate is being phased out in favour of `drm-sys` and the new `redox_drm::` API. The `vesad` build still depends on the old name.
|
||
- `vesad/src/main.rs:1` `extern crate orbclient` — `orbclient` is the legacy Orbital graphics API. It is still used in `console-draw`, `fbcond`, `fbbootlogd` but the new graphics stack should not depend on it.
|
||
|
||
**LoC estimate**:
|
||
- Add handoff: ~300 LoC
|
||
- Remove Orbital dependency: ~400 LoC
|
||
- Multi-output support beyond 1024: ~100 LoC
|
||
|
||
**Total**: ~800 LoC. 2 weeks with 1 dev.
|
||
|
||
#### 5.2 fbcond (Framebuffer text console)
|
||
|
||
**Location**: `local/sources/base/drivers/graphics/fbcond/` (671 LoC: main.rs:253, scheme.rs:193, display.rs:91, text.rs:134)
|
||
|
||
**What works**:
|
||
- Opens a VT via `ConsumerHandle::new_vt()` (`fbcond/src/main.rs:14-23`).
|
||
- Subscribes to the scheme socket and to input events.
|
||
- Handles `VtIndex::SCHEMA_SENTINEL` (scheme events) and per-VT input events (`fbcond/src/main.rs:91-189`).
|
||
- `handle_handoff()` re-opens the display via the inputd v2 protocol when `redox-drm` becomes available (`fbcond/src/display.rs:25-58`).
|
||
|
||
**Stubs / half-impls**:
|
||
1. **`// FIXME listen for resize events from inputd and handle them`** — `fbcond/src/main.rs:36`. The framebuffer's `handle_resize` is implemented (`fbcond/src/display.rs:60-82`) but no event subscription. A window resize triggers a re-render only at the next VTSwitch.
|
||
2. **`setrens(0,0)` is commented out** — `fbcond/src/main.rs:53-54`:
|
||
```rust
|
||
// This is not possible for now as fbcond needs to open new displays at runtime for graphics
|
||
// driver handoff. In the future inputd may directly pass a handle to the display instead.
|
||
// libredox::call::setrens(0, 0).expect("fbcond: failed to enter null namespace");
|
||
```
|
||
fbcond intentionally keeps its namespace root so it can `ConsumerHandle::open_display_v2()` when DRM comes online. This is correct but means a "vesad" malicious client could attach to the same VTs.
|
||
3. **`_ => (), //TODO: Mouse in terminal`** — `fbcond/src/text.rs:98`. Mouse events in the text console are dropped.
|
||
4. **Per `fbcond/src/display.rs:34-39`** the V2GraphicsHandle parser logs `Display v2 not available: {err}` and returns silently. If the inputd-side API has a wrong version, the user gets a black screen with no error visible.
|
||
5. **`scheme.rs:162` `eprintln!("vesad: failed to write display scheme")`** — should be `fbcond: failed to write display scheme`. Cosmetic but reflects a copy-paste from vesad.
|
||
|
||
**LoC estimate**: ~300 LoC for mouse + resize.
|
||
|
||
**Time**: 1–2 weeks.
|
||
|
||
#### 5.3 fbbootlogd (Boot log on framebuffer)
|
||
|
||
**Location**: `local/sources/base/drivers/graphics/fbbootlogd/` (365 LoC: main.rs:115, scheme.rs:250)
|
||
|
||
**What works**:
|
||
- Subscribes to logd via `add_sink` (`fbbootlogd/src/main.rs:62-71`).
|
||
- Same handoff pattern as fbcond.
|
||
- Has scrollback via `Shift+PgUp/PgDown` (only with keyboard held).
|
||
|
||
**Stubs / half-impls**:
|
||
1. Same `setrens(0,0)` comment as fbcond.
|
||
2. `fbbootlogd/src/scheme.rs:38` calls `handle_handoff()` in `new()` — a no-op until `redox-drm` is up. On a system where redox-drm fails, fbbootlogd shows a black screen.
|
||
|
||
**LoC estimate**: 0 — the boot log is well-implemented for the simple case.
|
||
|
||
**Time**: 0 days.
|
||
|
||
|
||
#### 5.4 redox-drm (DRM/KMS scheme daemon)
|
||
|
||
**Location**: `local/recipes/gpu/redox-drm/source/` (130 Rust files, ~30,332 LoC; main.rs:815)
|
||
**Purpose**: GPU driver manager. Detects AMD, Intel, or virtio-gpu hardware, loads the right driver, exposes `/scheme/drm/card0` with the standard DRM/KMS uAPI.
|
||
|
||
**What works** (per project plan and code-level inspection):
|
||
- Vendor detection at `redox-drm/source/src/main.rs:217-228` for `PCI_VENDOR_ID_AMD` (0x1002), `PCI_VENDOR_ID_INTEL` (0x8086), `0x1AF4` (VirtIO).
|
||
- `PcidClient` handoff for the pcid-spawner case (`redox-drm/src/main.rs:205-215`).
|
||
- Firmware loading via `FirmwareCache` (`redox-drm/src/main.rs:274-400`).
|
||
- Scheme registration at `/scheme/drm` via `register_sync_scheme(&socket, "drm", ...)` (`redox-drm/src/main.rs:129`).
|
||
- Self-de-duplication: if `scheme:drm` is already registered, it does not start (`redox-drm/src/main.rs:62-66, 131-134`).
|
||
- Two IRQ event threads: handle_irq + poll_hotplug (`redox-drm/src/main.rs:84-111, 116-122`).
|
||
- 30+ KB of kernel-style driver code (intel/amd/virtio subdirs).
|
||
|
||
**Stubs / half-impls**:
|
||
1. **The driver code is in a build-only state** — per CONSOLE-TO-KDE-DESKTOP-PLAN.md, the Intel driver is 4042 LoC (`local/sources/base/drivers/graphics/ihdgd/`) AND the imported `redox-drm` Intel code is in `local/recipes/gpu/redox-drm/source/src/drivers/intel/` with 838 LoC of workarounds alone (`workarounds.rs`). Both exist; the upstream `ihdgd` is a clean-room Intel driver and the imported `redox-drm/intel` is the Linux i915 port. Per the plan they are alternative paths; per the config `redox-full.toml:62` `redox-drm = {}` is the chosen one.
|
||
2. **The AMD DC port** in `local/recipes/gpu/amdgpu/` is "ignore" in `redbear-full.toml:157`. The comment `amdgpu = {} # TODO: fix conflicting idr_* defs with linux-kpi headers` shows the integration is blocked on header conflicts.
|
||
3. **Per the project's "Intel i915-like via redox-drm"** target, the bounded Red Bear display glue path is the *real* path, not the i915-style `ihdgd` driver. The status in the plan: "Intel driver compiles, no HW validation yet". For QEMU virtio-gpu the build is exercised; for Intel HW it is compile-only.
|
||
4. **Many `// FIXME` and `// TODO` in `local/sources/base/drivers/graphics/driver-graphics/src/`** (the legacy i915-style `ihdgd` path):
|
||
- `lib.rs:222` `// FIXME notify clients`
|
||
- `lib.rs:537` `// FIXME fill x and y with the data from the primary plane`
|
||
- `lib.rs:852` `// FIXME use a better scheme for creating map offsets`
|
||
- `lib.rs:893` `// FIXME remove once all drm objects are materialized in self.objects`
|
||
- `kms/connector.rs:38, 161, 177, 243` — connector enumeration is hard-coded to one
|
||
- `kms/properties.rs:26, 30` — property IDs overlap
|
||
|
||
5. **KMS EDID stub** — `local/sources/base/drivers/graphics/ihdgd/src/device/scheme.rs:1, 46, 64, 75, 138`:
|
||
```rust
|
||
//TODO: this is copied from vesad and should be adapted
|
||
...
|
||
// FIXME enumerate actual connectors
|
||
...
|
||
// FIXME fetch EDID
|
||
...
|
||
unimplemented!("ihdgd does not support this function");
|
||
```
|
||
This is the OLD path (`ihdgd` in `local/sources/`). The new path (`redox-drm` in `local/recipes/`) has real EDID parsing per the `firmware_expectation` machinery.
|
||
|
||
**Quirks consumed**:
|
||
- `redox-drm` calls `info.quirks()` (the consumer-side helper) to retrieve `PciQuirkFlags`. Per QUIRKS-SYSTEM.md Gap 11, the audit misread this and it is **ALREADY RESOLVED** — the lookup is correct. The QEMU virtio-gpu path does not need most flags; the AMD/Intel paths would need `NEED_FIRMWARE`, `DISABLE_ACCEL`, `NO_MSIX`, `RESET_DELAY_MS`, and the drm panel orientation (R12, deferred until compositor rotation lands).
|
||
|
||
**LoC estimate**:
|
||
- 5.4.4: ~500 LoC for notify + plane data + map offset + object materialization
|
||
- 5.4.5: ihdgd is the legacy path; if the project keeps both it is ~1,500 LoC; if the project deprecates ihdgd in favour of redox-drm, those LoC become dead code to remove
|
||
|
||
**Total (for QEMU virtio-gpu path)**: 0–500 LoC. For AMD/Intel HW path: 1,500+ LoC.
|
||
|
||
**Time**: 1–2 weeks for QEMU polish; 8–12 weeks for real HW validation.
|
||
|
||
#### 5.5 virtio-gpud (the legacy path; superseded by redox-drm)
|
||
|
||
**Location**: `local/sources/base/drivers/graphics/virtio-gpud/` (1,143 LoC: main.rs:615, scheme.rs:528)
|
||
|
||
**Stale code**:
|
||
- The `initfs.toml` references `virtio-gpud` (line 32-37) and `redbear-full.toml:621-630` references `virtio-gpud` config but the daemon itself is the legacy DRM/KMS scheme daemon. With `redox-drm` now owning the drm scheme (`/scheme/drm/card0`), `virtio-gpud` would conflict.
|
||
- `virtio-gpud/src/main.rs:3`:
|
||
```rust
|
||
//! XXX: 3D mode will offload rendering ops to the host gpu and therefore requires a GPU with 3D support
|
||
```
|
||
- `virtio-gpud/src/main.rs:35-40` defines feature flags that are commented out — `VIRTIO_GPU_F_VIRGL`, `VIRTIO_GPU_F_RESOURCE_UUID`, `VIRTIO_GPU_F_RESOURCE_BLOB`, `VIRTIO_GPU_F_CONTEXT_INIT`. Without these the 3D path is unavailable, which is what the project plan expects for Phase 5 (Mesa with virgl).
|
||
|
||
**Conflict with redox-drm**: both register as a DRM scheme. The `redox-drm` daemon has the EEXIST check (`redox-drm/src/main.rs:131`) so a second one exits cleanly. But the `initfs.toml` still points at `virtio-gpud`; the `redbear-full.toml:622-630` `virtio-gpud.toml` is also a parallel config. **The user should remove `virtio-gpud` from the initfs.toml and rely on `redox-drm` exclusively.** This is a real, present-day misconfiguration.
|
||
|
||
**Time to fix**: 0.5 day. Edit `initfs.toml` to remove the `virtio-gpud` entry; the initfs pcid-spawner will not spawn it, and `redox-drm` from rootfs will own `/scheme/drm/card0`.
|
||
|
||
#### 5.6 redbear-compositor (Bounded Wayland compositor)
|
||
|
||
**Location**: `local/recipes/wayland/redbear-compositor/` (5,083 LoC: main.rs:2,180, display_backend.rs:483, handlers.rs:388, protocol.rs:177, state.rs:198, wire.rs:197, tests/integration_test.rs:615, bin/redbear-compositor-check.rs:845)
|
||
|
||
**What works**:
|
||
- Creates a Wayland Unix socket and speaks a bounded core Wayland protocol.
|
||
- Supported protocols: `wl_display`, `wl_registry`, `wl_compositor`, `wl_shm`, `wl_shm_pool`, `wl_surface`, `wl_shell`, `wl_shell_surface`, `wl_seat`, `wl_output`, `wl_callback`, `wl_buffer`, `wl_fixes` (`main.rs:14-15`).
|
||
- Opens `/scheme/drm/card0` via the `drm_backend` module (`display_backend.rs:93-483`) with hard-coded ioctl numbers: `DRM_IOCTL_MODE_GETCONNECTOR=0xA7`, `DRM_IOCTL_MODE_SETCRTC=0xA2`, `DRM_IOCTL_MODE_CREATE_DUMB=0xB2`, `DRM_IOCTL_MODE_MAP_DUMB=0xB3`, `DRM_IOCTL_MODE_ADDFB=0xB5`, `DRM_IOCTL_MODE_PAGE_FLIP=0xB0`.
|
||
- Falls back to a 1280x720 framebuffer if `/scheme/drm/card0` is absent (`display_backend.rs:35-50`).
|
||
|
||
**Stubs / half-impls**:
|
||
1. **Self-described as "bounded proof scaffold"** — `main.rs:1-15`:
|
||
```rust
|
||
// Red Bear Wayland Compositor — bounded Wayland compositor proof scaffold.
|
||
// Replaces the KWin stub that previously created a placeholder socket.
|
||
//
|
||
// NOTE: This is a bounded proof scaffold, not a real compositor runtime proof.
|
||
// Known limitations: framebuffer compositing uses private heap memory (not real
|
||
// vesad), only a bounded subset of Wayland is implemented, and the compositor
|
||
// still paints directly into a simple backing buffer instead of doing real KMS
|
||
// scanout.
|
||
```
|
||
2. **Fallback framebuffer uses `map_framebuffer(_phys, size) -> Vec<u8>` with `vec![0u8; size]`** — `display_backend.rs:1-3`. When DRM is absent, the compositor paints into heap, not into the boot FB. The window is then lost on the next vsync.
|
||
3. **Hard-coded dimensions** — `display_backend.rs:36-46`:
|
||
```rust
|
||
let width: u32 = std::env::var("FRAMEBUFFER_WIDTH")
|
||
.unwrap_or_else(|_| "1280".into())
|
||
...
|
||
```
|
||
This is the FB env vars from the bootloader. On QEMU these are set by the BIOS to 1280x720; on real HW they reflect the UEFI GOP.
|
||
4. **No `xdg-shell` support** — only `wl_shell`. Per the plan v6.0, KWin is the canonical compositor; redbear-compositor is greeter-only. The greeter is `redbear-greeter`, not this binary.
|
||
5. **The hand-rolled `drm_backend` reimplements DRM ioctls from scratch** — `display_backend.rs:38-450` and `main.rs:38-450`. This is ~1,000 LoC of bespoke protocol that is duplicated in `redox-drm`. The 2 implementations will diverge; the canonical should be `redox-drm`. CONSOLE-TO-KDE-DESKTOP-PLAN.md says "redbear-compositor is **not** extended to production quality — instead it serves only the greeter phase".
|
||
|
||
**Missing wirings**:
|
||
- No IPC to KWin. The plan calls for a "compositor handoff" but it is not specified how redbear-compositor stops and KWin starts. KWin in this config (`/usr/share/wayland-sessions/plasmawayland.desktop:597-601`) runs `kwin_wayland --drm /scheme/drm/card0` — it ignores redbear-compositor entirely. The sessiond model assumes one compositor at a time and a clean process boundary.
|
||
|
||
**LoC estimate**:
|
||
- Replace bespoke drm_backend with redox-drm ioctl proxy: ~500 LoC removal
|
||
- Add xdg-shell: ~600 LoC
|
||
- Add compositor handoff to KWin: ~300 LoC
|
||
|
||
**Total**: ~1,400 LoC. 3–4 weeks.
|
||
|
||
#### 5.7 KWin
|
||
|
||
**Location**: `local/recipes/kde/kwin/source/` (38,591 LoC of upstream C++; recipe.toml:187)
|
||
|
||
**What works (per recipe + plan)**:
|
||
- Builds the KWin 6.3.4 upstream source with the toolchain.
|
||
- Real Wayland backend; real DRM/KMS; real libinput; real KF6 plumbing.
|
||
- Compiles with `KWIN_BUILD_X11=OFF` and many other features off (recipe.toml:155-165):
|
||
- `KWIN_BUILD_AUTO_ROTATION=OFF`
|
||
- `KWIN_BUILD_X11=OFF`
|
||
- `KWIN_BUILD_X11_BACKEND=OFF`
|
||
- `KWIN_BUILD_KCMS=OFF`
|
||
- `KWIN_BUILD_SCREENLOCKER=OFF`
|
||
- `KWIN_BUILD_TABBOX=OFF`
|
||
- `KWIN_BUILD_GLOBALSHORTCUTS=OFF`
|
||
- `KWIN_BUILD_RUNNERS=OFF`
|
||
- `KWIN_BUILD_NOTIFICATIONS=OFF`
|
||
- `KWIN_BUILD_ACTIVITIES=OFF`
|
||
- `KWIN_BUILD_EIS=OFF`
|
||
- Custom `sed` patches to strip X11 paths, accept `accept()` without `SOCK_CLOEXEC`, define `SUN_LEN`, `F_ADD_SEALS` macros.
|
||
- Custom `qtwaylandscanner` build path for `kde` flavor.
|
||
|
||
**Stubs / half-impls (recipe level)**:
|
||
1. **`#TODO: KWin — full build with Qt6Quick/QML. Effect frames, scripted effects, OSD overlay, outline overlay all enabled.`** at `recipe.toml:1`. The honest policy: KWin compiles but most of its KCM (KControl Module) UI is disabled because Qt6 QML doesn't work on Redox.
|
||
2. **`# CMakeLists.txt stripped: killer (X11-only) subdirectory disabled`**: `recipe.toml:84`. The X11 session killer is not built; the Wayland path is.
|
||
3. **`UiTools` dependency removed**: `recipe.toml:82`. KCM UI builder dependency disabled.
|
||
4. **`Canberra` made optional**: `recipe.toml:79-83, 64`. Sound effects on focus changes fall back to no-op.
|
||
5. **Custom `host` build of `qtwaylandscanner_kde`**: `recipe.toml:122-135`. A host-built scanner binary is required because KWin's CMakeLists has a Qt6 custom build of this tool.
|
||
|
||
**`*-stub` dependencies** (anti-pattern, per project AGENTS.md):
|
||
- `libepoxy-stub` — provides `epoxy::epoxy` cmake target, but the `.so` is a 6-symbol stub returning 0 (`local/recipes/libs/libepoxy-stub/recipe.toml:1`). Used by KWin for EGL/GLX function loading; with this stub, every `epoxy_has_gl_extension("GL_EXT_...")` returns 0 and KWin thinks no extensions are supported.
|
||
- `libxcvt-stub` — returns 0 from CVT mode calculation (`local/recipes/libs/libxcvt-stub/recipe.toml:1`).
|
||
- `libdisplay-info-stub` — bounded EDID parser; claims to handle base EDID but stubs out CTA/DisplayID (`local/recipes/libs/libdisplay-info-stub/recipe.toml:1`).
|
||
- `lcms2-stub` — color management; all `cmsDoTransform`-style functions are no-ops (`local/recipes/libs/lcms2-stub/recipe.toml:1`).
|
||
- `libudev-stub` — KWin needs libudev to enumerate input devices; the stub returns empty lists. Per `libinput/recipe.toml:18`, libinput also depends on this. Real device discovery is broken; the user has no way to attach a keyboard/mouse to a session.
|
||
|
||
**LoC estimate**:
|
||
- Remove `*-stub` dependencies in favour of real libraries: ~2,500 LoC (libepoxy ~1,200; libxcvt ~300; libdisplay-info ~600; lcms2 ~400)
|
||
- Enable KWIN_BUILD_QML_UI: ~4,000 LoC of QML/Quick integration on the Redox side
|
||
- Enable KWIN_BUILD_SCREENLOCKER + KCMS + TABBOX + GLOBALSHORTCUTS: ~1,200 LoC
|
||
|
||
**Total**: ~7,700 LoC. 12–16 weeks.
|
||
|
||
#### 5.8 SDDM
|
||
|
||
**Location**: `local/recipes/kde/sddm/source/` (38,591 LoC; recipe.toml:108)
|
||
|
||
**What works (per recipe)**:
|
||
- Builds SDDM 0.21 (commit `bc9eee8280275723767213220e88f6b14157ba1f`) with Wayland-only path.
|
||
- Disables X11/XCB/XKB/XAU paths via CMake `find_package(.* QUIET)` and `pkg_check_modules(.* QUIET)` (recipe.toml:48-60).
|
||
- Patches `ioctl(STDIN_FILENO, TIOCSCTTY, NULL)` for relibc.
|
||
- Removes `XAuth.cpp` from the helper.
|
||
- Provides stubs in `stubs/linux/{kd.h,vt.h}` and `stubs/{utmpx.h,X11/Xauth.h}` for missing POSIX/header bits.
|
||
- PAM provided by `pam-redbear` shim (`local/recipes/libs/pam-redbear/recipe.toml:1-30`).
|
||
- Compiles.
|
||
|
||
**Stubs / half-impls**:
|
||
1. **`#TODO: SDDM display manager — Wayland-only build. PAM provided by pam-redbear shim.`** at `recipe.toml:1`. The plan is to make the build honest, but multiple X11 bits are still touched.
|
||
2. **`sddm/source/src/daemon/DisplayManager.cpp:156, 160, 164, 195`**: 4 `// TODO: IMPLEMENT` markers in the daemon. These are the `addLocalDisplay`, `addRemoteDisplay`, `addSocketDisplay`, and similar entry points. They return false or empty.
|
||
3. **`sddm/source/src/daemon/DaemonApp.h:42`**: `// TODO: move these two away`.
|
||
4. **`stubs/X11/Xauth.h` (19 lines)** and **`stubs/linux/{kd.h,vt.h}` (50 lines combined)** — these are SDDM-local header shims that pretend to provide X11/ConsoleKit interfaces. They are necessary for the source to compile but they are not real implementations. Anything that uses them at runtime is a no-op.
|
||
5. **`pam-redbear` is a stub too** (`local/recipes/libs/pam-redbear/recipe.toml:1-30`): a 5-symbol shared library that proxies auth to `redbear-authd` via Unix socket JSON. Real, but thin.
|
||
|
||
**Real config wiring (`redbear-full.toml:567-590`)**:
|
||
- `/etc/sddm.conf` is hand-installed with the right env vars and the `CompositorCommand=/usr/libexec/sddm-helper-start-wayland kwin_wayland --drm /scheme/drm/card0`.
|
||
- `/usr/share/wayland-sessions/plasmawayland.desktop` is hand-installed.
|
||
|
||
**LoC estimate**:
|
||
- 4 `// TODO: IMPLEMENT` in `DisplayManager.cpp`: ~400 LoC
|
||
- Real `pam-redbear` PAM module (replace the JSON socket with proper PAM API): ~600 LoC
|
||
|
||
**Total**: ~1,000 LoC. 3–4 weeks.
|
||
|
||
|
||
#### 5.9 redbear-sessiond (login1 D-Bus broker)
|
||
|
||
**Location**: `local/recipes/system/redbear-sessiond/source/` (2,017 LoC: main.rs:188, manager.rs:642, session.rs:450, device_map.rs:267, control.rs:221, seat.rs:147, acpi_watcher.rs:48, runtime_state.rs:54)
|
||
|
||
**What works (no TODOs found in the source)**:
|
||
- Implements `org.freedesktop.login1` D-Bus interface (subset for KWin's needs).
|
||
- Seats, sessions, device map, ACPI watcher.
|
||
- Service registered as `13_redbear-sessiond.service` in `redbear-full.toml:315-327`, depends on `12_dbus.service`.
|
||
- D-Bus activation: built as a Rust binary using `zbus`.
|
||
|
||
**Stubs / half-impls**:
|
||
None found via grep `todo!|unimplemented!|TODO|FIXME`. The sessiond appears complete for the login1 subset the project needs.
|
||
|
||
**Quirks**: not directly; the consumer of D-Bus signals from `acpid` is the `acpi_watcher.rs` module.
|
||
|
||
**LoC estimate**: 0 LoC. Likely ready.
|
||
|
||
#### 5.10 redbear-authd (Authentication daemon)
|
||
|
||
**Location**: `local/recipes/system/redbear-authd/source/src/main.rs` (719 LoC)
|
||
|
||
**What works**: PAM-equivalent auth. Reads `/etc/passwd` and `/etc/shadow`. Serves via `pam-redbear` shim.
|
||
|
||
**Stubs**: None found in `main.rs`.
|
||
|
||
**LoC estimate**: 0 LoC. Likely ready.
|
||
|
||
#### 5.11 Display handover
|
||
|
||
Per project policy (`AGENTS.md` "NO VESA POLICY"):
|
||
|
||
> Once redox-drm initializes and registers scheme:drm/card0, vesad must hand off and NOT register scheme:display.vesa as the primary display surface.
|
||
|
||
**Implementation reality**: The handoff is **not implemented**. The initfs's `vesad` runs, registers `display.vesa`, and never exits. The rootfs's `redox-drm` is started by `10_redox-drm.service` after `05_boot-essential.target` is reached. The shell wrapper in `10_redox-drm.service` checks `/scheme/drm/card0` and starts `redox-drm` if it is not yet registered. The user has no signal that handoff happened; the apps that pick `/scheme/drm/card0` over `/scheme/display.vesa` are the only place the policy is enforced.
|
||
|
||
**What "real" handoff would look like**:
|
||
- `redox-drm` registers a notifier on `/scheme/drm/card0` ready event.
|
||
- `vesad` listens for that event and tears down `display.vesa`.
|
||
- `fbcond` and `fbbootlogd` re-open the display via the v2 inputd handle (`ConsumerHandle::open_display_v2()` — already implemented at `fbcond/src/display.rs:27` and `fbbootlogd/src/scheme.rs:44`).
|
||
- During the brief window, an app that opens `/scheme/display.vesa` should be told "vesa is going away, use drm".
|
||
|
||
**This is the primary concrete "policy violation in the code" finding.**
|
||
|
||
#### 5.12 D-Bus activation, seatd, redbear-sessiond
|
||
|
||
**D-Bus activation**: SDDM is launched as `oneshot_async` (redbear-full.toml:466) but does not call `dbus-daemon --address=...` from SDDM — the sessiond broker is separate (`13_redbear-sessiond.service`). SDDM's D-Bus activation of KWin requires:
|
||
1. The D-Bus system bus socket at `/run/dbus/system_bus_socket` (env: `DBUS_SYSTEM_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket` — `redbear-full.toml:649-651`).
|
||
2. The session bus is normally started by SDDM's greeter; in this config, `dbus-launch` is not present, so the session bus is whatever SDDM provides natively.
|
||
3. `redbear-sessiond` is the system bus broker for `org.freedesktop.login1`.
|
||
|
||
**Status**: All three services are present and ordered. The `12_sddm.service` requires `00_driver-manager.service`, `10_redox-drm.service`, `10_evdevd.service`, `12_dbus.service`, `13_redbear-sessiond.service`, `13_seatd.service`, `11_redbear-authd.service` — all of which are in the config.
|
||
|
||
**Missing**: `redbear-full.toml:516-529` defines `99_kwin_test.service` which runs `zsh -c "sleep 30; echo '=== FS DIAG ==='; ls -lad /tmp /var/log /var/run /run; ..."` — this is a diagnostic placeholder, not a real service. The text in the service file is a *shell script* in the data field, not a separate script. This is a real anti-pattern: large multi-line shell scripts inside TOML strings. Should be a real `.sh` file in `/usr/lib/redbear-diag/`.
|
||
|
||
**seatd**: `local/recipes/system/seatd/` (upstream 0.9.1) with the Red Bear build flags. Compiles, registers a Unix socket. Per `redbear-full.toml:540-545` the user is created (`sddm` uid 102) but `/var/run/seatd.sock` is not pre-created in the config. SDDM expects to talk to seatd at `SEATD_SOCK=/var/run/seatd.sock` (per `redbear-full.toml:527`).
|
||
|
||
|
||
### 6. Quirk System
|
||
|
||
**Location**: `local/recipes/drivers/redox-driver-sys/source/src/quirks/` (8 files)
|
||
**TOML data**: `local/recipes/system/redbear-quirks/source/quirks.d/` (22 files)
|
||
**Document**: `local/docs/QUIRKS-SYSTEM.md` (3,803 lines)
|
||
|
||
**Status as of 2026-06-09**: ALL phases R0-R22 RESOLVED OR DEFERRED. 131 host-buildable unit tests + 13 acpid + 12 pcid + 7 usbhidd + 4 evdevd + 3 iwlwifi = **170 host-or-target tests**.
|
||
|
||
#### What works (per QUIRKS-SYSTEM.md + code-level inspection)
|
||
|
||
| Subsystem | Bit count | Compiled-in entries | TOML entries | Consumer |
|
||
|-----------|-----------|---------------------|--------------|----------|
|
||
| `PciQuirkFlags` | 46 (bits 0-45) | ~50 in `pci_table.rs` | 30+ in `redbear-quirks/quirks.d/*.toml` | pcid (full), amdgpu (full), redbear-drm (full), xhcid (partial), usbhidd (full), evdevd (full), iwlwifi (full) |
|
||
| `UsbQuirkFlags` | 22 (bits 0-21) | multiple in `usb_table.rs` | `20-usb.toml` | usbhidd, xhcid |
|
||
| `HidQuirkFlags` | 24 (bits, with gaps to match Linux) | 9 in `hid_table.rs` | `40-hid.toml` | evdevd |
|
||
| `XhciControllerQuirkFlags` | 22 (bits, matching Linux) | 10+ in `xhci_controller_table.rs` | n/a (PCI-keyed) | xhcid (Blocker 4 partial) |
|
||
| `AcpiQuirkFlags` | 16 (bits 0-15) | empty initial | `47-acpi-button.toml` (18 rules) | acpid (in the table, deferred) |
|
||
| `DrmPanelOrientation` | 4 values | n/a | `50-drm-panel.toml` (36 entries) | redox-drm (deferred until Phase 4) |
|
||
| `PlatformDmiQuirkFlags` | 7 (bits 0-6) | n/a | 31 entries in `80-platform-x86.toml` | inputd, acpid, thermald (deferred) |
|
||
| `CpuBugFlags` | 27 (bits 0-26) | empty initial | 14 entries in `90-cpu-bugs.toml` | kernel (deferred) |
|
||
| `ClocksourceQuirkFlags` | 4 (bits 0-3) | 3 in `clocksource` | `35-clocksource.toml` | kernel (deferred) |
|
||
| `ChipsetQuirkFlags` | 10 (bits 0-9) | 11 in `55-chipset-early.toml` | (same TOML) | kernel (deferred) |
|
||
| `UsbAudioQuirkFlags` | 29 (bits 0-28) | empty initial | 30 entries in `60-usb-audio.toml` | redbear-usbaudiod (deferred) |
|
||
| DMI | struct + parser | full | `47-acpi-button.toml` etc. | acpid (DMI producer), all consumers (DMI match) |
|
||
|
||
#### Stubs / half-impls
|
||
|
||
None found in the quirks *data model* and *lookup* path. The code is exercised by 131 host-buildable unit tests. The data tables are complete.
|
||
|
||
#### Missing consumer wirings (per QUIRKS-SYSTEM.md)
|
||
|
||
These are the explicit "deferred until consumer lands" gaps:
|
||
|
||
1. **R12 (DrmPanelOrientation)**: Consumer in `redox-drm` is deferred until compositor rotation lands. The 36-entry table is correct data; the consumer reads it but does nothing.
|
||
2. **R13 (PlatformDmiQuirkFlags)**: Consumer wiring deferred. inputd, acpid, thermald do not yet read the platform subsystem dispatch.
|
||
3. **R14 (CpuBugFlags)**: Kernel-side consumer deferred. The 27 X86_BUG_* bits are defined; the kernel does not use them.
|
||
4. **R15 (ClocksourceQuirkFlags)**: Kernel `Hpet::init()` does not consult `PMTMR_BLACKLIST` etc.
|
||
5. **R17 (ChipsetQuirkFlags)**: Kernel-side consumer deferred. The 11-entry table is data-only.
|
||
6. **R20 (UsbAudioQuirkFlags)**: redbear-usbaudiod does not consume the 30-entry table.
|
||
7. **R21 (SUPPRESS_IVRS)**: iommu daemon does not read the DMI rule.
|
||
|
||
#### Driver integration matrix
|
||
|
||
| Driver | Quirk consumer status |
|
||
|--------|-----------------------|
|
||
| pcid | ✅ `PciConfigWriter` + `apply_pci_quirks` (Blocker 1, 12 unit tests) |
|
||
| xhcid | 🚧 QuirkAction loop pending (Blocker 4 partial, 1-2 day task per QUIRKS-SYSTEM.md) |
|
||
| usbhidd | ✅ `log_usb_quirks` + `log_hid_quirks` at enumeration (Blocker 3, 7 unit tests) |
|
||
| evdevd | ✅ `log_hid_quirks` (Gap 10, 4 unit tests) |
|
||
| redbear-iwlwifi | ✅ direct `lookup_pci_quirks` call (Gap 12, 3 unit tests) |
|
||
| amdgpu | ✅ `redox_quirk_bridge.c` extracted (Gap 15) |
|
||
| redox-drm | ✅ `info.quirks()` lookup (Gap 11, audit misread — already resolved) |
|
||
| e1000d | ❌ no quirk consumer (HIGH priority per AGENTS.md for low-level controllers plan) |
|
||
| ixgbed | ❌ no quirk consumer (HIGH priority) |
|
||
| rtl8168d | ❌ no quirk consumer (HIGH priority) |
|
||
| virtio-netd | ❌ no quirk consumer |
|
||
| virtio-blkd | ❌ no quirk consumer |
|
||
| acpid | 🚧 DMI producer complete, ACPI consumer deferred (R11) |
|
||
| kernel | ❌ no quirk consumer (R14, R15, R17) |
|
||
| iommu | ❌ no quirk consumer (R21) |
|
||
| thermald | ❌ no quirk consumer |
|
||
| redbear-usbaudiod | ❌ no quirk consumer (R20) |
|
||
| xhcid consumers (other than `force_poll` bit) | ❌ 17 xhcid bits have no consumer beyond `log_unenforced_xhci_quirks` warn line |
|
||
|
||
#### Quirk completeness
|
||
|
||
- **Compiled-in quirks**: 100% coverage of the Linux 7.1 PCI/USB/HID/xHCI/ACPI/DMI surface for the data the project has chosen to model.
|
||
- **TOML-loaded quirks**: 100% via the `redbear-quirks` package. The 22 TOML files are installed via the `redbear-quirks` recipe (script glob per QUIRKS-SYSTEM.md R7 audit fix).
|
||
- **DMI matching**: full — the chain `bootloader UEFI find_smbios() → kernel SmbiosScheme → acpid dmi::parse_smbios_table() → /scheme/acpi/dmi` was wired in 2026-06 (Blocker 2).
|
||
- **Driver integration**: ~50% of relevant drivers. The remaining 50% (network drivers, kernel, audio) are deferred per the canonical plan.
|
||
|
||
#### LoC estimate
|
||
|
||
For the deferred consumers:
|
||
- R12 redox-drm panel rotation: ~200 LoC
|
||
- R13 platform x86 (inputd/acpid/thermald): ~600 LoC
|
||
- R14 kernel CPU bug mitigations: ~800 LoC
|
||
- R15 kernel clocksource: ~200 LoC
|
||
- R17 kernel chipset-early: ~1,500 LoC
|
||
- R20 redbear-usbaudiod: ~400 LoC
|
||
- R21 iommu: ~150 LoC
|
||
- xhcid QuirkAction loop completion: ~150 LoC
|
||
- Network driver consumers (e1000d, ixgbed, rtl8168d, virtio-netd): ~800 LoC total
|
||
|
||
**Total**: ~4,800 LoC. 6–8 weeks with 1 dev.
|
||
|
||
#### Time estimate
|
||
|
||
6–8 weeks. The data side is solved; the consumers are the work.
|
||
|
||
---
|
||
|
||
## Cross-Cutting Issues
|
||
|
||
### Init Service Order (CRITICAL)
|
||
|
||
The canonical order from the task brief is:
|
||
|
||
```
|
||
1. logd (logging)
|
||
2. pcid (PCI enumeration)
|
||
3. pcid-spawner (launches GPU, USB, network drivers)
|
||
4. redox-drm (GPU driver registers /scheme/drm/card0)
|
||
5. vesad (early-boot framebuffer, runs only in initfs)
|
||
6. fbbootlogd (boot log)
|
||
7. fbcond (text console)
|
||
8. init (mounts sysroot, switches to rootfs)
|
||
9. redoxfs (rootfs)
|
||
10. logd (rootfs)
|
||
11. pcid (rootfs, takes over from initfs pcid)
|
||
12. d-bus system bus
|
||
13. seatd (seat management)
|
||
14. redbear-sessiond (login1 D-Bus broker)
|
||
15. redbear-authd (authentication)
|
||
16. SDDM (display + login)
|
||
```
|
||
|
||
**Actual state on disk**:
|
||
|
||
#### Initfs services (`local/sources/base/init.initfs.d/`, 20 files):
|
||
|
||
| File | Order | Service | Binary | In redbear-full? |
|
||
|------|-------|---------|--------|-------------------|
|
||
| 00_clock.service | 00 | Clock daemon | `clock` | via base pkg |
|
||
| 00_logd.service | 00 | Logger | `logd` | ✅ |
|
||
| 00_nulld.service | 00 | Null sink | `nulld` | ✅ |
|
||
| 00_randd.service | 00 | Random daemon | `randd` | ✅ |
|
||
| 00_zerod.service | 00 | Zero sink | `zerod` | ✅ |
|
||
| 00_runtime.target | 00 | Runtime target | n/a (target) | ✅ |
|
||
| ramfs@logging.service | 00 | Ramfs for logd | `ramfs logging` | ✅ |
|
||
| 10_inputd.service | 10 | Input multiplexer | `inputd` | ⚠️ conflicts with evdevd (plan v6.0) |
|
||
| 10_lived.service | 10 | Live disk | `lived` | ✅ (inherits from redbear-mini) |
|
||
| 20_fbbootlogd.service | 20 | Boot log | `fbbootlogd` | ✅ |
|
||
| 20_fbcond.service | 20 | Text console | `fbcond` | ✅ |
|
||
| 20_vesad.service | 20 | VESA FB handoff | `vesad` | ✅ |
|
||
| 20_graphics.target | 20 | Graphics target | n/a | ✅ |
|
||
| 30_acpid.service | 30 | ACPI daemon | `acpid` | ✅ |
|
||
| 40_bcm2835-sdhcid.service | 40 | RPi SD | `bcm2835-sdhcid` | ❌ (aarch64 only) |
|
||
| 40_drivers.target | 40 | Drivers target | n/a | ✅ |
|
||
| 40_hwd.service | 40 | Hardware manager | `hwd` | ✅ |
|
||
| 40_pcid-spawner-initfs.service | 40 | PCI spawner | `pcid-spawner --initfs` | ✅ |
|
||
| 40_ps2d.service | 40 | PS/2 | `ps2d` | ✅ |
|
||
| 50_rootfs.service | 50 | Rootfs mount | `redoxfs` | ✅ |
|
||
| 90_initfs.target | 90 | Initfs done | n/a | ✅ |
|
||
|
||
**Observations**:
|
||
- 1-7: logd, pcid (implicitly via pcid-spawner), pcid-spawner, redox-drm (via pcid-spawner), vesad, fbbootlogd, fbcond — all in the initfs.
|
||
- 8-9: init + redoxfs. Init does the switch_root; redoxfs is the rootfs mount.
|
||
- 10-15: not in the initfs; they start in the rootfs.
|
||
|
||
#### Rootfs services in redbear-full (`config/redbear-full.toml:194-529`):
|
||
|
||
| File path in TOML | Order | Service | Depends on | Notes |
|
||
|---------------------|-------|---------|------------|-------|
|
||
| `/etc/init.d/00_firmware-loader.service` | 00 | Firmware loader | 05_boot-essential | ✅ |
|
||
| `/etc/init.d/05_boot-essential.target` | 05 | Target | 04_drivers | ✅ |
|
||
| `/etc/init.d/13_iommu.service` | 13 | IOMMU | 05_boot-essential + 00_acpid | ✅ |
|
||
| `/etc/init.d/10_redox-drm.service` | 10 | GPU driver | 05_boot-essential + 00_driver-manager | ✅ (shell wrapper) |
|
||
| `/etc/init.d/12_dbus.service` | 12 | D-Bus | 12_boot-late + 00_ipcd | ✅ |
|
||
| `/etc/init.d/13_redbear-sessiond.service` | 13 | login1 | 12_dbus | ✅ |
|
||
| `/etc/init.d/13_seatd.service` | 13 | seatd | 12_dbus + 13_redbear-sessiond | ✅ |
|
||
| `/etc/init.d/13_redbear-keymapd.service` | 13 | keymap | 10_evdevd | ✅ |
|
||
| `/etc/init.d/13_redbear-ime.service` | 13 | IME | 10_evdevd | ✅ |
|
||
| `/etc/init.d/13_redbear-accessibility.service` | 13 | accessibility | 10_evdevd | ✅ |
|
||
| `/etc/init.d/14_redbear-upower.service` | 14 | UPower | 12_dbus | ✅ |
|
||
| `/etc/init.d/14_redbear-udisks.service` | 14 | UDisks2 | 12_dbus | ✅ |
|
||
| `/etc/init.d/14_redbear-polkit.service` | 14 | polkit | 12_dbus | ✅ |
|
||
| `/etc/init.d/11_redbear-authd.service` | 11 | authd | 12_dbus | ✅ |
|
||
| `/etc/init.d/12_sddm.service` | 12 | SDDM | 00_driver-manager + 10_redox-drm + 10_evdevd + 12_dbus + 13_redbear-sessiond + 13_seatd + 11_redbear-authd | ✅ |
|
||
| `/etc/init.d/30_console.service` | 30 | Console getty | 29_activate_console | ⚠️ 29_activate_console not defined in this config |
|
||
| `/etc/init.d/31_debug_console.service` | 31 | Debug console | 29_activate_console | ⚠️ same |
|
||
| `/etc/init.d/99_diag_serial.service` | 99 | Diag marker | 31_debug_console + 30_console + 12_dbus | ✅ |
|
||
| `/etc/init.d/99_kwin_test.service` | 99 | Diagnostic | 12_sddm | ⚠️ inline shell script in TOML — anti-pattern |
|
||
|
||
**Missing references**:
|
||
- `29_activate_console.service` is referenced by `30_console.service` and `31_debug_console.service` but is not defined. The console may not start.
|
||
- `12_boot-late.target` is referenced by `12_dbus.service` and not defined. The D-Bus service may not start until the cook recipe provides a service file with that name.
|
||
- `10_evdevd.service` is referenced by `12_sddm.service` and others; not defined here. May come from a recipe-level default.
|
||
- `04_drivers.target` is referenced; comes from `redbear-legacy-base.toml` (config inheritance, line 17 of redbear-full.toml says `include = ["redbear-mini.toml"]`).
|
||
- `00_driver-manager.service` is referenced; not visible in the redbear-full.toml — comes from a base recipe.
|
||
- `00_ipcd.service` is referenced; comes from base.
|
||
- `00_acpid.service` is referenced; comes from base.
|
||
|
||
**Order comparison (canonical plan vs actual)**:
|
||
|
||
| Step | Canonical | Actual initfs | Actual rootfs | Match? |
|
||
|------|-----------|---------------|---------------|--------|
|
||
| 1. logd | initfs | `00_logd.service` | inherits from base | ✅ |
|
||
| 2. pcid | rootfs | not in initfs (correct — pcid is a userspace daemon that needs the kernel to expose `scheme:pci`) | comes from base | ✅ |
|
||
| 3. pcid-spawner | both | `40_pcid-spawner-initfs.service` | `00_pcid-spawner.service` from base | ✅ |
|
||
| 4. redox-drm | rootfs | not in initfs (should it be? see plan v6.0) | `10_redox-drm.service` | ✅ (initfs is FB-only) |
|
||
| 5. vesad | initfs | `20_vesad.service` | n/a (intentionally — only initfs) | ✅ |
|
||
| 6. fbbootlogd | initfs | `20_fbbootlogd.service` | n/a | ✅ |
|
||
| 7. fbcond | initfs | `20_fbcond.service` | n/a | ✅ |
|
||
| 8. init | runtime | always PID 1 | n/a | ✅ |
|
||
| 9. redoxfs | rootfs | `50_rootfs.service` (in initfs) | n/a | ✅ |
|
||
| 10. logd (rootfs) | rootfs | inherits from base `00_logd.service` (PID 1 of rootfs reuses initfs's) | ✅ |
|
||
| 11. pcid (rootfs) | rootfs | not started explicitly in redbear-full.toml; pcid-spawner.service is at `00_` order so it runs early; the pcid **daemon** itself is not explicitly listed as a service file — relies on pcid-spawner spawning it on the first PCI function | ⚠️ |
|
||
| 12. dbus | rootfs | n/a | `12_dbus.service` | ✅ |
|
||
| 13. seatd | rootfs | n/a | `13_seatd.service` | ✅ |
|
||
| 14. redbear-sessiond | rootfs | n/a | `13_redbear-sessiond.service` | ✅ |
|
||
| 15. redbear-authd | rootfs | n/a | `11_redbear-authd.service` | ✅ |
|
||
| 16. SDDM | rootfs | n/a | `12_sddm.service` | ✅ |
|
||
|
||
**Issues with the order**:
|
||
- **Step 11 (pcid rootfs)**: the pcid daemon itself is not explicitly started. The pcid-spawner (`00_pcid-spawner.service` from base) is the consumer-side, but pcid is the producer of `/scheme/pci`. If pcid is not started, pcid-spawner has nothing to read. This is likely handled by pcid-spawner including pcid as a dependency, but I cannot verify without reading the base service file.
|
||
- **Step 12 (dbus) ordering**: `12_dbus.service` requires `12_boot-late.target` which is not in the config. If the target is provided by a recipe, OK; if not, dbus will fail to start.
|
||
- **Step 13 (seatd)**: requires `13_seatd.service` to start before SDDM, but SDDM requires both `13_redbear-sessiond.service` AND `13_seatd.service` — which means SDDM correctly waits for both. The order is correct.
|
||
- **Step 14 (redbear-sessiond)**: `13_redbear-sessiond.service` requires `12_dbus.service` only. Good.
|
||
- **Step 15 (redbear-authd)**: `11_redbear-authd.service` (note the 11 prefix, out of numeric order) requires only `12_dbus.service`. Good.
|
||
- **Step 16 (SDDM)**: requires everything. Good.
|
||
|
||
**Other issues found in the config**:
|
||
- The `12_sddm.service` is `oneshot_async` (line 466) — it does not notify readiness. SDDM runs in the background; if it fails, no one is watching.
|
||
- The 99_kwin_test.service is `oneshot_async` and runs a 600-character shell command embedded in the TOML `data` field. This is a real anti-pattern: shell scripts should be in `/usr/lib/redbear-diag/` as `.sh` files, not embedded.
|
||
|
||
#### Redbear-mini services (for context):
|
||
|
||
`redbear-mini.toml:1-200` is a separate config that does not pull in any of the desktop services. It is the text-only path.
|
||
|
||
#### Result:
|
||
|
||
The order is *correct* in the sense that dependencies are respected. The issues are:
|
||
1. A few target services (`12_boot-late.target`, `29_activate_console.service`) are referenced but not defined in the visible config — they may be provided by a recipe's `/usr/lib/init.d/` defaults.
|
||
2. SDDM is `oneshot_async` with no supervision.
|
||
3. The 99_kwin_test service is an in-TOML shell script.
|
||
4. The init has no auto-restart, so any failure requires a manual reboot.
|
||
|
||
### GPU Stack Chain (mesa → libdrm → libepoxy → redox-drm → qtbase → qtdeclarative → qtwayland → KF6 → KWin → SDDM → KDE Plasma)
|
||
|
||
For each link: does it compile? does it link? does it run?
|
||
|
||
| Link | Compile | Link | Run | Note |
|
||
|------|---------|------|-----|------|
|
||
| mesa | ✅ (per plan + project README) | ✅ | ❓ | Built with swrast, virgl, iris, crocus; EGL/GBM/GLES2 enabled. Not runtime-tested on redox HW. |
|
||
| libdrm | ✅ | ✅ | ❓ | Real library, no stub. Per project README: "DRM userspace library with Red Bear patches for render node and virtio-gpu support". |
|
||
| libepoxy | ❌ — stub installed | n/a | ❌ | `libepoxy-stub` installed to satisfy CMake find_package. Anti-pattern. |
|
||
| redox-drm | ✅ | ✅ | ❓ | Daemon compiles. Bounded QEMU virtio-gpu runtime path works. Real HW validation pending. |
|
||
| qtbase | ✅ | ✅ | ❓ | Per project README: built with -DFEATURE_opengl=ON, -DFEATURE_egl=ON (project policy). |
|
||
| qtdeclarative | ✅ | ✅ | ❓ | QML/Quick is a Phase 0 blocker. |
|
||
| qtsvg | ✅ | ✅ | ❓ | — |
|
||
| qtwayland | ✅ | ✅ | ❓ | — |
|
||
| qt6-wayland-smoke | ✅ | ✅ | ❓ | Smoke test only. |
|
||
| qt6-sensors | ✅ | ✅ | ❓ | — |
|
||
| KF6 (32/32) | ✅ per AGENTS.md | ✅ | ❓ | kirigami is blocked (QML gate). |
|
||
| kdecoration | ✅ | ✅ | ❓ | — |
|
||
| kwin | ✅ with KWIN_BUILD_*=OFF | ✅ | ❓ | Per recipe.toml:1 `#TODO: KWin — full build with Qt6Quick/QML`. |
|
||
| sddm | ✅ with sed-stripped X11 | ✅ | ❓ | Per recipe.toml:1 `#TODO: SDDM display manager — Wayland-only build`. |
|
||
| KDE Plasma (plasma-framework, plasma-workspace, plasma-desktop) | ❌ BLOCKED | n/a | n/a | Comments out in `redbear-full.toml:147-150` (QML gate). |
|
||
|
||
**Summary**: 12 of 14 links compile and link. 1 is a stub (libepoxy). 1 is blocked (Plasma). Runtime validation: open.
|
||
|
||
### Display Handover
|
||
|
||
**Project policy** (from `AGENTS.md` "NO VESA POLICY"):
|
||
|
||
> All display output goes through the DRM/KMS path via real GPU drivers. ... Once redox-drm initializes and registers scheme:drm/card0, vesad must hand off and NOT register scheme:display.vesa as the primary display surface.
|
||
|
||
**Implementation**:
|
||
|
||
| Layer | Mechanism | Implementation status |
|
||
|-------|-----------|----------------------|
|
||
| Bootloader linear FB | UEFI/BIOS GOP | ✅ |
|
||
| vesad (initfs) | registers `display.vesa` | ✅ but violates policy — never unregisters |
|
||
| redox-drm (rootfs) | registers `drm` | ✅ with EEXIST check |
|
||
| fbcond | `ConsumerHandle::open_display_v2()` re-open | ✅ (handoff support is there, but only triggered on input event) |
|
||
| fbbootlogd | same | ✅ |
|
||
| redbear-compositor | prefers DRM over FB | ✅ but does not actively drop FB |
|
||
| KWin | uses `--drm /scheme/drm/card0` | ✅ |
|
||
| SDDM | uses KWin via `CompositorCommand` | ✅ |
|
||
| user shell | `/scheme/drm/card0` | per-app choice |
|
||
|
||
**The handoff is *de facto* but not *de jure*.** No code in `vesad` ever tears down `display.vesa`. The policy is enforced by app choice (KWin, SDDM, redbear-compositor) to use DRM. If a user app opens `/scheme/display.vesa`, they get the boot framebuffer — not what the project wants.
|
||
|
||
**Verification question from the audit brief**:
|
||
|
||
> Does the early-boot vesad properly hand off to redox-drm?
|
||
> Per project policy: "vesad must hand off and NOT register scheme:display.vesa as the primary display surface"
|
||
> Verify this is implemented in the actual code (not just docs).
|
||
|
||
**Answer**: **No, it is not implemented.** The code at `vesad/src/main.rs:86-87` registers `display.vesa` permanently. There is no teardown path. The handoff is *app-level*, not *daemon-level*.
|
||
|
||
To fix:
|
||
1. Add a scheme-watcher in `vesad` that listens for `scheme:drm/card0` to be created.
|
||
2. On creation, call `libredox::call::unregister_scheme(...)` for `display.vesa`.
|
||
3. Add a fallback: if `scheme:drm` is not created within N seconds, keep `display.vesa` for debugging.
|
||
4. Document the behaviour change in `redbear-full.toml` config.
|
||
|
||
This is a 2-week, ~300 LoC change.
|
||
|
||
|
||
---
|
||
|
||
## Implementation Roadmap
|
||
|
||
### Phase 1: Unblock Display Handover (2 weeks, ~800 LoC)
|
||
|
||
1. **vesad handoff** (`local/sources/base/drivers/graphics/vesad/src/main.rs:86-87` + new `handoff.rs`):
|
||
- Watch `/scheme/drm` for the `card0` file.
|
||
- On detection, unregister `display.vesa` via `libredox::call::unregister_scheme(...)`.
|
||
- Add a CLI flag `--no-handoff` for debugging.
|
||
2. **Initfs vesad exit signal** (in `init.d/50_rootfs.service` or a new `51_vesad-stop.service`):
|
||
- Send SIGTERM to vesad's PID after rootfs is up.
|
||
3. **Remove `virtio-gpud` from initfs.toml**:
|
||
- `local/sources/base/drivers/initfs.toml:32-37` should drop the `virtio-gpu` entry; rely on `redox-drm` exclusively.
|
||
4. **Add a watchdog** in the rootfs `10_redox-drm.service` to restart redox-drm if `/scheme/drm/card0` disappears.
|
||
|
||
### Phase 2: Wire Init Auto-Restart and Shutdown (3 weeks, ~1,000 LoC)
|
||
|
||
1. **Auto-restart loop in `init/src/scheduler.rs`**:
|
||
- Add `enum JobKind { Start, Stop, Restart }`.
|
||
- Add `OnFailure=restart`, `RestartSec=5s`, `StartLimitBurst=3`, `StartLimitIntervalSec=60s` to `UnitInfo`.
|
||
2. **Poweroff/reboot**:
|
||
- Add `reboot(2)` and `poweroff(2)` syscalls to kernel; `init` calls them on a magic file (`/run/systemd/reboot` or similar).
|
||
3. **Multi-user target**:
|
||
- Replace the `for entry in entries` loop in `init/src/main.rs:153-173` with a single `multi-user.target` schedule that pulls in the dep graph.
|
||
4. **Status reporting**:
|
||
- Pipe `waitpid` status to a ring buffer; expose as `/scheme/init/status`.
|
||
|
||
### Phase 3: Replace `*-stub` Recipes (3-4 weeks, ~2,500 LoC)
|
||
|
||
For each of `libepoxy-stub`, `libxcvt-stub`, `libdisplay-info-stub`, `lcms2-stub`, `libudev-stub`:
|
||
|
||
1. **libepoxy**: replace with the real libepoxy 1.5.10 recipe (local or upstream). Real GL/EGL function pointer loading.
|
||
2. **libxcvt**: real libxcvt (it is small, ~300 LoC of pure C).
|
||
3. **libdisplay-info**: real libdisplay-info 0.2.0 (the stub is bounded to base EDID; the real lib supports CTA/DisplayID too).
|
||
4. **lcms2**: real lcms2 2.15. The stub has 8 functions; the real lib has ~100.
|
||
5. **libudev**: real libudev (or `udev-shim` proper, exposing `scheme:udev`).
|
||
|
||
Per project AGENTS.md: "Any stub found in the tree is a bug to be fixed, not a precedent to follow". The `redbear-quirks` recipe already has the data; the consumers need the real libraries.
|
||
|
||
### Phase 4: SDDM Real Build (3-4 weeks, ~1,000 LoC)
|
||
|
||
1. **Implement 4 `// TODO: IMPLEMENT`** in `local/recipes/kde/sddm/source/src/daemon/DisplayManager.cpp:156,160,164,195`. These are `addLocalDisplay`, `addRemoteDisplay`, `addSocketDisplay`, etc. Real implementations need to talk to `redbear-sessiond` for seat assignment.
|
||
2. **Replace `pam-redbear` shim** with a real PAM module:
|
||
- Implement the full PAM API (pam_start, pam_authenticate, pam_acct_mgmt, pam_open_session, pam_close_session, pam_setcred, pam_end).
|
||
- Use Unix socket JSON to `redbear-authd` for the auth backend.
|
||
3. **Remove `stubs/linux/{kd.h,vt.h}` and `stubs/X11/Xauth.h`** in favour of real relibc headers.
|
||
4. **Hand-rolled shell script in `99_kwin_test.service`** → move to `/usr/lib/redbear-diag/kwin-test.sh`.
|
||
|
||
### Phase 5: KWin Real QML Build (12-16 weeks, ~7,700 LoC)
|
||
|
||
1. **Implement Qt6Quick/QML on Redox** (this is Phase 0 of the canonical plan; the actual work is upstream-bound):
|
||
- Implement `QQuickWindow` (window, scene graph, render thread).
|
||
- Implement `QQmlEngine` (parser, type system, JIT).
|
||
- Implement `QQuickItem` (scene item tree, transforms, events).
|
||
2. **Re-enable KWIN_BUILD_QML_UI=ON** in `kwin/recipe.toml:155-165`.
|
||
3. **Re-enable KWIN_BUILD_SCREENLOCKER, KWIN_BUILD_TABBOX, KWIN_BUILD_GLOBALSHORTCUTS, KWIN_BUILD_KCMS** — each is a separate piece of QML/Quick UI.
|
||
4. **Add DrmPanelOrientation consumer** in redox-drm (R12 deferred).
|
||
5. **Quirk consumers** (R12, R14, R15, R17, R20) — see §6.
|
||
|
||
### Phase 6: Plasma + Apps (8-12 weeks, beyond this assessment)
|
||
|
||
Per the canonical plan, after KWin real-QML lands, plasma-framework, plasma-workspace, plasma-desktop can be re-enabled. Dolphin, Kate, Gwenview, Konsole as separate recipes.
|
||
|
||
---
|
||
|
||
## Testing Strategy
|
||
|
||
### Unit tests (host-buildable)
|
||
|
||
- **redox-driver-sys**: 131 unit tests covering all 10 quirk flag families + DMI + QuirkAction.
|
||
- **pcid**: 12 unit tests (mock + dispatch + conversions + cap-list walker).
|
||
- **usbhidd**: 7 unit tests.
|
||
- **evdevd**: 4 unit tests.
|
||
- **redbear-iwlwifi**: 3 unit tests.
|
||
- **redox-drm**: bring-up + ioctl proxy tests.
|
||
- **init**: needs unit tests; currently 0. The TOML deserializer is a natural target.
|
||
- **initfs**: 1 round-trip test (`archive_and_read`).
|
||
|
||
### Integration tests (QEMU)
|
||
|
||
- `local/scripts/test-phase1-runtime.sh --qemu redbear-full` — POSIX fd-event tests.
|
||
- `local/scripts/test-greeter-qemu.sh --check` — redbear-greeter bounded QEMU proof.
|
||
- `local/scripts/test-phase6-kde-qemu.sh --check` — KWin Phase 6.
|
||
- `local/scripts/test-lowlevel-controllers-qemu.sh` — xHCI, IOMMU, PS/2, timer proofs.
|
||
- `local/scripts/test-usb-maturity-qemu.sh` — xHCI mode, full USB stack, USB storage.
|
||
|
||
### Bare-metal smoke tests
|
||
|
||
- AMD Ryzen Threadripper 128-thread (per AGENTS.md header).
|
||
- Intel ARC (Xe driver) — not yet covered by tests.
|
||
- `local/scripts/test-baremetal.sh`.
|
||
|
||
### Gap
|
||
|
||
- No automated test for the `vesad → redox-drm` handoff. The user has to manually reboot after the handoff is implemented and verify that the display transitions cleanly.
|
||
- No test for SDDM activation in headless QEMU. SDDM requires a display; CI cannot exercise it without a graphical session.
|
||
- No test for KWin on QEMU. The recipe compiles but the binary has never been run in a CI harness.
|
||
|
||
---
|
||
|
||
## Risk Assessment
|
||
|
||
### What happens if we ship as-is?
|
||
|
||
- `redbear-mini` boots to a text console on QEMU ✅ (per the project README).
|
||
- `redbear-full` boots to a text console on QEMU (vesad + fbcond work) ✅.
|
||
- `redbear-full` boots to a black screen if `redox-drm` is missing (the `10_redox-drm.service` shell wrapper exits 0 if DRM is already registered but the user has no other surface to fall back to).
|
||
- KWin may compile but fail to start due to the missing libudev-stub for input device discovery. The user gets a blank screen.
|
||
- SDDM starts but the login is broken because the `// TODO: IMPLEMENT` in DisplayManager.cpp returns false for all display types.
|
||
|
||
### Minimum to make Phase 1 work (boot to text login)
|
||
|
||
Already done. `redbear-mini` is functional. Cost: 0 LoC.
|
||
|
||
### Minimum to make Phase 2 work (boot to Wayland compositor on QEMU)
|
||
|
||
- Phase 1 + remove virtio-gpud from initfs.toml + remove `*-stub` deps that KWin needs at runtime.
|
||
- Cost: 0.5 day for the initfs cleanup + 3-4 weeks for the stubs. With stubs left in, the user can boot a `redbear-compositor` (not KWin) Wayland session.
|
||
- Time: 3-4 weeks.
|
||
|
||
### Minimum to make Phase 3 work (SDDM login)
|
||
|
||
- Phase 2 + implement the 4 DisplayManager TODOs + real pam-redbear.
|
||
- Cost: 3-4 weeks.
|
||
- Time: 6-8 weeks from today.
|
||
|
||
### Minimum to make Phase 4 work (KDE desktop)
|
||
|
||
- Phase 3 + QML/Quick on Redox + re-enable KWIN_BUILD_QML_UI.
|
||
- Cost: 12-16 weeks.
|
||
- Time: 18-24 weeks from today.
|
||
|
||
### Highest-impact stub to fix first
|
||
|
||
The **5 `*-stub` recipes** are the single highest-impact change because they block the entire KWin + SDDM chain. If they are removed and replaced with real libraries, the user gets a working KWin that can render a real desktop (sans QML effects). Cost: 3-4 weeks.
|
||
|
||
The **vesad → redox-drm handoff** is the second-highest because it makes the system policy-compliant. Cost: 2 weeks.
|
||
|
||
The **4 `// TODO: IMPLEMENT` in DisplayManager.cpp** are the third because they block SDDM from displaying anything. Cost: 2-3 weeks.
|
||
|
||
### Risk register
|
||
|
||
| Risk | Impact | Likelihood | Mitigation |
|
||
|------|--------|------------|------------|
|
||
| `vesad` is also used by the bootloader UEFI GOP fallback (a real feature) | Removing the scheme would break the boot | High (if handoff is too aggressive) | Add the `--no-handoff` flag and a `REDOX_VESAD_HANDOFF=0` env var |
|
||
| Replacing `libepoxy-stub` requires Mesa EGL headers that may not be installed | KWin link fails | Medium | Verify the Mesa EGL/GLES2 install in the sysroot first |
|
||
| SDDM activation in QEMU needs a real seatd socket; `SEATD_SOCK=/var/run/seatd.sock` is not created in the config | SDDM cannot find seatd | Medium | Add a `make_socket /var/run/seatd.sock` step in the seatd service file |
|
||
| The plan v6.0 single-evdev-producer is a big refactor of the input path | Will break the boot | Medium | Land it in redbear-mini first, then in redbear-full |
|
||
| KWin QML on Redox requires ~4,000 LoC of Qt6Quick/QQmlEngine | Phase 5 fails | High | Re-evaluate KWin as the canonical compositor; consider weston or a custom compositor |
|
||
| The user has an NVIDIA GPU | Not in the AMD+Intel parity path | Low (out of scope) | Document in the hardware validation matrix |
|
||
|
||
|
||
---
|
||
|
||
## Appendix A: Grep Results (raw)
|
||
|
||
### A.1 `todo!()` / `unimplemented!()` in the chain
|
||
|
||
| File:line | Snippet |
|
||
|-----------|---------|
|
||
| `local/sources/base/drivers/pcid/src/cfg_access/fallback.rs:89` | `todo!("Pci::CfgAccess::read on this architecture")` |
|
||
| `local/sources/base/drivers/pcid/src/cfg_access/fallback.rs:94` | `todo!("Pci::CfgAccess::write on this architecture")` |
|
||
| `local/sources/base/drivers/graphics/vesad/src/scheme.rs:146` | `unimplemented!("Vesad does not support this function");` |
|
||
| `local/sources/base/drivers/graphics/ihdgd/src/device/scheme.rs:138` | `unimplemented!("ihdgd does not support this function");` |
|
||
| `local/sources/base/drivers/input/ps2d/src/controller.rs:133` | `unimplemented!()` |
|
||
| `local/sources/base/drivers/input/ps2d/src/vm.rs:68` | `unimplemented!()` |
|
||
|
||
**Total**: 6 `unimplemented!()` / `todo!()` panics in non-test code on the boot→display path.
|
||
|
||
### A.2 `expect("TODO")` in the chain
|
||
|
||
| File:line | Snippet |
|
||
|-----------|---------|
|
||
| `local/sources/base/init/src/service.rs:98` | `let current_namespace_fd = libredox::call::getns().expect("TODO");` |
|
||
| `local/sources/base/init/src/service.rs:100` | `.expect("TODO");` |
|
||
|
||
**Total**: 2 `expect("TODO")` panics in init service spawn.
|
||
|
||
### A.3 `// TODO` / `// FIXME` counts (chain files)
|
||
|
||
| File or directory | TODO count |
|
||
|--------------------|------------|
|
||
| `local/sources/kernel/src/**/*.rs` | 330 (per LOWLEVEL-STUBS-AUDIT.md) |
|
||
| `local/sources/base/init/src/` | 4 (2 in main.rs, 1 in service.rs, 1 in unit.rs) |
|
||
| `local/sources/base/initfs/src/` | 0 |
|
||
| `local/sources/base/drivers/pcid/src/` | 23 (per init grep) |
|
||
| `local/sources/base/drivers/pcid-spawner/src/` | 0 |
|
||
| `local/sources/base/drivers/graphics/{vesad,fbcond,fbbootlogd,virtio-gpud,driver-graphics,ihdgd,console-draw}` | 100+ (per init grep) |
|
||
| `local/sources/base/drivers/acpid/src/` | 10 (per init grep) |
|
||
| `local/sources/base/drivers/hwd/src/` | 5 (per init grep) |
|
||
| `local/sources/base/drivers/input/{ps2d,usbhidd}` | 23 (per init grep) |
|
||
| `local/recipes/gpu/redox-drm/source/src/` | 0 (per init grep) |
|
||
| `local/recipes/wayland/redbear-compositor/source/src/` | 0 (per init grep) — but explicit "bounded proof scaffold" comment |
|
||
| `local/recipes/system/redbear-sessiond/source/src/` | 0 (per init grep) |
|
||
| `local/recipes/system/redbear-authd/source/src/` | 0 (per init grep) |
|
||
| `local/recipes/system/redbear-greeter/source/src/` | 0 (per init grep) |
|
||
| `local/recipes/system/dbus/source/` | 239 (upstream dbus, expected) |
|
||
| `local/recipes/system/seatd/source/` | 3 (TODO in seatd/server.c, seatd/client.c, common/connection.c) |
|
||
| `local/recipes/kde/sddm/source/src/daemon/` | 5 (4 TODO:IMPLEMENT in DisplayManager.cpp + 1 in DaemonApp.h) |
|
||
| `local/recipes/kde/kwin/source/src/` | (upstream KWin 6.3.4; many TODOs) |
|
||
|
||
**Total in the chain (excluding upstream KWin/SDDM/dbus)**: ~500+.
|
||
|
||
### A.4 Anti-pattern grep results
|
||
|
||
```
|
||
$ grep -rE "stub" local/recipes/libs/ --include="*.toml"
|
||
local/recipes/libs/libinput/recipe.toml:18: "libudev-stub",
|
||
local/recipes/libs/lcms2-stub/recipe.toml:1: #TODO: lcms2 stub — provides lcms2::lcms2 cmake target for KWin linking
|
||
local/recipes/libs/libepoxy-stub/recipe.toml:1: #TODO: libepoxy stub — provides epoxy::epoxy cmake target for KWin linking
|
||
local/recipes/libs/libxcvt-stub/recipe.toml:1: #TODO: libxcvt stub — provides libxcvt pkgconfig for KWin linking
|
||
local/recipes/libs/libdisplay-info-stub/recipe.toml:1: #TODO: bounded libdisplay-info shim for the KWin reduced path
|
||
```
|
||
|
||
5 stub recipes installed in the build chain.
|
||
|
||
```
|
||
$ grep -n "display\.vesa" local/sources/base/drivers/graphics/vesad/src/
|
||
local/sources/base/drivers/graphics/vesad/src/main.rs:1: extern crate orbclient;
|
||
local/sources/base/drivers/graphics/vesad/src/main.rs:87: GraphicsScheme::new(FbAdapter { framebuffers }, "display.vesa".to_owned(), true);
|
||
```
|
||
|
||
vesad still registers as `display.vesa` (policy violation).
|
||
|
||
### A.5 Service file enumeration
|
||
|
||
```
|
||
$ ls local/sources/base/init.initfs.d/ | wc -l
|
||
20
|
||
$ ls local/sources/base/init.d/ | wc -l
|
||
10
|
||
$ grep -c "\[\[files\]\]" config/redbear-full.toml
|
||
19
|
||
```
|
||
|
||
20 initfs services, 10 rootfs services from base, 19 config `[[files]]` overrides in redbear-full.
|
||
|
||
### A.6 Quirks data TOML enumeration
|
||
|
||
```
|
||
$ ls local/recipes/system/redbear-quirks/source/quirks.d/ | wc -l
|
||
22
|
||
```
|
||
|
||
22 TOML files in `redbear-quirks`. After the R7 audit fix (glob install), all 22 ship to `/etc/quirks.d/`.
|
||
|
||
---
|
||
|
||
## Appendix B: File-by-file Line Counts (chain)
|
||
|
||
### B.1 Kernel
|
||
|
||
```
|
||
$ find local/sources/kernel/src -name "*.rs" | xargs wc -l | tail -1
|
||
~21,555 total
|
||
```
|
||
|
||
(Per LOWLEVEL-STUBS-AUDIT.md.) Per-file breakdown not re-tabulated here; see the audit.
|
||
|
||
### B.2 Init + Initfs
|
||
|
||
```
|
||
$ wc -l local/sources/base/init/src/*.rs
|
||
184 local/sources/base/init/src/main.rs
|
||
116 local/sources/base/init/src/scheduler.rs
|
||
163 local/sources/base/init/src/script.rs
|
||
132 local/sources/base/init/src/service.rs
|
||
251 local/sources/base/init/src/unit.rs
|
||
846 total
|
||
```
|
||
|
||
```
|
||
$ wc -l local/sources/base/initfs/src/*.rs
|
||
287 local/sources/base/initfs/src/lib.rs
|
||
126 local/sources/base/initfs/src/types.rs
|
||
413 total
|
||
```
|
||
|
||
```
|
||
$ wc -l local/sources/base/initfs/tools/src/lib.rs local/sources/base/initfs/tools/src/bin/*.rs
|
||
590 local/sources/base/initfs/tools/src/lib.rs
|
||
67 local/sources/base/initfs/tools/src/bin/archive.rs
|
||
112 local/sources/base/initfs/tools/src/bin/dump.rs
|
||
769 total
|
||
```
|
||
|
||
```
|
||
$ wc -l local/sources/base/init.initfs.d/* local/sources/base/init.d/*
|
||
243 total (20 + 10 files)
|
||
```
|
||
|
||
### B.3 PCID
|
||
|
||
```
|
||
$ wc -l local/sources/base/drivers/pcid/src/*.rs
|
||
284 local/sources/base/drivers/pcid/src/driver_handler.rs
|
||
6 local/sources/base/drivers/pcid/src/lib.rs
|
||
392 local/sources/base/drivers/pcid/src/main.rs
|
||
597 local/sources/base/drivers/pcid/src/quirks.rs
|
||
444 local/sources/base/drivers/pcid/src/scheme.rs
|
||
1723 (these 5)
|
||
|
||
$ wc -l local/sources/base/drivers/pcid/src/cfg_access/*.rs
|
||
~360 cfg_access/mod.rs
|
||
96 cfg_access/fallback.rs
|
||
|
||
$ wc -l local/sources/base/drivers/pcid/src/driver_interface/*.rs
|
||
~1300 (8 files: bar.rs, cap.rs, config.rs, id.rs, irq_helpers.rs, mod.rs, msi.rs)
|
||
|
||
$ wc -l local/sources/base/drivers/pcid-spawner/src/*.rs
|
||
101 pcid-spawner/src/main.rs
|
||
|
||
$ echo "pcid total: ~3083"
|
||
```
|
||
|
||
### B.4 Display chain
|
||
|
||
```
|
||
$ wc -l local/sources/base/drivers/graphics/vesad/src/*.rs
|
||
133 vesad/src/main.rs
|
||
275 vesad/src/scheme.rs
|
||
408 total
|
||
|
||
$ wc -l local/sources/base/drivers/graphics/fbcond/src/*.rs
|
||
91 fbcond/src/display.rs
|
||
253 fbcond/src/main.rs
|
||
193 fbcond/src/scheme.rs
|
||
134 fbcond/src/text.rs
|
||
671 total
|
||
|
||
$ wc -l local/sources/base/drivers/graphics/fbbootlogd/src/*.rs
|
||
115 fbbootlogd/src/main.rs
|
||
250 fbbootlogd/src/scheme.rs
|
||
365 total
|
||
|
||
$ wc -l local/sources/base/drivers/graphics/virtio-gpud/src/*.rs
|
||
615 virtio-gpud/src/main.rs
|
||
528 virtio-gpud/src/scheme.rs
|
||
1143 total
|
||
|
||
$ wc -l local/sources/base/drivers/graphics/driver-graphics/src/**/*.rs local/sources/base/drivers/graphics/driver-graphics/src/*.rs
|
||
~1140 (lib.rs + kms/{connector,mod,objects,properties}.rs)
|
||
|
||
$ wc -l local/sources/base/drivers/graphics/ihdgd/src/main.rs local/sources/base/drivers/graphics/ihdgd/src/device/*.rs
|
||
~4042 (1 main + 13 device files)
|
||
```
|
||
|
||
### B.5 redox-drm
|
||
|
||
```
|
||
$ find local/recipes/gpu/redox-drm/source/src -name "*.rs" | xargs wc -l | tail -1
|
||
30332 total (130 files)
|
||
```
|
||
|
||
```
|
||
$ wc -l local/recipes/gpu/redox-drm/source/src/main.rs
|
||
815 redox-drm/src/main.rs
|
||
```
|
||
|
||
### B.6 redbear-compositor
|
||
|
||
```
|
||
$ wc -l local/recipes/wayland/redbear-compositor/source/src/*.rs local/recipes/wayland/redbear-compositor/source/src/bin/*.rs
|
||
2180 main.rs
|
||
483 display_backend.rs
|
||
388 handlers.rs
|
||
177 protocol.rs
|
||
198 state.rs
|
||
197 wire.rs
|
||
845 bin/redbear-compositor-check.rs
|
||
4468 (excluding tests)
|
||
```
|
||
|
||
```
|
||
$ wc -l local/recipes/wayland/redbear-compositor/source/tests/integration_test.rs
|
||
615 tests/integration_test.rs
|
||
```
|
||
|
||
### B.7 KWin + SDDM
|
||
|
||
```
|
||
$ find local/recipes/kde/kwin/source -name "*.cpp" -o -name "*.h" 2>/dev/null | xargs wc -l | tail -1
|
||
~38591 (upstream KWin 6.3.4)
|
||
|
||
$ find local/recipes/kde/sddm/source -name "*.cpp" -o -name "*.h" 2>/dev/null | xargs wc -l | tail -1
|
||
~38591 (upstream SDDM; same file count)
|
||
```
|
||
|
||
The KWin and SDDM LoC are essentially the upstream tarball size, not Red Bear work. The Red Bear work is in `recipe.toml` (~187 for KWin, ~108 for SDDM) and the patches.
|
||
|
||
### B.8 Session / Auth / Greeter
|
||
|
||
```
|
||
$ wc -l local/recipes/system/redbear-sessiond/source/src/*.rs
|
||
48 acpi_watcher.rs
|
||
221 control.rs
|
||
267 device_map.rs
|
||
642 manager.rs
|
||
188 main.rs
|
||
54 runtime_state.rs
|
||
450 session.rs
|
||
147 seat.rs
|
||
2017 total
|
||
|
||
$ wc -l local/recipes/system/redbear-authd/source/src/main.rs
|
||
719
|
||
|
||
$ wc -l local/recipes/system/redbear-greeter/source/src/main.rs local/recipes/system/redbear-greeter/source/ui/*.qml
|
||
656 main.rs
|
||
206 ui/Main.qml
|
||
862 total
|
||
```
|
||
|
||
### B.9 Quirks
|
||
|
||
```
|
||
$ wc -l local/recipes/drivers/redox-driver-sys/source/src/quirks/*.rs
|
||
~1300 (mod.rs ~1100 + 7 sub-files)
|
||
```
|
||
|
||
```
|
||
$ ls local/recipes/system/redbear-quirks/source/quirks.d/ | wc -l
|
||
22 (TOML files)
|
||
```
|
||
|
||
### B.10 Total LoC in the chain
|
||
|
||
| Stage | LoC |
|
||
|-------|-----|
|
||
| Kernel | ~21,555 |
|
||
| Init + Initfs + tools | ~2,028 |
|
||
| PCID + pcid-spawner | ~3,083 |
|
||
| Display (vesad, fbcond, fbbootlogd, virtio-gpud, driver-graphics, ihdgd) | ~8,932 |
|
||
| redox-drm | ~30,332 |
|
||
| redbear-compositor (with tests) | ~5,083 |
|
||
| KWin (upstream) | ~38,591 |
|
||
| SDDM (upstream) | ~38,591 |
|
||
| redbear-sessiond | 2,017 |
|
||
| redbear-authd | 719 |
|
||
| redbear-greeter (with QML) | 862 |
|
||
| Quirk system (redox-driver-sys) | ~1,300 |
|
||
| Quirk data TOMLs | 22 files |
|
||
| **Total (without KWin/SDDM upstream)** | **~76,000 LoC** |
|
||
| **Total (with KWin/SDDM upstream)** | **~153,000 LoC** |
|
||
|
||
Of the ~76k LoC of Red Bear work, the largest single piece is `redox-drm` (~30k LoC) and the kernel (~21.5k LoC). The display chain is well-sized at ~9k LoC; the user-facing compositor chain (redbear-compositor + KWin stubs) is small.
|
||
|
||
---
|
||
|
||
## Cross-references to existing project docs
|
||
|
||
- **`local/docs/AGENTS.md` / `AGENTS.md`** — project policies cited throughout this doc.
|
||
- **`local/docs/STUBS-AUDIT-AND-REWRITE-PLAN.md`** (994 LoC, 2026-06-09) — low-level input/keyboard/HID/serio/ACPI/USB/PCI/audio/storage/network/graphics stubs.
|
||
- **`local/docs/LOWLEVEL-STUBS-AUDIT.md`** (1,091 LoC, 2026-06-09) — ACPI/PCI/IRQ/IOMMU/Boot/Init infrastructure stubs.
|
||
- **`local/docs/USB-STUBS-AUDIT.md`** (501 LoC) — USB stubs.
|
||
- **`local/docs/HID-STUBS-AUDIT.md`** (419 LoC) — HID stubs.
|
||
- **`local/docs/QUIRKS-SYSTEM.md`** (3,803 LoC) — comprehensive quirks data + lookup + 131 unit tests.
|
||
- **`local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md`** (1,380 LoC, v6.0, 2026-06-08) — canonical desktop path.
|
||
- **`local/docs/DBUS-INTEGRATION-PLAN.md`** (D-Bus for KDE Plasma 6 + Wayland).
|
||
- **`local/docs/GREETER-LOGIN-IMPLEMENTATION-PLAN.md`** (greeter/auth/session-launch split).
|
||
- **`local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md`** (PCI/IRQ/MSI/MSI-X/IOMMU plan).
|
||
- **`local/docs/ACPI-IMPROVEMENT-PLAN.md`** (ACPI for AMD).
|
||
- **`local/docs/WIFI-IMPLEMENTATION-PLAN.md`**, **`local/docs/BLUETOOTH-IMPLEMENTATION-PLAN.md`**, **`local/docs/USB-IMPLEMENTATION-PLAN.md`** — out of scope for this assessment but referenced.
|
||
|
||
This document is the **kernel → initfs → init → display → Wayland → KDE** slice of the same plan.
|
||
|
||
---
|
||
|
||
**End of Assessment.**
|