- 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.
94 KiB
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)
vesadstill registersdisplay.vesaas a primary display scheme (vesad/src/main.rs:87). Per project policy (AGENTS.md"NO VESA POLICY") vesad must hand off toredox-drmand not be the primary surface. The code does not implement this handoff. KWin/SDDM are told to use/scheme/drm/card0(good) but ifredox-drmis slow to register (or fails on a non-virtio GPU) the boot falls back to vesad as the visible surface, contradicting the policy.- 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. - 5
*-stubrecipes 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 CMakefind_packagecalls and provide empty/no-op symbols. Per project policy this is a violation: "Implement the missing functionality properly" rather than stub. - Init has no auto-restart (
init/src/scheduler.rs:14-17definesenum JobKind { Start }only; no Restart, no Stop, no Reload). Ifredox-drmdies after registering/scheme/drm/card0, the user gets a frozen desktop and no recovery. - The
redbear-compositorWayland 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
-
HPET initialization is hard-coded; userspace cannot reconfigure —
acpi/mod.rs:163:// TODO: Let userspace setup HPET, and then provide an interface to specify which timer to // use? Hpet::init();Impact: When
redbear-quirksflags a clocksource issue (e.g.PMTMR_BLACKLISTon PIIX4<3, ICH4, ServerWorks LE), the kernel has no path to read the flag and pick a different clocksource. The flag exists inredox-driver-sysand is loaded by the TOML (R15), but the kernel-side consumer is missing. -
Processor enumeration is in the kernel —
acpi/mod.rs:149:// 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.
-
aarch64 SPCR parsing is gated —
acpi/mod.rs:159-167://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.
-
Start-up still touches ACPI tables directly —
acpi/mod.rs:134:// 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.
-
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 flagSUPPRESS_IVRSfor theiommudaemon to consult is not yet wired into the kernel side. -
Total of 330
TODO|FIXMEmarkers across the kernel tree (find ... | xargs grep -c "TODO\|FIXME" | awk '{s+=$2}END{print s}'= 330) — most are localised incontext/memory.rs:67(memory layout) andcontext/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-sysexportsClocksourceQuirkFlags::PMTMR_BLACKLIST/PMTMR_GRAYLIST/HPET_BROKEN/TSC_UNSTABLE(R15), but the kernelHpet::init()does not consume them. To close this: kernel must read/scheme/acpi/dmi(or an analogous publisher) atHpet::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.rsandacpi/srat.rsexist butnumad(perredbear-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:1smbiosparsing feeds the DMI scheme (Blocker 2), but theDmiInfostruct is missing some fields that newer kernels (Linux 7.1drivers/firmware/dmi_scan.c) parse. Resolved 2026-06 (b56b810c0addedbios_vendor/bios_date).
Quirks used by kernel
- DMI table (R11 / Blocker 2): kernel
SmbiosScheme→ acpiddmi::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; seetypes.rs:4) with a header, an inode table, and string-offset dir entries. The library can be compiled tono_stdand used inside the bootloader (initfs/src/lib.rs:1-30). archiveanddumptools exist for assembling the initfs image and inspecting it. The tests exercise the round trip (archive → read → dump).- The
initfs.toml[[drivers]]table inlocal/sources/base/drivers/initfs.tomllists 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.tomlandinitfs-storage.tomlprovide 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::archiveconsuming 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.tomlis silent. There is no equivalent ofcargo metadatato 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
-
expect("TODO")panic inService::spawnwhen aScheme(type)service starts —service.rs:98, 100:let current_namespace_fd = libredox::call::getns().expect("TODO"); libredox::call::register_scheme_to_ns(current_namespace_fd, scheme, new_fd) .expect("TODO");The
getnscall and theregister_scheme_to_nscall 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 realtodo!()disguised as.expect("TODO")(2 of them in this section). -
No auto-restart loop —
scheduler.rs:14-17:enum JobKind { Start, }No
Stop, noRestart. A scheme service that registers its scheme and then dies (e.g.redox-drmpanic) leaves/scheme/drm/card0in a stale state with no recovery. Per LOWLEVEL-STUBS-AUDIT.md "Init auto-restart on failure: 2 weeks". -
Multi-user target is a comment, not a unit —
main.rs:150-151:// 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 (like99_diag_serial.service) get scheduled even if their dep chain has not yet reached them. Thedefault_dependencies = falseworkaround in service files is the only guard. -
No poweroff/reboot handling —
init/src/main.rs:180-183: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 orSIGINTfrom 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). -
No on-failure service policy —
unit.rs:117-128definesUnitInfowithdescription,default_dependencies,requires_weak,condition_architecture,condition_boardbut norestart,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. -
unit.rs:126// FIXME replace this with hwd reading from the devicetree—condition_boardis 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). -
The
00_*.service/90_*.servicenumeric ordering is implicit —unit.initfs.d/90_initfs.targetexists as a target butinit.d/00_*.servicefiles in the rootfs come from the cookbook and have no ordering key beyond file name. systemd hasBefore=/After=; this init has no equivalent (onlyrequires_weak).
Missing wirings
- No
Reloadjob for services whose state file changes (e.g. SDDM config, seatd policy). - No
ConditionPathExists/ConditionKernelCommandLinefor env-gated activation. Right now a service that should only run onredbear-fullmust be excluded fromredbear-mini.tomlmanually. - No graceful shutdown of dependent services before a reboot. The current
waitpidloop just reaps zombies.
Stale code
main.rs:181readslet mut status = 0;but the variable ismut-declared and never mutated. Likely acargo clippyunused_mutwarning. Thewaitpid(0, &mut status, 0).unwrap()then overwrites it but the compiler may not see that.- The
condition_boardfield is aFIXMEand is read fromoption_env!("BOARD")(compile time) atunit.rs:243— it is effectively dead. No recipe setsBOARDat 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
-
todo!()panic on non-x86 PCI access —pcid/src/cfg_access/fallback.rs:89, 94:#[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.
-
unimplemented!()panics inpcid::scheme::SchemeImpl::pcilinkpath —pcid/src/scheme.rs:329:log::trace!("TODO: Support disabling device (called on {})", addr);This is a
log::trace!(not atodo!()), 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). -
pcid-spawner has zero ACPI / DMI matching —
pcid-spawner/src/main.rs:65-72: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/dmito pick a different driver for a known-bad implementation. This is not implemented; for QEMU virtio-gpu the match works because the table isvendor=0x1AF4, device=0x1050(perredbear-full.toml:621-630). -
pcid-spawner
--initfsflag selects the initfs config directory —pcid-spawner/src/main.rs:11, 22-30: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
pcidkey. Theinitfs-pcid-storage.tomlandinitfs-storage.tomluse a different format ([[drivers]]withcommandas a single string, vs. the new[[driver]]withcommandas a list —redbear-full.toml:206-226uses the new format with[[driver.match]]). There is a real risk that theinitfs-pcid-storage.tomland the new manifest format are not interchangeable; the spawner would not parse the new format if started from initfs. -
10
// TODO/// FIXMEinpcid/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).
-
8
// TODO/// FIXMEinpcid/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 (perlocal/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 thecfg_accessfallback 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::pcischeme 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/card0inredbear-full.toml:295). The translation is dead code in practice.cfg_access/fallback.rs:30-35warns 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..1023env entries for multi-display boot (vesad/src/main.rs:60-84). - Registers the scheme as
display.vesa(vesad/src/main.rs:86-87):let mut scheme = GraphicsScheme::new(FbAdapter { framebuffers }, "display.vesa".to_owned(), true); - Implements
GraphicsAdapterwithDumbBufferandSync(viavesad/src/scheme.rs:83-138). - Forwards input events from
inputdviainputd_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:
-
unimplemented!()panic on cursor plane operations —vesad/src/scheme.rs:146: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, butredox-drmmight try to usedrmModeSetCursorand propagate through the sameGraphicsAdaptertrait. -
GraphicsScheme::new(..., true)— the thirdtrueargument —vesad/src/main.rs:87: This passesblock = true(or similar) to the scheme constructor. Meansvesadaccepts ablockflag where clients can wait for the device. Compatible with the early-boot handoff. -
//TODO: ideal maximum number of outputs?atvesad/src/main.rs:59— 1024 is hard-coded. Cosmetic. -
No handover logic to
redox-drm—vesad/src/scheme.rshas 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/card0over/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:
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_rootatinit/src/main.rs:143-148re-mounts the rootfs. - The initfs daemons (
vesad,fbcond,fbbootlogd,acpid,hwd,pcid-spawner --initfs) are not killed byswitch_root(Redoxswitch_rootis implemented as a logical remount, not a process kill). - The rootfs daemons (same names, plus
redox-drm) start fresh. - The result is two parallel
vesads — one from initfs, one from rootfs (if it's in the rootfs service set; it isn't inredbear-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
vesadshutdown signal in the rootfs init sequence. - No DRM scheme handoff acknowledgement.
- The initfs's
vesadregistersdisplay.vesaand 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-12imports fromdrm_sys::— this is the legacy pre-2024drmcrate namespace. Thedrmcrate is being phased out in favour ofdrm-sysand the newredox_drm::API. Thevesadbuild still depends on the old name.vesad/src/main.rs:1extern crate orbclient—orbclientis the legacy Orbital graphics API. It is still used inconsole-draw,fbcond,fbbootlogdbut 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 whenredox-drmbecomes available (fbcond/src/display.rs:25-58).
Stubs / half-impls:
// FIXME listen for resize events from inputd and handle them—fbcond/src/main.rs:36. The framebuffer'shandle_resizeis implemented (fbcond/src/display.rs:60-82) but no event subscription. A window resize triggers a re-render only at the next VTSwitch.setrens(0,0)is commented out —fbcond/src/main.rs:53-54:fbcond intentionally keeps its namespace root so it can// 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");ConsumerHandle::open_display_v2()when DRM comes online. This is correct but means a "vesad" malicious client could attach to the same VTs._ => (), //TODO: Mouse in terminal—fbcond/src/text.rs:98. Mouse events in the text console are dropped.- Per
fbcond/src/display.rs:34-39the V2GraphicsHandle parser logsDisplay 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. scheme.rs:162eprintln!("vesad: failed to write display scheme")— should befbcond: 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:
- Same
setrens(0,0)comment as fbcond. fbbootlogd/src/scheme.rs:38callshandle_handoff()innew()— a no-op untilredox-drmis 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-228forPCI_VENDOR_ID_AMD(0x1002),PCI_VENDOR_ID_INTEL(0x8086),0x1AF4(VirtIO). PcidClienthandoff 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/drmviaregister_sync_scheme(&socket, "drm", ...)(redox-drm/src/main.rs:129). - Self-de-duplication: if
scheme:drmis 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:
-
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 importedredox-drmIntel code is inlocal/recipes/gpu/redox-drm/source/src/drivers/intel/with 838 LoC of workarounds alone (workarounds.rs). Both exist; the upstreamihdgdis a clean-room Intel driver and the importedredox-drm/intelis the Linux i915 port. Per the plan they are alternative paths; per the configredox-full.toml:62redox-drm = {}is the chosen one. -
The AMD DC port in
local/recipes/gpu/amdgpu/is "ignore" inredbear-full.toml:157. The commentamdgpu = {} # TODO: fix conflicting idr_* defs with linux-kpi headersshows the integration is blocked on header conflicts. -
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
ihdgddriver. 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. -
Many
// FIXMEand// TODOinlocal/sources/base/drivers/graphics/driver-graphics/src/(the legacy i915-styleihdgdpath):lib.rs:222// FIXME notify clientslib.rs:537// FIXME fill x and y with the data from the primary planelib.rs:852// FIXME use a better scheme for creating map offsetslib.rs:893// FIXME remove once all drm objects are materialized in self.objectskms/connector.rs:38, 161, 177, 243— connector enumeration is hard-coded to onekms/properties.rs:26, 30— property IDs overlap
-
KMS EDID stub —
local/sources/base/drivers/graphics/ihdgd/src/device/scheme.rs:1, 46, 64, 75, 138://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 (
ihdgdinlocal/sources/). The new path (redox-drminlocal/recipes/) has real EDID parsing per thefirmware_expectationmachinery.
Quirks consumed:
redox-drmcallsinfo.quirks()(the consumer-side helper) to retrievePciQuirkFlags. 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 needNEED_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.tomlreferencesvirtio-gpud(line 32-37) andredbear-full.toml:621-630referencesvirtio-gpudconfig but the daemon itself is the legacy DRM/KMS scheme daemon. Withredox-drmnow owning the drm scheme (/scheme/drm/card0),virtio-gpudwould conflict. virtio-gpud/src/main.rs:3://! XXX: 3D mode will offload rendering ops to the host gpu and therefore requires a GPU with 3D supportvirtio-gpud/src/main.rs:35-40defines 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/card0via thedrm_backendmodule (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/card0is absent (display_backend.rs:35-50).
Stubs / half-impls:
- Self-described as "bounded proof scaffold" —
main.rs:1-15:// 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. - Fallback framebuffer uses
map_framebuffer(_phys, size) -> Vec<u8>withvec![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. - Hard-coded dimensions —
display_backend.rs:36-46: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.let width: u32 = std::env::var("FRAMEBUFFER_WIDTH") .unwrap_or_else(|_| "1280".into()) ... - No
xdg-shellsupport — onlywl_shell. Per the plan v6.0, KWin is the canonical compositor; redbear-compositor is greeter-only. The greeter isredbear-greeter, not this binary. - The hand-rolled
drm_backendreimplements DRM ioctls from scratch —display_backend.rs:38-450andmain.rs:38-450. This is ~1,000 LoC of bespoke protocol that is duplicated inredox-drm. The 2 implementations will diverge; the canonical should beredox-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) runskwin_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=OFFand many other features off (recipe.toml:155-165):KWIN_BUILD_AUTO_ROTATION=OFFKWIN_BUILD_X11=OFFKWIN_BUILD_X11_BACKEND=OFFKWIN_BUILD_KCMS=OFFKWIN_BUILD_SCREENLOCKER=OFFKWIN_BUILD_TABBOX=OFFKWIN_BUILD_GLOBALSHORTCUTS=OFFKWIN_BUILD_RUNNERS=OFFKWIN_BUILD_NOTIFICATIONS=OFFKWIN_BUILD_ACTIVITIES=OFFKWIN_BUILD_EIS=OFF
- Custom
sedpatches to strip X11 paths, acceptaccept()withoutSOCK_CLOEXEC, defineSUN_LEN,F_ADD_SEALSmacros. - Custom
qtwaylandscannerbuild path forkdeflavor.
Stubs / half-impls (recipe level):
#TODO: KWin — full build with Qt6Quick/QML. Effect frames, scripted effects, OSD overlay, outline overlay all enabled.atrecipe.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.# CMakeLists.txt stripped: killer (X11-only) subdirectory disabled:recipe.toml:84. The X11 session killer is not built; the Wayland path is.UiToolsdependency removed:recipe.toml:82. KCM UI builder dependency disabled.Canberramade optional:recipe.toml:79-83, 64. Sound effects on focus changes fall back to no-op.- Custom
hostbuild ofqtwaylandscanner_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— providesepoxy::epoxycmake target, but the.sois 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, everyepoxy_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; allcmsDoTransform-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. Perlibinput/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
*-stubdependencies 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)andpkg_check_modules(.* QUIET)(recipe.toml:48-60). - Patches
ioctl(STDIN_FILENO, TIOCSCTTY, NULL)for relibc. - Removes
XAuth.cppfrom the helper. - Provides stubs in
stubs/linux/{kd.h,vt.h}andstubs/{utmpx.h,X11/Xauth.h}for missing POSIX/header bits. - PAM provided by
pam-redbearshim (local/recipes/libs/pam-redbear/recipe.toml:1-30). - Compiles.
Stubs / half-impls:
#TODO: SDDM display manager — Wayland-only build. PAM provided by pam-redbear shim.atrecipe.toml:1. The plan is to make the build honest, but multiple X11 bits are still touched.sddm/source/src/daemon/DisplayManager.cpp:156, 160, 164, 195: 4// TODO: IMPLEMENTmarkers in the daemon. These are theaddLocalDisplay,addRemoteDisplay,addSocketDisplay, and similar entry points. They return false or empty.sddm/source/src/daemon/DaemonApp.h:42:// TODO: move these two away.stubs/X11/Xauth.h(19 lines) andstubs/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.pam-redbearis a stub too (local/recipes/libs/pam-redbear/recipe.toml:1-30): a 5-symbol shared library that proxies auth toredbear-authdvia Unix socket JSON. Real, but thin.
Real config wiring (redbear-full.toml:567-590):
/etc/sddm.confis hand-installed with the right env vars and theCompositorCommand=/usr/libexec/sddm-helper-start-wayland kwin_wayland --drm /scheme/drm/card0./usr/share/wayland-sessions/plasmawayland.desktopis hand-installed.
LoC estimate:
- 4
// TODO: IMPLEMENTinDisplayManager.cpp: ~400 LoC - Real
pam-redbearPAM 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.login1D-Bus interface (subset for KWin's needs). - Seats, sessions, device map, ACPI watcher.
- Service registered as
13_redbear-sessiond.serviceinredbear-full.toml:315-327, depends on12_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-drmregisters a notifier on/scheme/drm/card0ready event.vesadlistens for that event and tears downdisplay.vesa.fbcondandfbbootlogdre-open the display via the v2 inputd handle (ConsumerHandle::open_display_v2()— already implemented atfbcond/src/display.rs:27andfbbootlogd/src/scheme.rs:44).- During the brief window, an app that opens
/scheme/display.vesashould 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:
- 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). - The session bus is normally started by SDDM's greeter; in this config,
dbus-launchis not present, so the session bus is whatever SDDM provides natively. redbear-sessiondis the system bus broker fororg.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:
- R12 (DrmPanelOrientation): Consumer in
redox-drmis deferred until compositor rotation lands. The 36-entry table is correct data; the consumer reads it but does nothing. - R13 (PlatformDmiQuirkFlags): Consumer wiring deferred. inputd, acpid, thermald do not yet read the platform subsystem dispatch.
- R14 (CpuBugFlags): Kernel-side consumer deferred. The 27 X86_BUG_* bits are defined; the kernel does not use them.
- R15 (ClocksourceQuirkFlags): Kernel
Hpet::init()does not consultPMTMR_BLACKLISTetc. - R17 (ChipsetQuirkFlags): Kernel-side consumer deferred. The 11-entry table is data-only.
- R20 (UsbAudioQuirkFlags): redbear-usbaudiod does not consume the 30-entry table.
- 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-quirkspackage. The 22 TOML files are installed via theredbear-quirksrecipe (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/dmiwas 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.serviceis referenced by30_console.serviceand31_debug_console.servicebut is not defined. The console may not start.12_boot-late.targetis referenced by12_dbus.serviceand not defined. The D-Bus service may not start until the cook recipe provides a service file with that name.10_evdevd.serviceis referenced by12_sddm.serviceand others; not defined here. May come from a recipe-level default.04_drivers.targetis referenced; comes fromredbear-legacy-base.toml(config inheritance, line 17 of redbear-full.toml saysinclude = ["redbear-mini.toml"]).00_driver-manager.serviceis referenced; not visible in the redbear-full.toml — comes from a base recipe.00_ipcd.serviceis referenced; comes from base.00_acpid.serviceis 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.servicefrom 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.servicerequires12_boot-late.targetwhich 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.serviceto start before SDDM, but SDDM requires both13_redbear-sessiond.serviceAND13_seatd.service— which means SDDM correctly waits for both. The order is correct. - Step 14 (redbear-sessiond):
13_redbear-sessiond.servicerequires12_dbus.serviceonly. Good. - Step 15 (redbear-authd):
11_redbear-authd.service(note the 11 prefix, out of numeric order) requires only12_dbus.service. Good. - Step 16 (SDDM): requires everything. Good.
Other issues found in the config:
- The
12_sddm.serviceisoneshot_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_asyncand runs a 600-character shell command embedded in the TOMLdatafield. This is a real anti-pattern: shell scripts should be in/usr/lib/redbear-diag/as.shfiles, 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:
- 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. - SDDM is
oneshot_asyncwith no supervision. - The 99_kwin_test service is an in-TOML shell script.
- 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:
- Add a scheme-watcher in
vesadthat listens forscheme:drm/card0to be created. - On creation, call
libredox::call::unregister_scheme(...)fordisplay.vesa. - Add a fallback: if
scheme:drmis not created within N seconds, keepdisplay.vesafor debugging. - Document the behaviour change in
redbear-full.tomlconfig.
This is a 2-week, ~300 LoC change.
Implementation Roadmap
Phase 1: Unblock Display Handover (2 weeks, ~800 LoC)
- vesad handoff (
local/sources/base/drivers/graphics/vesad/src/main.rs:86-87+ newhandoff.rs):- Watch
/scheme/drmfor thecard0file. - On detection, unregister
display.vesavialibredox::call::unregister_scheme(...). - Add a CLI flag
--no-handofffor debugging.
- Watch
- Initfs vesad exit signal (in
init.d/50_rootfs.serviceor a new51_vesad-stop.service):- Send SIGTERM to vesad's PID after rootfs is up.
- Remove
virtio-gpudfrom initfs.toml:local/sources/base/drivers/initfs.toml:32-37should drop thevirtio-gpuentry; rely onredox-drmexclusively.
- Add a watchdog in the rootfs
10_redox-drm.serviceto restart redox-drm if/scheme/drm/card0disappears.
Phase 2: Wire Init Auto-Restart and Shutdown (3 weeks, ~1,000 LoC)
- Auto-restart loop in
init/src/scheduler.rs:- Add
enum JobKind { Start, Stop, Restart }. - Add
OnFailure=restart,RestartSec=5s,StartLimitBurst=3,StartLimitIntervalSec=60stoUnitInfo.
- Add
- Poweroff/reboot:
- Add
reboot(2)andpoweroff(2)syscalls to kernel;initcalls them on a magic file (/run/systemd/rebootor similar).
- Add
- Multi-user target:
- Replace the
for entry in entriesloop ininit/src/main.rs:153-173with a singlemulti-user.targetschedule that pulls in the dep graph.
- Replace the
- Status reporting:
- Pipe
waitpidstatus to a ring buffer; expose as/scheme/init/status.
- Pipe
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:
- libepoxy: replace with the real libepoxy 1.5.10 recipe (local or upstream). Real GL/EGL function pointer loading.
- libxcvt: real libxcvt (it is small, ~300 LoC of pure C).
- libdisplay-info: real libdisplay-info 0.2.0 (the stub is bounded to base EDID; the real lib supports CTA/DisplayID too).
- lcms2: real lcms2 2.15. The stub has 8 functions; the real lib has ~100.
- libudev: real libudev (or
udev-shimproper, exposingscheme: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)
- Implement 4
// TODO: IMPLEMENTinlocal/recipes/kde/sddm/source/src/daemon/DisplayManager.cpp:156,160,164,195. These areaddLocalDisplay,addRemoteDisplay,addSocketDisplay, etc. Real implementations need to talk toredbear-sessiondfor seat assignment. - Replace
pam-redbearshim 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-authdfor the auth backend.
- Remove
stubs/linux/{kd.h,vt.h}andstubs/X11/Xauth.hin favour of real relibc headers. - 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)
- 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).
- Implement
- Re-enable KWIN_BUILD_QML_UI=ON in
kwin/recipe.toml:155-165. - Re-enable KWIN_BUILD_SCREENLOCKER, KWIN_BUILD_TABBOX, KWIN_BUILD_GLOBALSHORTCUTS, KWIN_BUILD_KCMS — each is a separate piece of QML/Quick UI.
- Add DrmPanelOrientation consumer in redox-drm (R12 deferred).
- 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-drmhandoff. 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-miniboots to a text console on QEMU ✅ (per the project README).redbear-fullboots to a text console on QEMU (vesad + fbcond work) ✅.redbear-fullboots to a black screen ifredox-drmis missing (the10_redox-drm.serviceshell 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: IMPLEMENTin 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
*-stubdeps 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.