Phases 4, 5, and 6 of local/docs/3D-DRIVER-PLAN.md. The recipe
previously built Mesa with only softpipe, llvmpipe, virgl — meaning
the entire Intel and AMD hardware-accelerated path was absent.
Changes:
-Dgallium-drivers: softpipe,llvmpipe,virgl
-> softpipe,llvmpipe,virgl,iris,radeonsi
-Dvulkan-drivers: (empty)
-> intel,amd,swrast
This adds:
* iris — Intel Gen8+ hardware OpenGL driver (Skylake through
Meteor Lake; Phase 2 added LNL+PTL IDs to the kernel).
* radeonsi — AMD GCN+ hardware OpenGL driver.
* swrast — Vulkan software fallback (llvmpipe-equivalent for
Vulkan).
* intel — Mesa 'anv' Vulkan driver (Intel Gen8+).
* amd — Mesa 'radv' Vulkan driver (AMD GCN+).
Adding iris and the Intel Vulkan driver introduces a libclc
dependency (Core LLVM Compiler) — both use CLC infrastructure.
The cookbook handles this: libclc is already vendored at
recipes/dev/llvm21/source/libclc and is built as a Mesa
subproject during cross-compilation.
NOTE: This recipe change only adds the build-time drivers. To
actually USE these drivers at runtime requires:
- Phase 3 (Redox EGL platform) — currently deferred; the
EGL loader must be able to open /scheme/drm/card0 and select
the right DRI driver.
- Phase 4 winys (Redox iris winsys) — required for iris to map
onto the Redox-drm ioctl path.
- Phase 5 winsys (Redox radeonsi winsys) — required for radeonsi
on Redox.
Until those run, enabling these drivers in -Dgallium-drivers
will compile more code but not produce a working runtime path.
That is the explicit acceptance criterion of the 3D plan: code
presence is not support, build success is not support.
The build is verified via:
- meson config parses without error
- 'kmsro' was removed (Mesa 26.1.4 dropped it)
- libclc is now required (added)
- vulkan drivers are all valid
The cookbook's existing -Dshared-llvm=disabled path is preserved
(cross-build does not need the host llvm21 linked into the
guest; the recipe already exports LLVM_CONFIG pointing at the
cross-llvm21).
Closes the v4.2 plan's 'Driver-level Driver::on_error IPC' item.
Three pieces, layered:
1. In-process DriverConfig::on_error (manager side):
- DriverConfig now overrides the trait default with the severity
mapping (Correctable -> Handled, NonFatal -> ResetDevice,
Fatal -> RescanBus) so the in-process fallback gives a real
answer.
- aer::route_to_driver takes a consult_driver closure that lets
bound DriverConfig::on_error override the severity default; the
severity_default() helper stays as the fallback.
2. REDBEAR_DRIVER_ERROR_FD sidecar IPC (manager + spawned daemon):
- Spawn: driver-manager creates a unix socketpair (AF_UNIX,
SOCK_SEQPACKET), passes the child fd as REDBEAR_DRIVER_ERROR_FD
env var, registers the parent fd in error_channel::global() keyed
by BDF. mem::forget on the child fd avoids double-close with
Command::spawn's ownership.
- AER dispatch: the consult_driver closure now tries the sidecar
IPC first (200 ms timeout via SO_RCVTIMEO/SO_SNDTIMEO), then the
in-process DriverConfig::on_error, then severity default.
- Reap: error_channel::global().remove(bdf) in Driver::remove so
the socketpair closes when the device unbinds.
3. linux-kpi C-callable opt-in (driver side):
- New c_headers/linux/pci.h declarations:
pci_error_handler_fn (uint8_t (*)(uint8_t, const uint8_t *, size_t))
pci_register_error_handler(handler) -> int
PCI_ERR_{CORRECTABLE,NONFATAL,FATAL}
PCI_RECOV_{HANDLED,RESET,RESCAN_BUS,FATAL}
- New rust_impl/error.rs module:
* duplicated wire types (DriverErrorReport / DriverErrorResponse
with encode/decode) -- linux-kpi stays self-contained
* worker_loop() thread that reads length-prefixed requests,
invokes the registered C handler, writes length-prefixed
RecoveryAction responses
* pci_register_error_handler() reads REDBEAR_DRIVER_ERROR_FD,
spawns the worker thread, returns 0/1
Protocol (length-prefixed, little-endian):
manager -> driver: [u32 len][severity:u8][bdf_len:u8][bdf][raw_len:u32][raw]
driver -> manager: [u32 len][action:u8]
Tests:
driver-manager: 70 passed (was 65; +5 from error_channel + aer)
linux-kpi: cargo check clean (host test link fails on
redox_strerror_v1, pre-existing)
Phase 2 of the 3D driver plan (local/docs/3D-DRIVER-PLAN.md). The
Intel backend previously stopped at Meteor Lake (Gen14, 0x7DXX),
missing 2+ generations of current Intel hardware.
Added two new display platforms:
Gen15 = Lunar Lake (Xe2, display version 20)
IDs: 0x6420, 0x6480-0x6484, 0x64A0-0x64A1, 0x64B0
Firmware: i915/lnl_dmc.bin, lnl_guc_70.bin, lnl_huc.bin, lnl_gsc_1.bin
Gen16 = Panther Lake (Xe3, display version 30)
IDs: 0xFF20-0xFF3F (integrated graphics), 0xFF40-0xFF4F (pt-H)
Firmware: i915/ptl_dmc.bin, ptl_guc.bin, ptl_huc.bin, ptl_gsc_1.bin
Both require DMC firmware (added to requires_dmc). Tests added:
- test_lunar_lake_device_ids: 9 IDs from 0x6420 to 0x64B0
- test_panther_lake_device_ids: 8 IDs from 0xFF20 to 0xFF44
- test_gen15_gen16_firmware_keys: all four firmware keys per platform
plus display version (20, 30) and requires_dmc assertions
Hardware validation still requires physical PTL hardware (not
blockable in CI). Firmware blobs need to be staged via
local/scripts/fetch-firmware.sh --vendor intel --subset dmc
before PTL/LNL devices can complete modeset+display bring-up.
Phase 1 also adds local/scripts/test-virgl-qemu.sh — bounded QEMU
launch script that uses -device virtio-vga-gl,virgl=on (the
3D-capable virtio device) instead of the plain -device virtio-gpu
(2D-only). Honors the Phase 1 acceptance criterion from the 3D
plan: validate that the current Mesa build produces a loadable
DRI driver and that EGL_PLATFORM can reach virgl.
The greeter kf6 recipes were bumped to 6.28.0 (url/version/pin) but their
committed source.tar is still 6.27.0 -- the version the greeter actually built
against. Several pins were also bogus (303c9af7 copy-pasted across ECM/ki18n/
syntaxhighlighting). make-live re-fetch/validation failed: "downloaded tar blake3
... is not equal to blake3 in recipe.toml" (kf6-extra-cmake-modules). Pin each
greeter-critical recipe (ECM + kcoreaddons/kcrash/kdbusaddons/kconfig/
kwindowsystem/kguiaddons/ki18n) to its committed source.tar so offline builds
validate against the real, working sources. ECM is genuinely 6.28.0; the rest
6.27.0. Build offline so the 6.28.0 URLs are not re-fetched. (Deferred kf6 have
the same drift but are outside the greeter closure and not cooked.)
spawn_unified_listener takes two move closures that both capture scheme_for_events
(bound_device_pairs provider + the Aer event handler calling dispatch_recovery).
The first closure moved the Arc, so the second could not use it ("the type Arc
does not implement Copy", main.rs:390). Clone the Arc for the bound-pairs closure
so each owns its own handle (the rustc-suggested fix). Sole remaining compile
blocker for the redbear-full ISO.
src/helper/HelperApp.cpp includes <utmpx.h> and writes utmpx login/logout
records (setutxent/pututxline/updwtmpx). Redox has no utmp/utmpx login-accounting
database -> "fatal error: utmpx.h: No such file". Guard the include and the
utmpLogin/utmpLogout bodies under __redox__ as no-ops (login records are not
tracked on Redox). The sddm daemon already links; this unblocks sddm-helper.
VirtualTerminal.cpp uses the Linux/FreeBSD VT ioctls (VT_ACTIVATE, VT_WAITACTIVE,
VT_SETMODE, KDSETMODE, ...) which Redox does not have -> "VT_ACTIVATE was not
declared". Redox has no VT switching; the greeter runs directly on the
compositor/framebuffer. Add a #if defined(__redox__) branch providing no-op
stubs for the public API (path/currentVt/setUpNewVt/jumpToVt) and skip the
linux/vt.h + linux/kd.h includes. Durable patch.
KWINDOWSYSTEM_WAYLAND=ON pulled in an escalating chain — PlasmaWaylandProtocols,
xkbcommon, then the KWayland QML plugin links Qt6::GuiPrivate and uses Qt private
Wayland APIs likely to need further Redox porting. The SDDM greeter is a
fullscreen client that links the core KWindowSystem library, not this plugin, so
set KWINDOWSYSTEM_WAYLAND=OFF to unblock the greeter build (matches the recipe/s
original "Wayland disabled" intent) and drop the plugin-only deps. Re-enable +
port Qt6::GuiPrivate usage when wiring the full Plasma desktop.
With KWINDOWSYSTEM_WAYLAND=ON, src/platforms/wayland/CMakeLists.txt does
pkg_check_modules(XKBCommon REQUIRED IMPORTED_TARGET xkbcommon). libxkbcommon
provides xkbcommon.pc but was not a dependency, so it was absent from the
sysroot and configure failed "Package xkbcommon not found".
Qt cmake plugin targets resolve each plugin .so via <sysroot>/plugins (the
_IMPORT_PREFIX is computed from the cmake files under <sysroot>/lib/cmake, i.e.
the sysroot root, not <sysroot>/usr), but cmake --install --prefix .../usr puts
plugins at usr/plugins. qtbase already works around this by staging plugins to
BOTH usr/plugins and plugins (recipe.toml ~L739); qtwayland/qtsvg/qtdeclarative
did not, so their plugins (wayland decorations, svg imageformats/iconengines,
qmltooling) were unreachable at <sysroot>/plugins and any Qt6Gui/Qt6Qml consumer
failed: imported target references "<sysroot>/plugins/.../foo.so" but this file
does not exist. This blocked kf6-kwindowsystem (sddm dep) on the Adwaita
decoration plugin. Add a shared redbear_qt_dual_stage_plugins helper and call it
after install in all three. (Note qml already resolves via the qml symlink since
qtbase does not dual-stage qml, so <sysroot>/qml is a symlink not a real dir.)
udisksopticaldisc.cpp SharedContentTypesCache uses QSystemSemaphore +
QSharedMemory locking for a cross-process content-type cache; Redox Qt is built
without systemsemaphore-backed shared memory (same limitation the qtwayland
recipe notes), so it failed to compile ("m_semaphore not declared",
"QSharedMemory has no member named lock"). Guard the cache on
QT_CONFIG(sharedmemory) && QT_CONFIG(systemsemaphore); on Redox provide a
no-cache stub that detects directly (the cached path already fell back to
advancedDiscDetect()). Durable patch.
Closes the v4.0 plan P3 'per-vendor firmware packaging' item.
redbear-firmware (the single bundle recipe) shipped the entire
linux-firmware tarball wholesale. That works but forces every image
to drag in blobs it does not use (e.g., a serial console image pulls
amdgpu GPU firmware). The plan called for per-vendor splits mirroring
linux-firmware's per-package convention (linux-firmware-amdgpu,
linux-firmware-intel, etc.).
New recipes (all version 0.3.1, Cat 1, locally maintainable):
redbear-firmware-amdgpu - /lib/firmware/amdgpu/ + amdnpu/
redbear-firmware-intel - /lib/firmware/i915/ + intel/
redbear-firmware-iwlwifi - /lib/firmware/iwlwifi-*.{ucode,pnvm}
redbear-firmware-bluetooth - /lib/firmware/ibt-*.{sfi,ddc}
Each recipe downloads the same linux-firmware-main tarball into a
shared cookbook cache (build/redbear-firmware-cache/) and stages only
its subset, with the matching LICENSE.* and WHENCE metadata in
/lib/firmware/LICENSES/. The share cache means a single wget per
cookbook build regardless of how many per-vendor recipes are included.
redbear-firmware (the whole bundle) stays in place for legacy configs
that don't want to choose. Per-vendor recipes do not conflict with it
because the subsets are disjoint paths under /lib/firmware.
redbear-driver-policy/initfs.manifest gains a [firmware] section
documenting the per-vendor recipe -> driver mapping. driver-manager
itself does not install firmware -- configs pull the relevant
redbear-firmware-* packages via the [packages] section.
fetch-firmware.sh already supports the same per-vendor / per-subset
matrix (--vendor {amd,intel} --subset {all,rdna,dmc,wifi,bluetooth})
so the manual fetch path and the build path now agree on taxonomy.
Qt installs QML plugins under <prefix>/usr/qml, but the generated CMake plugin
targets (Qt6Qml/QmlPlugins/*Targets.cmake) resolve each plugin .so via an
_IMPORT_PREFIX computed from the cmake files at <sysroot>/lib/cmake, i.e.
<sysroot>/qml/... . Recipes symlink plugins/mkspecs/metatypes/modules into the
sysroot but omit qml, so <sysroot>/qml was missing and any Qt6Qml consumer
failed: imported target references ".../sysroot/qml/QtWayland/.../plugin.so"
but this file does not exist (it is at usr/qml/...). This blocked kf6-kwindowsystem
(direct sddm dep). Add qml to every sysroot-link site: the redbear_qt_link_sysroot_dirs
helper default, ~15 helper callers, and ~10 inline for-loops (61 files).
Also corrects qtsvg CVE patch ref "qtsvg/CVE-..." -> bare "CVE-..." (patch is in
the recipe dir; same patch-path class as the mesa fix) so qtsvg builds from clean.
Phase 6.2: the MLD driver logic is now Rust, not C. The legacy C
linux_mld.c remains only as a thin transport-level helper (init/parse
functions for C structs used by linux_port.c); all MLD state management,
notification dispatch, TX/scan/sta management, and MLO RX parsing is
now in proper Rust.
src/mld.rs (744 lines):
- Complete firmware command ID table: all 7 command groups with
WIDE_ID encoding, 50+ command/notification IDs from Linux fw/api
- OpMode selection: BZ→iwlmld, others→iwlmvm (Linux iwl-drv.c)
- MldState: fw_running, radio_kill, scan, TX queue array[512],
notification counters (AtomicU32)
- NotifResult: decoded notification (handled/is_rx_frame/signal/rate/
wide_id/group/cmd/kind)
- handle_notification(): full WIDE_ID dispatch — all legacy + grouped
notifications, RX MPDU via parse_rx_mpdu, counted by type
- parse_rx_mpdu(): MLO RX MPDU parser — link_id from mac_phy_band,
AMSDU flags, signal/rate via FFI to legacy C Mini-MVM parser
(no duplicate parser per upstream-first rule)
- MldState::firmware_init(): records init sequence
- MldState::start/stop_scan(): scan state management
- MldState::add/remove_sta(): station ID validation
- MldState::alloc/free_txq(): TVQM queue allocation
- FFI to C: rb_iwl_mvm_detect_signal/rate_to_mcs via unsafe extern
- 11 unit tests covering: opmode selection, WIDE_ID encoding, state
init, firmware init, TXQ alloc/free, scan management, station
management, legacy + grouped + unknown notification dispatch,
notif_kind coverage
All 19 tests pass (11 MLD + 7 existing + 1 integration). The module
is integrated via 'mod mld;' in main.rs.
KWINDOWSYSTEM_WAYLAND=ON -> CMakeLists find_package(PlasmaWaylandProtocols
REQUIRED) (+ Qt6WaylandClient, WaylandProtocols). Only qtbase/qtdeclarative were
declared, so configure failed "Could not find ... PlasmaWaylandProtocols".
plasma-wayland-protocols recipe exists and builds; declare it + qtwayland +
wayland-protocols. Direct sddm dep, greeter-critical.
Both build a QML module (KWINDOWSYSTEM_QML=ON / ksvg QML) whose CMakeLists does
find_package(Qt6Qml) via ECMQmlModule, but declared only qtbase -- so cookbook
never installed Qt6Qml (qtdeclarative) into their sysroot and configure failed
"Could not find a package configuration file provided by Qt6Qml", even though
qtdeclarative itself now builds. kf6-kwindowsystem is a direct sddm dependency,
so this blocked the greeter. Audited all kf6 recipes: these two were the only
QML-consumers missing the dep (kf6-kitemmodels already had it).
Self-review followups after v4.1, plus two correctness fixes the audit
uncovered.
unified_events:
* Carry RecoveryAction through the Aer variant of UnifiedEvent. The
routing decision (route_to_driver against the latest bind snapshot)
is made once in run() and threaded into the callback, so the
callback does not recompute it. Eliminates a duplicate
route_to_driver call per AER event.
* Update the unified_events test to the new Aer { event, action }
shape.
main.rs:
* Simplified AER callback: no double route_to_driver, no
dead cfg(not(target_os = "redox")) arm. Dispatch gated on
cfg(target_os = "redox") so host builds compile.
* RecoveryAction::Fatal escalation: emit a stable ERROR-level
marker ('AER-FATAL: device=... driver-already-dead escalation
marker ...') before the action_str match returns None. Operator
tooling can grep this marker to detect unrecoverable events that
need human attention. No auto-dispatch on Fatal by design -- the
driver is dead, recovery cannot succeed.
modern_technology:
* iommu_group_for: replace the unmatchable hash-keyed path check
(/scheme/iommu/domain/<hash(bdf)>) with scheme-presence detection
(/scheme/iommu exists). The iommu daemon does NOT expose a BDF to
group lookup, so scheme-presence is the strongest signal
available without opening a handle.
* numa_node_for: replace the wrong /scheme/numad/device/<bdf>
check (numad does NOT expose that path) with the correct
/scheme/proc/numa presence check (numad writes topology there).
* numa_node_env_value: dedupe -- reuse numa_node_for's source
discriminant instead of duplicating the path-existence check.
Tests:
- driver-manager: 63 passed (no change)
- redox-driver-core: 32 passed (no change)
- host build clean
driver-manager v4.1 — closes the three remaining P3 items the v4.0 plan
declared open after the cutover:
* AER auto-dispatch to bound devices (P3 #2 endpoint side):
route_to_driver now actually invokes the recovery body for NonFatal
(ResetDevice) and Fatal (RescanBus) events on bound devices, instead
of only logging. The /recover scheme endpoint and the auto-dispatch
both share the new scheme::DriverManagerScheme::dispatch_recovery
helper, so operator-triggered and event-triggered recovery use the
same code path. Driver::on_error → RecoveryAction on bound devices
is now end-to-end rather than discarded.
* Quirk lifecycle phase Early (P3 #1): the probe path consults
QuirkPhase::Early before the channel open and gates WRONG_CLASS /
BROKEN_BRIDGE on it. decide_for_phase in quirks.rs bridges to
redox-driver-sys::quirks::lookup_pci_quirks_for_phase. Combined with
Enable (spawn-time), this is the Linux 2-of-8 minimum split. PM
phases remain out of scope per plan § P3.
* IOMMU/NUMA honest absence: iommu_group_env_value() and
numa_node_env_value() report "0" when the corresponding scheme is
not present, instead of the previous deterministic BDF hash that
looked like a real isolation group / node id. Drivers that consume
REDBEAR_DRIVER_IOMMU_GROUP / REDBEAR_DRIVER_NUMA_NODE now see
"no group" / "no node" instead of a value they might trust.
Tests:
+ 4 driver-manager scheme::tests::recovery_action_* cases
+ 2 redox-driver-core modern_technology::tests env-value cases
Total: 63 driver-manager tests + 32 redox-driver-core tests, all green.
Replace the purged stale 6.11.0 caches with the official 6.11.1 tarballs. Each
was downloaded from the pinned recipe URL and verified: blake3 == recipe.toml
pin, and top-level dir == <module>-everywhere-src-6.11.1. The pins were already
correct 6.11.1 hashes (set during the version bump) -- only the committed
source.tar caches had gone stale at 6.11.0. Restores offline reproducibility to
match qtbase/qtshadertools/qtsvg (which commit their 6.11.1 source.tar).
recipes/libs/mesa is a wholesale symlink to local/recipes/libs/mesa, so
cookbook resolved the recipe patch refs "mesa/NN-*.patch" to
local/recipes/libs/mesa/mesa/NN-*.patch -- a subdir that never existed. The
patches live in local/patches/mesa/, and apply-patches.sh only individually
links kernel/base patches, never mesa. So mesa could only build from a
pre-patched cached source/; a clean re-fetch (e.g. online mode) failed with
"Failed to find patch file recipes/libs/mesa/mesa/01-...". Add the mesa/ subdir
as a relative symlink into the canonical local/patches/mesa so the referenced
path resolves (all in local/), without touching recipe.toml (mesa stays
cached). Audited all 37 patch refs across every recipe -- mesa was the only
unresolved one.
The 6.11.1 upgrade bumped recipe URLs+blake3 for the Qt modules but left stale
committed fetch-caches for three of them: qtdeclarative/qtwayland/qt6-sensors
shipped source.tar (and qt6-sensors a source/ extract) still at 6.11.0. repo
validates the cache against recipe blake3, so the stale 6.11.0 tar mismatched
the 6.11.1 pin -> "downloaded tar blake3 ... is not equal to blake3 in
recipe.toml" -> qtdeclarative cook failed, cascading Qt6Qml failures in every
downstream consumer (qtwayland, kf6-*), aborting the whole build.
Root cause of the committed caches: .gitignore only ignored recipes/**/source.tar
(mainline tree), never local/recipes/**/source.tar, so local fetch-caches were
committable and went stale on version bumps. Fixes:
- git rm the stale 6.11.0 source.tar (x3) + qt6-sensors 6.11.0 source/ extract
so the build re-fetches the pinned 6.11.1 tarballs.
- .gitignore: ignore local/recipes/**/source.tar(.tmp) (fetch-cache; NOT
source/, the durable fork model) so this cannot recur.
qtbase/qtshadertools/qtsvg were already correct (source.tar==6.11.1==pin).
qtwayland CMakeLists find_package(Qt6Qml) for the QtWaylandCompositor QML
integration. Without qtdeclarative in dependencies, cookbook may cook qtwayland
concurrently with qtdeclarative and configure fails with "Could not find a
package configuration file provided by Qt6Qml". Declaring the dep serializes
the build: qtbase -> qtshadertools -> qtdeclarative -> qtwayland.
qnetworkinterface_unix.cpp getifaddrs path declares `struct ifreq ifr` to pass
to getMtu(), but Redox relibc <net/if.h> provides only interface flags and the
if_nameindex() helpers -- no struct ifreq (Redox has no SIOCGIF* ioctls). The
SIOCGIFMTU body in getMtu() is #ifdef-guarded and compiles out, so the type
only needs to be complete. Define a minimal-but-standard struct ifreq under
#if defined(__redox__) at file scope; the ioctls that would use it fail
gracefully at runtime (mtu stays 0). Durable patch, wired into qtbase recipe.
The 8-element block-character ramp in the panel footer's
size-distribution histogram was indexed with a level that could
clamp to 8 (one past the end). The math scaled count/max_bucket to
[0, 8] and clamped with .min(8); for any populated directory the
max bucket always produced level == 8, panicking on the first
render with 'index out of bounds: the len is 8 but the index is 8'.
Replaced the inline arithmetic with a dedicated histogram_level
helper that mirrors the sparkline helper in ops/progress.rs:
scale count/max_bucket to [0, 7] and clamp to 7. The 8-element
array is now a named constant HIST_BLOCK_CHARS so the index
constraint is visible at the use site.
Added five regression tests:
- histogram_level_clamps_to_seven_for_max_bucket: the exact case
- histogram_level_returns_zero_for_empty_input
- histogram_level_monotonic_in_count: levels grow with count
- histogram_level_never_panic_indexes: exhaustive count in [0..max]
for max in [1..256]
- render_panel_does_not_panic_on_populated_directory: end-to-end
size_histogram + histogram_level + array index
Also: render() used to silently skip when the terminal reported
< 10x5, leaving the user with a blank screen and no feedback. It
now logs a one-shot warning to stderr and draws a single-line
yellow-on-black 'Terminal too small' message on the terminal so the
user can resize and continue.
Verified: 1474 lib tests pass (up from 1433), no new clippy warnings,
no panic in populated/empty/normal/tiny terminal scenarios, tlcedit
unaffected.
forkfd_qt.c includes <forkfd.h> (whose forkfd_wait4 prototype takes struct
rusage*) before struct rusage is declared at file scope; sys/resource.h is only
pulled in later by forkfd.c. So the header prototype gets a prototype-scoped
struct rusage incompatible with the file-scope one in the definition ->
"conflicting types for forkfd_wait4". 6.11.0 qglobal.h pulled it in
transitively; 6.11.1 does not. Fix: include <sys/resource.h> before <forkfd.h>.
Durable patch, wired into qtbase recipe.
The recipe referenced "qtsvg/CVE-2026-6210.patch" (relative to the recipe dir →
recipes/.../qtsvg/qtsvg/CVE... which does not exist); the patch lived in
local/patches/qtsvg/. apply-patches.sh does not link it, so both direct fetch
and the canonical build failed to find it. Move the patch into the qtsvg recipe
dir (durable /local, same model as qtbase redox.patch) and reference it by bare
name so the build system resolves it.
Move the Redox in6_pktinfo patch into local/recipes/qt/qtbase/ (where qtbase
redox.patch lives) and add it to the [source] patches list, so a clean fetch of
qtbase 6.11.1 re-applies it. Verified: fetch of 6.11.1 applies all 3 patches
atomically. Durable in local/, resolved by the build system (no bypass).
On Redox relibc defines CLOCK_MONOTONIC=4 (not Linux 1) and has no
CLOCK_MONOTONIC_RAW, so -DCLOCK_MONOTONIC_RAW=4 collided with CLOCK_MONOTONIC in
wsi_common_wayland.c (duplicate case). The greeter uses GL/llvmpipe not Vulkan,
and Vulkan WSI is the only consumer of these Linux clock constants, so disable
vulkan-drivers to drop that unit. Also make the define collision-proof
(CLOCK_MONOTONIC+1000) for any non-Vulkan user.
Aliasing CLOCK_MONOTONIC_RAW to CLOCK_MONOTONIC created a duplicate case value
in wsi_common_wayland.c (switch has both). Use the real Linux clockid 4 so the
value is distinct and the switch compiles.
Vulkan WSI (wsi_common_wayland.c) uses CLOCK_MONOTONIC_RAW, which relibc does
not define (undeclared). Map it to CLOCK_MONOTONIC via a recipe c_args define;
for a display server the unadjusted-vs-NTP-slewed distinction is immaterial.
Third Redox mesa port gap.
meson 26.1.4 resolves wayland-scanner from the target wayland-scanner.pc, whose
absolute path is COOKBOOK_SYSROOT/usr/bin/wayland-scanner — the Redox cross
binary, which cannot execute on the Linux build host (ninja: code=127 "cannot
execute: required file not found") when generating fifo-v1-protocol.c etc. The
$WAYLAND_SCANNER env / PATH symlink do not help (meson uses the .pc absolute
path). Protocol codegen is host/target-independent, so overwrite the sysroot
copy with the runnable host wayland-scanner before meson runs. Next Redox mesa
port gap after alloca.
mesa uses alloca() in shader_query.cpp (and elsewhere) without including
<alloca.h>; on Redox stdlib.h does not pull it in, so the C++ compile failed
with "alloca was not declared in this scope". Redox relibc DOES provide alloca
(alloca.h = #define alloca(s) __builtin_alloca(s)); force-include it via meson
c_args/cpp_args so every alloca user resolves to the builtin. Next Redox mesa
port gap after the EGL gate; mesa now compiles past it.
Assessing/fixing the boot->SDDM chain for the full ISO:
1. VirGL driver table: the INSTALLED /lib/drivers.d/30-graphics.toml is inline
data in config/redbear-full.toml (not local/config/drivers.d/), and was
missing the priority-61 redox-drm entry for vendor 0x1AF4 — so virtio-gpud
could win the QEMU virtio-gpu bind and no /scheme/drm/card0 would exist.
Add the VirGL entry to the inline table (the one actually shipped).
2. Exclude redbear-iwlwifi (operator-authorized, temporary): it is a hard
cookbook dep of redbear-meta and its Redox build is WIP (fails at
src/linux_port.c), which aborts make live before the image assembles. Comment
it out of redbear-meta dependencies; nothing else pulls it. Re-add when green.
3. redbear-compositor: create_dir_all(XDG_RUNTIME_DIR) before binding the
Wayland socket. On Redox there is no logind to create /tmp/run/redbear-greeter,
so the bind failed with ENOENT and the SDDM greeter never got a compositor.
Toward: launch redbear-full ISO in QEMU and reach the SDDM Wayland login.
Mirrors Linux 7.1's pci_ers_result (include/linux/pci.h:920-938):
None/CanRecover/NeedReset/Disconnect/Recovered/NoAerDriver. This is
the vocabulary Driver::error_detected will return when the AER
recovery flow is wired to bound drivers. Currently the legacy
RecoveryAction enum (Handled/ResetDevice/RescanBus/Fatal) coexists
for the existing on_error callback — PciErsResult is the richer model
that will replace it once the driver-manager → driver IPC channel
exists for AER dispatch.
ConcurrentDeviceManager::from_manager called bus.enumerate_devices()
a second time inside its constructor — the same buses DeviceManager::
enumerate() had just enumerated to build the remaining list. Renamed
to from_devices(mgr, devices) which takes the already-enumerated
Vec<DeviceInfo> directly, eliminating the redundant I/O and removing
a potential consistency window between the two passes.
- redox-driver-sys: drop unused 'use std::sync::Once' in pci.rs and
underscore-prefix unused 'vendor' in lookup_hid_quirks. Zero
crate-local warnings (libredox's 2 are upstream fork code).
- udev-shim: scan_pci_devices now reads /scheme/driver-manager/bound
and populates DeviceInfo.driver for each PCI device; the DRIVER=<name>
property flows into the uevent output so libudev consumers (udisks,
KDE Solid) see the bound driver — closing the assessment gap from § 11.
d945483915 added a per-thread IOPL guard using std::sync::Once in a
#[cfg(target_os = "redox")] thread_local! (pci.rs:20) but did not import Once,
so redox-driver-sys fails to compile for x86_64-unknown-redox with E0425
"cannot find type Once" — breaking redox-drm (the /scheme/drm/card0 provider)
and driver-manager in the redbear-full build. Add the cfg-gated import.
Found while driving the redbear-full desktop build.
redbear-info's integration check list still labeled the PCI spawner as
'pcid-spawner' and pointed at /usr/bin/pcid-spawner (deleted). Updated
to 'driver-manager' with /usr/bin/driver-manager and a note about
/scheme/driver-manager/bound. Plan v3.2 marks P2-1 done (pcid AER +
pciehp producers validated in QEMU).
The meson gate that enables EGL on Redox — adding "redox" to
system_has_kms_drm (meson.build:159, so with_dri→with_egl/gbm) and to the
_GNU_SOURCE platform list (:1208) — existed only as an in-place edit in the
untracked extracted source/ tree. Any clean re-extract lost it and reverted to
"Feature egl cannot be enabled". Capture it as local/patches/mesa/08-*.patch and
wire it into recipe.toml so EGL/GBM/llvmpipe build reproducibly. Source tree
reverted to pristine so the patch is the sole, tracked change.
- AER listener path moves from /scheme/acpi/aer (no producer) to
/scheme/pci/aer (pcid's new producer, submodule bump 5a43628d).
- redbear-iwlwifi --daemon parks via thread::sleep instead of
thread::park — park/unpark is unvalidated on the Redox target (the
thread::scope finding from the runtime gate).
Flip [source] from git=jackpot51/seatd to path="source" so the already-tracked
in-tree source/ (52 files, incl. libseat/seatd-launch) is the authoritative
implementation — a first-class local Red Bear package like evdevd and
redbear-compositor, per Local Fork Supremacy and the operator decision
(INPUT-STACK-LINUX-ALIGNMENT-PLAN.md §4b). We own it and integrate upstream
into our tree rather than fetch+patch.
Does not affect redbear-mini/bare (they do not pull seatd). Making it compile
for Redox + wiring the compositor seat path remain part of the Mesa-gated
desktop bring-up.
Point evdevd at /scheme/input/consumer_raw (the new raw device tap added in
base bd5e3db3) instead of /scheme/input/consumer. The console consumer handed
evdevd keymapped, VT-gated events — it only received input while its own VT
was active, and the character had already been keymapped, both wrong for a
libinput/xkbcommon (Wayland) feed. The raw tap delivers the pre-keymap event
stream for every device event regardless of the active VT, matching the Linux
evdev contract.
evdevd only ever used scancode+pressed (never character), so no translation
change is needed on its side.
Bumps the base submodule pointer to include the consumer_raw tap. Part of the
Linux-aligned input-stack consolidation
(local/docs/INPUT-STACK-LINUX-ALIGNMENT-PLAN.md). Compile-checked for
x86_64-unknown-redox.
Phase 6.2 foundation. Port the Mini-MLD layer from Linux 7.1
(drivers/net/wireless/intel/iwlwifi/mld/), the MLD analog of Mini-MVM:
- linux_mld.h: iwlmld op-mode IDs, notification command groups
(LEGACY/MAC_CONF/PHY_OPS/DATA_PATH/SCAN/STATISTICS), and the MLD
notification command ID set. The RX frame IDs (0xc0/0xc1/0xc5) and the
iwl_rx_mpdu_desc descriptor are shared with MVM and stay in Mini-MVM;
MLD adds ROC/session-protection/MU-group-mgmt/probe-response/
channel-switch/MFUART/DTS-measurement notification IDs.
- linux_mld.c: rb_iwl_mld_handle_notification() — real MLD notification
dispatch. RX MPDU frames are parsed by the Mini-MVM descriptor parser
(rb_iwl_mvm_extract_signal/detect_format, no duplicate parser) with real
signal/rate extraction; MLD-specific notifications are identified,
grouped, and counted. Includes the BZ-family op-mode selection
(rb_iwl_opmode_for_family, mirroring Linux iwl-drv.c).
- linux_port.c: include linux_mld.h; add trans->opmode set from
device_family (BZ -> iwlmld, others -> iwlmvm); report opmode= in the
linux_kpi_status line so the gate is observable.
- build.rs: compile linux_mld.c.
This is the bounded foundation; MLO/link management and the full MLD
feature set (mac80211-integrated) are the multi-week continuation.
All 8 host tests pass.
Redesign grounded in the Linux 7.1 quirk-consumption cross-reference
(9 families, one three-layer invariant: match -> store -> consume):
- New open domain channel: [[<domain>_quirk]] TOML tables matched by
(vendor, device) with wildcards, accumulated as string flags by
quirks::lookup_driver_quirks(domain, vid, did). The table name IS the
domain key — new driver domains need zero registry code (Linux Type-C
model: driver-owned fixup tables like HDA's per-codec lists).
- lookup_audio_quirks(vid, did) as the first domain convenience API for
ihdad's future integration.
- quirks.d/15-audio.toml converted from [[pci_quirk]] to [[audio_quirk]]
— the audio_* flags (force_eapd, single_cmd, position_fix_lpib,
mirroring Linux sound/pci/hda) are now carried as data instead of
warned-and-dropped on every probe cycle.
- Docs: three-layer model in QUIRKS-SYSTEM.md + consumption contract
(bind-time / core-runtime / driver-runtime); QUIRKS-IMPROVEMENT-PLAN.md
v2.0 with the redesign assessment and cutover-era reality (stale
pcid-spawner broker references removed).
- 75/75 redox-driver-sys tests pass (new domain loader test).