Adds the local recipe.toml files for pipewire and wireplumber
under local/recipes/libs/. Both recipes are now properly tracked
as Red Bear OS custom recipes that follow the local-over-WIP
convention.
The recipe.toml files document:
* the upstream version (0.3.85 for pipewire, 0.4.14 for
wireplumber) and the v6.0 2026 Red Bear description
* the build dependencies (glib, dbus, expat, pipewire for
wireplumber)
* the build command (cookbook_meson with Redox-specific
meson flags disabling ALSA, BlueZ, V4L2, JACK, systemd,
elogind, etc.)
* the redox_compat/ shim headers that stage byteswap.h and
sys/mman.h into the per-recipe sysroot so the meson
subprojects (spa/plugins/*) see them
The 'source' symlinks (absolute paths) and the
recipes/wip/services/{pipewire,wireplumber} symlinks were
already wired up in the previous redbear-full commit.
The redbear-full desktop target now pulls in pipewire and wireplumber
as the audio backend for KDE Plasma (Phonon, KMix, the Plasma audio
widget). This wires up the packages built by the new
local/recipes/libs/pipewire and local/recipes/libs/wireplumber
recipes on top of the existing audiod scheme daemon in the base
package.
Changes:
* config/redbear-full.toml
- new [packages] entries for pipewire and wireplumber
- two new [[files]] init services: 15_pipewire.service and
16_wireplumber.service (both oneshot_async, depend on
12_dbus.service)
* local/recipes/system/redbear-dbus-services/files/
- new org.freedesktop.PipeWire.service (system bus, runs
/usr/bin/pipewire) and org.pulseaudio.Server.service
(system bus, runs /usr/bin/pipewire-pulse)
- new org.freedesktop.impl.pulseaudio.service (session bus,
runs /usr/bin/pipewire-pulse) for KDE Phonon / KMix
- matching .conf policy files for org.freedesktop.PipeWire
and org.pulseaudio.Server that allow the expected
Introspectable / Properties / *Manager / *Node / *Link /
*Client / *Device / *Meter / *Core / *Port send and
receive patterns
* config/protected-recipes.toml
- new [libs] entries for pipewire and wireplumber, so the
cookbook never silently re-fetches them; sources are
directly editable in local/sources/
* recipes/wip/services/{pipewire,wireplumber}
- replaced the tracked WIP directories with symlinks to
local/recipes/libs/{pipewire,wireplumber}, per the
local-over-WIP convention enforced by
local/scripts/build-redbear.sh
Known build state (documented in the upstream README-redbear.md
files in each source fork):
* pipewire build reaches ~24/603 C files compiled before
hitting relibc gaps (sys/prctl.h, sys/mount.h, and a few
Linux-specific ioctls). The recipe, source fork, and
Redox-compat shims are in place; the remaining work is
upstream relibc headers, not PipeWire porting decisions.
* wireplumber recipe is in place but the build has not been
attempted yet — wireplumber depends on the pipewire build
completing first.
The audiod integration (the scheme backend that pipewire would
talk to) is not implemented in this commit. That is the next
gating work item and is tracked in
local/sources/pipewire/README-redbear.md.
The StubBackend returned hardcoded SSIDs ("demo-ssid", "demo-open")
and synthesised connection outcomes without ever touching the iwlwifi
driver or netstack. This was a stub that hid the real work needed to
control Intel Wi-Fi devices on Redox.
This commit removes the StubBackend entirely and renames the existing
real PCI/iwlwifi-aware backend from IntelBackend to IwlwifiBackend.
The renamed backend is the default; when no Intel Wi-Fi device is
detected, the NoDeviceBackend is selected (which is the legitimate
"no hardware present" path, not a stub).
Backend mode selection (in main.rs):
- REDBEAR_WIFICTL_BACKEND=iwlwifi|no-device: explicit override
- redox runtime + iwlwifi driver + Intel interface detected: Iwlwifi
- everything else: NoDevice (no silent stub fallback)
The IwlwifiBackend talks to /usr/lib/drivers/redbear-iwlwifi via the
existing Command-based action plumbing (--prepare, --init-transport,
--activate-nic, --scan, --connect, --disconnect, --retry, etc.), which
in turn maps BAR0 MMIO, loads ucode/pnvm, and drives the iwlwifi
device. The previously-stripped stub output paths (firmware=stub,
transport=stub, transport_init=stub, connect=stub, disconnect=stub)
are gone; every status field is now sourced from the real driver or
returned as an honest error from NoDeviceBackend.
Version bumped 0.1.0 -> 0.2.3.
Tests:
- 17 unit tests pass on host target (replaced 4 stub_* tests with
no_device_* and iwlwifi_transport_probe_honors_driver_action).
- 2 CLI integration tests pass (cli_transport.rs unchanged).
- cargo test 19/19 green.
- ./target/release/repo cook redbear-wifictl: successful; produces
repo/x86_64-unknown-redox/redbear-wifictl.pkgar and .toml with
version 0.2.3.
The initfs already starts inputd (in phase 1) and registers the
'scheme input/evdev'. The rootfs 29_activate_console.service was
calling 'inputd -A 2' from minimal.toml, which the v6.0 inputd
binary does not accept (no -A flag; v6.0 inputd is a pure scheme
daemon that registers the single-producer evdev ring buffer).
Override the rootfs service with a no-op ('true') that satisfies
the unit dependency chain without re-spawning inputd. The actual
input pipeline (drivers writing Linux evdev, evdevd reading from
the scheme, libinput/KWin consuming /dev/input/eventN) works
without this redundant rootfs invocation.
The v6.0 single-producer input architecture registers the input
producer scheme as 'input/evdev' (not the legacy 'input' scheme).
Without this update, the initfs would try to register 'input' but
the inputd binary would attempt to register 'input/evdev' — leading
to a 'scheme already registered' error or a missing scheme entirely.
Also update the description to reflect the v6.0 role: pure evdev
ring buffer (not the legacy VT input and graphics multiplexer).
The 4 service files (org.kde.ksmserver, org.kde.JobViewServer,
org.kde.ActivityManager, org.freedesktop.StatusNotifierWatcher)
existed in local/recipes/system/redbear-dbus-services/files/ but were
never mirrored into source/ where the build actually reads in offline
mode. This meant only 3 of the 7 session-service activation files
reached the staged package.
Also fix org.kde.kglobalaccel.service to point at the real install
location: kglobalacceld is installed to /usr/libexec/ (KDE_INSTALL_LIBEXECDIR),
not /usr/bin/.
Sync files/session-services/org.kde.kded6.service to the offscreen-QPA
wrapper that the build was already shipping from source/.
Build now stages all 7 session-service files plus 4 system-services
and 4 policy files (15 dbus config files total).
Cross-cutting changes tied to the libepoxy/libxcvt/libdisplay-info/
lcms2/libudev stub-removal work:
- config/protected-recipes.toml [graphics]: add libepoxy, libxcvt,
libdisplay-info, lcms2 (real Red Bear recipes under local/recipes)
- config/protected-recipes.toml [libs]: drop the 5 *-stub entries,
add 'libudev' (renamed from libudev-stub)
- local/recipes/AGENTS.md catalog: drop the 5 *-stub rows, update
the 5 real lib rows to reflect the v6.0 2026 fork
- local/scripts/apply-patches.sh: drop the 5 *-stub symlink
creation entries; add libudev symlink entry
(The redbear-full.toml package list was already updated to enable
libdisplay-info, libxcvt, lcms2 and add libudev, as part of the
pam-redbear commit that included both changes.)
The libudev-stub was a real 1314-line libudev implementation backed
by the /scheme/udev producer (driven by udev-shim) — not a stub in
the zero-tolerance sense. It was named -stub to make the bounded
hotplug-event-delivery scope obvious.
Rename the recipe to libudev to match the upstream systemd surface it
implements (the recipe still backs through scheme:udev, but the public
name now matches the library's actual role for KWin tablet / input
discovery and libinput's udev device enumeration). Update:
- local/recipes/libs/libudev/recipe.toml: bump to 0.2.3, drop the
#TODO: stub-style header, add v6.0 2026 description
- local/recipes/libs/libinput/recipe.toml: dependency now 'libudev'
- local/recipes/kde/kwin/recipe.toml: dependency now 'libudev'
- config/protected-recipes.toml [libs]: now lists 'libudev'
The libudev.pc, UDev::UDev CMake target, and libudev.so surface are
unchanged — they are the real libudev C ABI as required by KWin and
libinput, with /scheme/udev/devices as the data source.
The lcms2-stub was a CMake-imported shared library that returned
NULL/zero from every API: cmsOpenProfileFromMem, cmsCreateTransform,
cmsDoTransform, cmsCreate_sRGBProfile, cmsGetProfileInfo, and the
rest. KWin color correction, ICC profile lookup, and color space
transformation were silently broken — every transform call produced
identity output.
Replace it with the real lcms2 (mm2/Little-CMS lcms2.19 fork) — the
full upstream C source built via CMake, providing real profile
parsing, gamut mapping, ICC v4 / v2 profile handling, sRGB profile
generation, and the LittleCMS transform pipeline. Recipe bumped to
0.2.3 with v6.0 2026 description.
The libdisplay-info-stub was a bounded 11k shim that parsed only base
EDID vendor/product, strings, physical size, chromaticity, and the
preferred-timing descriptor. All other di_edid_* / di_cta_* /
di_displayid_* calls returned NULL or fell through to the stub.
KWin output configuration, display detection, and EDID-based
connection setup were silently degraded.
Replace it with the real libdisplay-info (emersion/libdisplay-info
fork) — a full C implementation that exposes the libdisplay-info
EDID parser API (di_info_parse_edid, di_edid_get_vendor_product,
di_edid_get_display_name, di_edid_get_screen_size, etc.) with
complete EDID 1.4 parsing of base block + extensions. CTA and
DisplayID remain unsupported in the bounded v6.0 2026 fork, which
is documented in the [package] description. Recipe bumped to 0.2.3.
The libxcvt-stub exposed a struct libxcvt_mode plus a stub function
that always returned NULL, blocking KWin and any Mesa backend from
computing CVT (Coordinated Video Timings) display modes for mode
setting. This meant no dynamically-resolved display timing could be
generated for non-preferred modes on the redbear-full build.
Replace it with the real libxcvt (freedesktop.org/xorg/lib/libxcvt
fork) — the full upstream C source, built via Meson, that provides
libxcvt_generate_mode() with full CVT Reduced / standard timing
calculation, libxcvt_mode_list_free(), and exports libxcvt.pc plus
the proper include path. Recipe bumped to 0.2.3 with v6.0 2026
description.
The libepoxy-stub provided a hardcoded stub that returned 0/NULL for
every epoxy_egl_extension_supported, epoxy_has_gl_extension, and
epoxy_gl_version call, plus a fake epoxyConfig.cmake. KWin and Qt6
Wayland code paths were never able to detect GL/EGL extensions or
negotiate GL versions, which broke the KWin rendering pipeline silently.
Replace it with the real libepoxy (anholt/libepoxy fork) — the full
upstream C source, built against Mesa EGL/GLES2, that registers
epoxy::epoxy in CMake, provides libepoxy.pc, and produces the real
epoxy_gl_version / epoxy_has_gl_extension / epoxy_egl_*_supported
runtime values. Recipe bumped to 0.2.3 with v6.0 2026 description.
Also: protected-recipes.toml [libs] no longer lists the stub.
Promote the four runtime TOML loader families from pub(crate) to pub
so consumers (acpid) can call them directly at startup:
* read_toml_cpu_bug_entries / parse_cpu_bug_toml / load_cpu_bug_flags
* read_toml_clocksource_entries / parse_clocksource_toml / load_clocksource_flags
* read_toml_chipset_entries / parse_chipset_toml / load_chipset_flags
* read_toml_usb_audio_entries / parse_usb_audio_toml / load_usb_audio_flags
These read /etc/quirks.d/*.toml at startup and OR-accumulate the
flags. Exposing them makes the quirks system data-driven for any
caller, not just compiled-in drivers. The semantics are unchanged;
only the visibility bumps from pub(crate)/fn to pub.
2026 Red Bear OS.
llvm21 is a Mesa (graphics) build dep used by mesa and libepoxy for
shader compilation. It is NOT required for the redbear-mini or
redbear-grub text-only targets, but the pre-cook list was cooking
it unconditionally, adding a 30+ minute stall to every mini build.
Pre-cook only relibc + icu for mini/grub. The full desktop chain
(including llvm21) is still pre-cooked for redbear-full.
The pre-cook list (kwin, sddm, qtbase, mesa, libdrm, libepoxy,
redox-drm, lcms2, libdisplay-info, libxcvt) is the desktop graphics
chain. It only applies to redbear-full. For redbear-mini and
redbear-grub (text-only targets), trying to pre-cook kwin and sddm
fails because their build dependencies (QML/QtQuick, libxcb, etc.)
are not in the mini/grub compile surface.
Pre-cook only relibc + icu + llvm21 for mini/grub; pre-cook the full
desktop chain for full.
KWin CMake config does find_package(Fontconfig) and needs the
fontconfig.h header at /usr/include/fontconfig/fontconfig.h.
fontconfig wasn't previously in the build deps, so the CMake
fontconfig module couldn't find the headers and failed.
libxcb is in recipes/wip/x11/ which is not safe upstream ownership for
Red Bear shipping decisions. KWin on Wayland does not need X11 — the
recipe already builds with -DKWIN_BUILD_X11=OFF -DKWIN_BUILD_X11_BACKEND=OFF
and the build script removes #include <xcb/xcb_cursor.h>. The libxcb
dep was leftover from a full X11+KWin build and is not required for
the Red Bear Wayland-only compositor path.
- /var/log and /var/run: override base.toml's 0o755 (root-only write) to
0o1777 (sticky-bit world-writable) so log/run daemons running under
non-root users (messagebus, etc.) can create files in them.
- 00_rtcd.service: remove invalid uid=0 field. The init service parser
uses serde(deny_unknown_fields) and only accepts cmd, args, envs,
inherit_envs, type — uid caused 'unknown field uid' parse error.
v6.0 prep. Description now says 'writes Linux evdev events to
/scheme/input/evdev' instead of 'orbclient format and pushed to
inputd'. The Cargo.toml orbclient dep is removed; the main.rs
still uses orbclient::Event but will be refactored to use
inputd::EvdevProducerHandle in a follow-up commit (the main.rs
refactor is large enough to warrant its own commit for review).
The v6.0 desktop plan replaces the dual-path input architecture
(inputd orbclient + evdevd bridge) with a single Linux evdev
producer. evdevd now reads from /scheme/input/evdev and relays
events as-is to its per-device queues.
Changes:
- main.rs: InputConsumer opens /scheme/input/evdev (not
/scheme/input/consumer). Reads 8-byte WireEvent records
(u16 type, u16 code, i32 value) — matches Linux
struct input_event (sans time fields, which evdevd's
types::InputEvent::new adds).
- main.rs: dispatch_evdev_event() replaces the orbclient
EventOption translation logic. Events go straight to the
scheme's queue.
- main.rs: drop unused 'use size_of' and 'use orbclient' imports.
- scheme.rs: new push_input_event(event_type, code, value)
method. Routes events to the correct device (keyboard,
mouse, or touchpad) based on event type/code. SYN_REPORT
is broadcast to all devices so the libinput consumer sees
a complete report.
- scheme.rs: new queue_raw_event() helper for push_input_event.
- main.rs: log message updated to 'v6.0 single-producer mode'.
The legacy feed_*() methods (orbclient -> evdev translation)
remain in scheme.rs for now, used by the existing unit tests
and as a fallback path. They will be removed in a follow-up
cleanup once /scheme/input/evdev is confirmed working in QEMU.
cargo check --target x86_64-unknown-redox: 0 errors, 26 warnings
(all warnings are in legacy translate.rs/feed_* methods that
are now unused but kept for backward compat).
After review push-back on the dual-path (orbclient + evdev) input
architecture, the v6.0 plan is simplified to a single evdev producer
model. The user committed: 'we do not use Orbital and do not plan to
use it. we aim for wayland/kde.'
The dual-path was rejected for:
- Doubling every driver's event-write code
- Doubling per-event syscall cost
- Out-of-order risk between the two producers
- Translating back and forth loses metadata
- No desktop consumer actually needs Orbital
The corrected architecture:
Hardware
-> single /scheme/input/evdev producer (Linux struct input_event)
-> evdevd (pure scheme->/dev/input/eventN adapter)
-> /dev/input/eventN
-> libinput in-process to KWin (user session)
-> libinput in-process to redbear-compositor (greeter)
-> direct evdev fd (Qt6 apps that need raw access)
inputd is deprecated for the desktop config. It stays in the tree
only as a historical daemon.
What this changes:
1. Phase 1 effort drops from 1-2 weeks to 1 week
2. Drivers change ONCE (replace ProducerHandle with
EvdevProducerHandle) instead of dual-writing
3. evdevd refactor is now cleaner: just switch its consumer from
/scheme/input/consumer (orbclient) to /scheme/input/evdev
(Linux evdev)
4. inputd/src/lib.rs gains a new EvdevProducerHandle, EvdevEvent,
keycodes module — committed in the base fork first
Plan updates:
- Section 2 (Unified Input Architecture) rewritten to 'Single-Producer
Input Architecture'
- Critical path Phase 1 row updated to reflect 1-week effort
- Executive summary text updated
- 'Two Architecture Decisions Resolved' updated to reflect
Orbital-out decision
This is a full v6.0 rewrite of the desktop plan, produced after:
1. Booting CachyOS desktop ISO (cachyos-desktop-260426.iso, 2.9GB) in QEMU
11.0.0 to establish the reference baseline.
2. Six parallel research agents that audited the full Red Bear stack
against the CachyOS reference and Linux 7.1 kernel source.
3. Resolution of two architectural questions that v5.x punted on.
Two non-negotiable architecture decisions (v6.0):
A. UNIFIED INPUT ARCHITECTURE: every input driver writes to BOTH
/scheme/input/orbclient (for Orbital) and /scheme/input/evdev (for
KWin + libinput). No more inputd <-> evdevd bridge that loses
metadata (timestamps, axis ranges, vendor IDs, SYN_REPORT).
Matches CachyOS/Linux: one kernel-evdev path, all consumers
read from it.
B. KWIN IS THE PRIMARY COMPOSITOR: redbear-compositor (788-line
Rust) is too small to reach production parity with KWin in any
realistic timeframe. KWin is used for the user session;
redbear-compositor hosts only the greeter (minimal xdg-shell +
wl_keyboard events are still needed for the greeter to function).
Critical path rework (v6.0):
- Phase 0: QML JIT gate (4-6 weeks) — moves to pre-flight because
it blocks 12 KF6 packages and KWin. Without QML, no Plasma.
- Phase 1: Unified input (1-2 weeks) — resolves the inputd/evdevd
proliferation.
- Phase 2: DRM atomic modeset + render node + PRIME real FDs +
RESOURCE_MAP_BLOB (2-3 weeks).
- Phase 3: Mesa EGL Wayland fix (1 week).
- Phase 4: Compositor greeter — redbear-compositor adds
xdg-shell + wl_keyboard events (2-3 weeks).
- Phase 5: KWin real build (2-4 weeks).
- Phase 6: PipeWire + wireplumber + audiod bridge (6-8 weeks).
- Phase 7: Plasma shell (4-6 weeks).
- Phase 8: QEMU E2E validation (1-2 weeks).
- Phase 9: Intel ARC track (parallel) (12-20 weeks).
Coverage inventory (v6.0):
237 components audited across 14 categories.
86 real (36%), 41 partial (17%), 110 missing (46%).
Detailed gap matrix in §8.
Intel ARC support:
Added as Phase 9 parallel track — requires Mesa iris + Xe driver
cross-compile + real hardware validation.
Total: 22-32 weeks to functional software-rendered KDE Plasma
Wayland desktop on QEMU. +4-8 weeks for Mesa virgl. +12-20 weeks
for real Intel ARC hardware.
This supersedes v5.0 and v5.1 in full. The v5.x changelog sections
(§9, §9.1, §9.1.1) are retained as historical record.
Two parallel review agents cross-checked the virtio-inputd driver against
the Linux 7.1 reference (drivers/virtio/virtio_input.c, virtio_input.h)
and the proven redox-drm virtio transport. 12 issues were found across
BLOCKER, MAJOR, MINOR, and NIT severity, all fixed in this commit before
runtime testing.
BLOCKERs (would have prevented the driver from working in QEMU):
1. fill_avail() never wrote avail_idx after pushing the 64 ring
entries. The device reads avail_ring[avail_idx % size] to discover
new buffers, so without publishing avail_idx = size, the device
saw avail_idx = 0 and ignored all initial buffers. Fix: explicit
'fence(Release); write_avail_idx(self.size)' with a spec citation.
2. drain() recycled IDs derived from 'last_used_idx - drained_count',
which is wrong when the used ring wraps and a single drain cycle
spans more than one full ring revolution. Fix: collect the actual
drained 'id' values in a stack '[u16; 64]' array during the drain
loop, then push those exact ids back to the avail ring. The
doc-comment explains why the derivation is unsafe.
3. config_read_string() and config_read_bitmap() used
'self.device_cfg.size()' (the MMIO region size = 40) instead of
the device-reported config size from offset 2. Fix: use
'config_read_size()' to read the actual size field.
4. config/redbear-full.toml: device_id_range was a TOML string
('0x1042..=0x107F') but serde's Range<u16> deserializes from a
sequence, not a string. pcid-spawner would have silently failed
to load the fragment. Fix: use serde array form
'device_id_range = [0x1042, 0x107F]'.
MAJORs (silent failure modes or runtime bugs):
5. activate_queue() had no fence between address writes and
'queue_enable = 1'. A CPU write buffer may reorder writes to
distinct MMIO addresses. Fix: explicit 'fence(SeqCst)' with
a comment citing virtio spec 2.8 and Linux's virtio_wmb.
6. No 'reset_device()' on error path after partial init. The device
would be left in ACKNOWLEDGE|DRIVER with no driver active,
requiring a guest reboot to recover. Fix: wrap init in a closure;
any error calls 'transport.reset_device()' before propagating.
7. Drain loop never checked DEVICE_NEEDS_RESET or DEVICE_STATUS_FAILED.
If the device entered an unrecoverable state, the driver would
poll forever with stale state. Fix: 'device_in_error_state()' on
the transport; loop checks it each iteration and exits cleanly.
8. The abs_count probe used 'config_read_size() == 24', which was
always false (virtio_input_absinfo is 20 bytes, not 24). The
count was always logged as 0. Fix: '>= 20' per spec.
MINORs / NITs (hardening, no functional impact):
9. config_read_absinfo() returned AbsInfo without validating
device-reported size. Now returns Option<AbsInfo> and validates
size >= 20.
10. map_cap_region() missing bounds check: capability range may
extend past BAR end (QEMU is permissive; bare-metal is not).
Added 'cap_end > bar_size' check with spec reference.
11. Legacy device 0x1052 entry in pcid fragment caused spurious
spawn + log noise. Removed.
12. notify_queue() error silently dropped with .ok(). Now logs warn
and continues.
Plan update:
The CONSOLE-TO-KDE-DESKTOP-PLAN.md v5.1 changelog now has a new
'9.1.1 Phase 5.1 review-driven fixes' section documenting all 12
findings with file:line, severity, and fix. Future maintainers can
trace the BLOCKERs back to specific commits to understand the
critical-path safety net this review provided.
Verification: cargo check zero errors, 64 warnings (all unused
keycode constants reserved for Phase 5.2 expansion). The driver
is now ready for runtime testing in QEMU.
Add a real, QEMU-targeted virtio-input driver as a new Red Bear recipe at
local/recipes/drivers/virtio-inputd/. The driver handles virtio-input-host-pci,
virtio-input-keyboard, virtio-input-mouse, and virtio-input-tablet devices and
closes Gap #19 of the v5.0 desktop plan.
The driver:
* Walks the PCI capability list to find the modern virtio 1.0 capability
block (common_cfg, notify_cfg, isr_cfg, device_cfg) using MmioRegion
mappings via redox-driver-sys. Rejects legacy virtio-input (device 0x1052)
which lacks the modern transport.
* Negotiates VIRTIO_F_VERSION_1 only (the only required feature).
* Allocates one event virtqueue (size up to 64) backed by four DMA buffers
(desc, avail, used, event_buffers) and pre-fills the avail ring.
* Polls the used ring at 60 Hz, drains completed events, decodes each
virtio_input_event (8-byte type/code/value), and recycles drained buffers
back to the avail ring.
* Translates events to orbclient format and pushes them to inputd via
ProducerHandle (Orbital path):
- EV_KEY -> KeyEvent (with US-QWERTY character mapping)
- EV_REL -> MouseRelativeEvent (REL_X/REL_Y) or ScrollEvent (REL_WHEEL)
- EV_SYN -> dropped (inputd multiplexes)
- Other -> dropped (Phase 5.2 will add evdevd path)
Probe-time checks:
* Vendor 0x1AF4, device_id >= 0x1042, revision >= 1
* Caps include a device_cfg block with virtio type == 18 (virtio_input)
Configuration: a pcid-spawner fragment is added to config/redbear-full.toml
under /etc/pcid.d/virtio-inputd.toml matching class=0x09 vendor=0x1AF4 with
device_id_range 0x1042..=0x107F (and a separate 0x1052 entry that the driver
intentionally rejects).
Verification: cargo check produces 0 errors and 65 warnings, all of which are
unused input-event-codes.h constants reserved for the Phase 5.2 expansion.
Linking the binary requires the Redox cross-toolchain (relibc provides
redox_sys_call_v0); this is provided by the build system, not the host
toolchain.
Plan: this is Phase 5.1 of CONSOLE-TO-KDE-DESKTOP-PLAN.md v5.0. The plan is
updated to v5.1 with: (a) a 'What Changed Since v5.0' section, (b) Gap #19
marked DONE, (c) Phase 5 row marked DONE with sub-task status, (d) Gate E
updated, (e) Input pipeline section updated to reflect the (c) path is now
implemented. Phase 5.2 (evdevd producer path + virtio-snd) is documented as
the next planned work but not yet implemented.
Major revision: replaces v4.1 with a code-grounded audit where every claim
is verified by direct source inspection. Corrects several false claims
in v4.1 and adds an honest gap matrix grounded in a live CachyOS
desktop ISO booted in QEMU 11.0 as the functional reference.
Corrections to v4.1:
- audiod EXISTS at local/sources/base/audiod/ (real implementation,
277 lines, mixer with volume control and HANDLE_BUFFER_SIZE=4096)
- redbear-input-headers EXISTS at local/recipes/drivers/redbear-input-headers/
(recipe.toml + source/include/linux/linux/ with input.h, uinput.h)
- inputd is a real producer/consumer multiplexer, not a stub
- synthetic_edid() is not a stub — generates valid 1920x1080@60Hz EDID
with correct checksum
- The Mesa LDFLAGS -lorbital link is the real EGL path issue, not
'EGL works'
New v5.0 findings (not in v4.1):
- ATOMIC ioctl in redox-drm passes empty connectors to set_crtc
(showstopper, scheme.rs:1733)
- No render node (renderD128) — Wayland compositors need this
- PRIME export uses in-memory token, not real DMA-BUF FD — blocks Mesa
- No VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB handler
- No host→guest resize notification processing in IRQ handler
- libdrm missing DRM lease ioctls
- redbear-compositor missing xdg-shell, zwp_linux_dmabuf, wp_presentation,
zwp_linux_explicit_synchronization (showstoppers for modern Wayland)
- redbear-compositor page flip reopens DRM fd every call
- usbhidd/ps2d send to inputd (Orbital path) not to evdevd
- evdevd not in init system of redbear-full
- No virtio-input or virtio-snd drivers (QEMU specific)
Critical path to functional QEMU Wayland desktop (12 weeks, no hardware):
Phase 1: Fix DRM atomic modeset (2-3 weeks)
Phase 2: Fix Mesa EGL Wayland (1 week)
Phase 3: Add compositor protocols xdg-shell + dmabuf + presentation (2-3 weeks)
Phase 4: Wire input pipeline to compositor (1-2 weeks)
Phase 5: Add virtio-input + virtio-snd drivers (1-2 weeks)
Phase 6: QEMU end-to-end validation vs CachyOS (1 week)
Total to software-rendered Wayland desktop on QEMU: 12 weeks.
Total to software-rendered KDE Plasma (QML gate): 18 weeks.
Total to hardware-accelerated QEMU desktop (Mesa virgl): 22 weeks.
Total to real AMD/Intel GPU: 42 weeks (requires hardware).
Replace text-grep cascade detection with a precomputed in-memory graph:
- Build a recipe_index of pkg_name → deps_csv (extracted from
[package]/[build] sections of recipe.toml).
- find_reverse_deps() queries the index in O(1) per package.
- Precompute once, query BFS in O(N) instead of O(N²).
Also fix a bug where empty target string would match every empty-deps
recipe, causing runaway BFS to all 3055 packages (was: 2m40s; now: 6s).
The script now correctly identifies which packages explicitly declare
a target as a [package] or [build] dependency. Implicit cross-compile
toolchain dependencies (relibc, base) are NOT tracked here — they
participate in build via the redoxer/cross setup, not via recipe
declarations. Tracking those requires a different mechanism.
Plan: local/docs/BUILD-SYSTEM-ROBUSTNESS-PLAN.md
- Complete OHCI 1.0 driver supporting USB 1.1 full/low speed devices
- PCI enumeration via BAR0 MMIO mapping
- HCCA and frame list DMA buffer allocation
- Controller reset and initialization sequence
- Port polling and device enumeration via control transfers
- Root hub port status handling with connect/disconnect detection
- Scheme registration for USB device access (/scheme/usb)
- Full ED/TD structures for control transfers
- OHCI spec-compliant register definitions and timing
Gap 7 (OHCI) from LOWLEVEL plan v1.1
- Complete PCI enumeration (class 0x0C, subclass 0x03, prog-if 0x00)
- I/O port register access (inb/outb style via volatile ptr)
- BAR4: I/O port range for operational registers (USBCMD, USBSTS, etc.)
- MMIO-mapped FLBASEADD for frame list base address
- 1024-entry frame list with QH pointers
- Control QH chain for transfer scheduling
- Full controller reset and initialization sequence
- Port polling with connect/disconnect detection
- Device enumeration via control transfers (GET_DESCRIPTOR, SET_ADDRESS)
- Port reset with proper timing (50ms hold, 10ms settle)
- Transfer descriptor (TD) construction for setup/data/status phases
- Wait-for-completion loop with error detection
- All registers documented in registers.rs per UHCI spec
- Scheme interface for scheme:usb access
Completes the daemon side of the Gap 11 fix from LOWLEVEL plan v1.1.
The kernel exposes /scheme/irq/remapping for the iommu daemon to
control the MSI validation gate (set_iommu_remapping_active in
kernel/src/scheme/irq.rs). This change:
- Adds IommuScheme::has_interrupt_remapping() that returns true once at
least one AMD-Vi or Intel VT-d unit has been initialized.
- Adds set_kernel_remapping(active: bool) helper in main.rs that opens
/scheme/irq/remapping and writes "1" (activate) or "0" (deactivate).
- Calls set_kernel_remapping(true) in the main loop after the first
request that leaves a unit initialized. Idempotent: subsequent writes
are harmless.
- Calls set_kernel_remapping(false) unconditionally on exit so the
kernel does not retain stale state if the daemon terminates.
The write failures are non-fatal: in environments where the scheme is
not available (QEMU without PCI passthrough, very early boot), the
daemon continues and MSI delivery works without remapping, which the
kernel handles correctly via the existing fallback in iommu_validate_msi_irq().
Add source_modified() that uses git ls-tree -r HEAD to hash the
contents of all tracked files in a source dir, falling back to
modified_dir_ignore_git for non-git sources. Wire into cook_build.rs
in place of the recursive mtime walk.
Eliminates spurious rebuilds from:
- .swp files, editor backups
- build artifacts in target/ or other untracked dirs
- filesystem timestamp drift after touch operations
The git-tree approach is content-addressed: identical content always
yields the same fingerprint, regardless of mtime. Combined with T1.1
(sysroot content-hash + pkgar mtime preservation), a no-op rebuild
should take seconds rather than hours.
Plan: local/docs/BUILD-SYSTEM-ROBUSTNESS-PLAN.md
After packaging, hash the staged sysroot with BLAKE3 (sorted paths,
deterministic). Compare against the previous build's fingerprint
stored next to stage.pkgar. If identical, restore the old pkgar mtime
on the new pkgar so dependents do not see a 'changed' timestamp and
skip their own rebuilds.
This catches the no-op rebuild pathology where a config-only change
(comment edit, [patch] reordering, dependency re-resolution) produces
byte-identical output but cascades through every dependent because of
mtime advancement.
Verified: 23 fingerprints written during redbear-mini build; T1.1
preserved mtime messages logged for relibc, libffi, expat, glib,
pcre2, etc. — all packages whose content was unchanged from the
previous build.
Plan: local/docs/BUILD-SYSTEM-ROBUSTNESS-PLAN.md
Cross-referenced every stub/gap claim in v1.0 against actual code and
Linux 7.1 reference (local/reference/linux-7.1/). Four parallel audits.
Key corrections to v1.0:
- kernel/src/arch/x86_shared/sleep.rs:257-276 does NOT exist; real PCI
stubs are in acpid/aml_physmem.rs:375-398 (root cause: pcid never
sends fd to acpid)
- EHCI is ALREADY implemented (1538+ lines); the stubs are OHCI and UHCI
- aml_physmem.rs:195, :274 line numbers were wrong; actual stubs at
:213-232 (map_physical_region panic) and :241-280 (read returns 0)
- MSI stub at irq.rs:231 was fixed 2026-06-08 (this audit's first task)
New gaps added (v1.1):
- Gap 11: IOMMU daemon->kernel IRQ integration missing (kernel has
set_iommu_remapping_active() but daemon never calls it)
- Gap 12: MSI multi-vector not exposed (blocks xhcid, nvmed, ixgbed,
redox-drm)
Other corrections:
- DMAR init should move to iommu daemon, not acpid
- >255 CPU ID is a panic (u8::try_from().expect()), not deferred
- hwd legacy backend stub is acceptable (graceful no-op fallback)
Added new sections:
- Section 13: Concrete Fix List (v1.1, ready to execute) with exact
file paths, line numbers, current code, target code, Linux reference
- Section 14: v1.1 Audit Methodology documenting the cross-reference
approach
All execution plan phases updated with corrected tasks, owners, and
verification gates.
Comprehensive 6-tier plan to address the 1.5h full-rebuild pathology
when making small config changes. Covers content-hash output
fingerprinting, per-crate granularity, public API surface tracking,
restat / equivalence caching, and developer-experience tools.
Synthesizes techniques from Nix, Buildroot, Yocto, GN/Ninja, Cargo,
and Bazel adapted to Red Bear OS's Rust cookbook.
Triggered by: 2-line edit to local/sources/base/Cargo.toml caused
1.5h full rebuild of redbear-mini. Root cause: cookbook tracks at
recipe granularity (one stage.pkgar for 45-member Cargo workspace)
instead of crate granularity.
The acpid `_OSI` interceptor was incomplete: firmware that
calls `_OSI("Windows 2015")` or `_OSI("Windows 2020")`
would fall through to the AML interpreter and return 1 (true)
even on systems with `OSI_DISABLE_*` flags set, because
the interceptor only knew about Vista/7/8 strings.
- redox-driver-sys::quirks::AcpiQuirkFlags gains
OSI_DISABLE_WIN10 (bit 14) and OSI_DISABLE_WIN11 (bit 15)
with explicit no-collision guard against the existing
R11/R21 bits (0-13).
- ACPI_FLAG_NAMES in toml_loader.rs maps
`osi_disable_win10` and `osi_disable_win11` to the
new bitflag constants.
- acpid::acpi::AcpiContext::try_intercept_osi now matches
"Windows 2015" → OSI_DISABLE_WIN10 and "Windows 2020"
→ OSI_DISABLE_WIN11, alongside the existing Vista/7/8
string matches.
Source: linux-7.1 drivers/acpi/osi.c (dmi_system_id[] for
Win10/11 laptops that need the kernel to lie about the
host OS to keep ACPI firmware from misbehaving).
cargo test --package redox-driver-sys: 132 passed; 0 failed.
Two findings from the R7 comprehensive review:
1. Boot order race (CRITICAL)
00_driver_manager.service and 00_acpid.service both have the
00_ prefix and no explicit dependency. If driver-manager
enumerates PCI before acpid publishes /scheme/acpi/dmi, every
device gets empty quirk_flags because
redox_driver_sys::quirks::dmi::read_dmi_info() returns Err(())
when the file doesn't exist yet. The OR-accumulation is frozen
at enumeration time so hotplug won't pick up later-published
DMI data.
Fix: add 00_acpid.service to requires_weak for both
00_driver_manager.service (redbear-device-services.toml) and
13_iommu.service (redbear-mini.toml + redbear-full.toml).
2. xHCI typo (CRITICAL)
quirks.d/25-xhci.toml:38 has 'broken_port_pec' which doesn't
exist in the flag name table. The correct flag is
'broken_port_ped' (Port Enabled/Disabled, bit 25 in
XhciControllerQuirkFlags). The typo causes the flag to be
silently dropped at runtime, leaving Intel ICH6 xHCI
(vendor=0x8086, device=0x1E31) without the intended
BROKEN_PORT_PED quirk.
Fix: corrected typo to 'broken_port_ped'.
R12: All 5 ConnectorInfo construction sites (kms/connector.rs
synthetic_displayport, intel/display.rs, intel/mod.rs ..connector
inheritance, virtio/mod.rs both sites, amd/display.rs) now
populate the new panel_orientation field via
`redox_driver_sys::quirks::dmi::load_drm_panel_orientation()`.
The 36 panel orientation rules from 50-drm-panel.toml (Linux
7.1 drm_panel_orientation_quirks.c: Jupiter 0x0B57, Galileo
0x0B47, etc.) now apply to every connector detected.
R13: main.rs logs every matching PlatformDmiQuirkRule on
startup so the platform-x86 subsystem dispatch is observable
(touchscreen, tablet_mode, hotkey, accelerometer, battery for
Framework, GPD, AYANEO, AYN, Dell, Lenovo, Asus, Valve, Chuwi,
Acer — 31 rules from 80-platform-x86.toml).
R21: main.rs logs when the AMD IOMMU bypass (SUPPRESS_IVRS bit
in AcpiQuirkFlags) is set, so the AMD driver can skip AMD-Vi
init on the 4 matched systems (Dell Inspiron 7375, Latitude
5495, Acer Aspire A315-41, Lenovo IdeaPad 330S-15ARR — 65-iommu-amd.toml).
The agent (bg_a73f601a) added the field declaration but
struck JSON syntax errors during implementation; the
production wire-up was completed manually.
cargo check: builds clean (pre-existing E0382 in drivers/fence.rs
test is unrelated).
The R21 AMD IOMMU bypass rules in 65-iommu-amd.toml were missing
the flags line on each entry, so the AcpiQuirkFlags returned
by apply_dmi_acpi_quirk_rules was always empty and the iommu
daemon's check_dmi_ivrs_bypass() never triggered.
Add flags = ["suppress_ivrs"] to all 4 entries (Dell Inspiron
7375, Dell Latitude 5495, Acer Aspire A315-41, Lenovo IdeaPad
330S-15ARR) so the bypass logic actually fires on the matched
systems.
Without this fix, the iommu daemon would attempt to initialize
the broken AMD-Vi silicon and hang the boot on those specific
laptops — the very regression the R21 data file was meant to
prevent.
When /etc/quirks.d/65-iommu-amd.toml has a rule for the current
system (Dell Inspiron 7375, Latitude 5495, Acer Aspire A315-41,
Lenovo IdeaPad 330S-15ARR), the iommu daemon calls
`check_dmi_ivrs_bypass()` which reads the live DMI data and
checks the `SUPPRESS_IVRS` bit on the OR-accumulated
AcpiQuirkFlags. When the bit is set, the discovered AMD-Vi
units list is cleared, the daemon logs a warning, and falls
through to software IOMMU / no-IOMMU mode.
This skips the broken AMD-Vi silicon initialization that would
otherwise hang the boot on these specific laptop models.
Source: linux-7.1 drivers/iommu/amd/init.c (DMI matching
pattern, `acpi_ivrs` DMI table).
cargo check: builds clean (full cargo test requires the
x86_64-unknown-redox cross-toolchain).