Advance redbear-full Wayland, greeter, and Qt integration
Consolidate the active desktop path around redbear-full while landing the greeter/session stack and the runtime fixes needed to keep Wayland and KWin bring-up moving forward.
This commit is contained in:
+10
-10
@@ -3,7 +3,7 @@
|
||||
## Overview
|
||||
|
||||
This document maps the distance between current Redox OS 0.9.0 and three goals:
|
||||
1. **Wayland compositor support** → see [03-WAYLAND-ON-REDOX.md](03-WAYLAND-ON-REDOX.md)
|
||||
1. **Wayland compositor support** → see `../local/docs/WAYLAND-IMPLEMENTATION-PLAN.md`
|
||||
2. **KDE Plasma desktop** → see [05-KDE-PLASMA-ON-REDOX.md](05-KDE-PLASMA-ON-REDOX.md)
|
||||
3. **Linux driver compatibility layer** → see [04-LINUX-DRIVER-COMPAT.md](04-LINUX-DRIVER-COMPAT.md)
|
||||
|
||||
@@ -21,8 +21,8 @@ Use the matrix below as the authoritative phase summary before reading the older
|
||||
|---|---|---|
|
||||
| P0 ACPI / bare-metal boot | **Materially complete for the historical boot baseline, not release-grade complete.** Implemented: kernel RSDP/RSDT/XSDT/MADT/FADT parsing, typed `StartupError` in `acpid`, AML mutex real state (`aml_physmem.rs`), EC widened accesses via byte transactions (`ec.rs`), kstop-based shutdown eventing (kernel registers `/scheme/kernel.acpi/kstop`, `acpid` subscribes, `redbear-sessiond` emits D-Bus `PrepareForShutdown`). Sleep state transitions (`\_Sx` beyond `\_S5`) and sleep eventing are **known gaps**. DMAR module remains present in `acpid` but not wired; ownership is still transitional/orphaned rather than cleanly transferred. Bare-metal validation remains bounded rather than broad. | `local/docs/ACPI-FIXES.md`, `local/docs/ACPI-IMPROVEMENT-PLAN.md`, `local/patches/kernel/redox.patch`, `local/patches/base/redox.patch`, `recipes/core/base/source/drivers/acpid/src/main.rs`, `recipes/core/base/source/drivers/acpid/src/aml_physmem.rs`, `recipes/core/base/source/drivers/acpid/src/ec.rs`, `local/recipes/system/redbear-sessiond/source/src/acpi_watcher.rs` |
|
||||
| P1 driver infrastructure | Complete in-tree, compile-oriented | `local/recipes/drivers/redox-driver-sys/`, `local/recipes/drivers/linux-kpi/`, `local/recipes/system/firmware-loader/` |
|
||||
| P2 DRM / AMD+Intel display | Complete in-tree, hardware validation pending | `local/docs/P2-AMD-GPU-DISPLAY.md`, `local/recipes/gpu/redox-drm/`, `local/recipes/gpu/amdgpu/` |
|
||||
| P3 POSIX + input | Implemented in-tree; consumer-visible `signalfd`/`timerfd`/`eventfd`/`open_memstream` header-export path fixed in this repo pass; runtime validation still pending | `recipes/core/relibc/source/src/header/`, `recipes/core/relibc/source/include/sys/signalfd.h`, `local/patches/relibc/`, `local/recipes/system/evdevd/`, `local/recipes/system/udev-shim/` |
|
||||
| P2 DRM / AMD+Intel display | Partial — redox-drm + bounded AMD display glue build in-tree; imported Linux AMD DC/TTM/core remain under compile triage; hardware validation pending | `local/docs/AMD-FIRST-INTEGRATION.md`, `local/docs/DRM-MODERNIZATION-EXECUTION-PLAN.md`, `local/recipes/gpu/redox-drm/`, `local/recipes/gpu/amdgpu/` |
|
||||
| P3 POSIX + input | Implemented in-tree; consumer-visible `signalfd`/`timerfd`/`eventfd`/`open_memstream` header-export path fixed in this repo pass; strict Redox-target relibc runtime proof now exists for the fd-event slice | `local/patches/relibc/`, `recipes/core/relibc/recipe.toml`, `recipes/tests/relibc-tests-bins/recipe.toml`, `local/recipes/system/evdevd/`, `local/recipes/system/udev-shim/` |
|
||||
| P4 Wayland stack | Partially complete | `recipes/wip/wayland/`, `recipes/wip/libs/other/libinput/`, `recipes/wip/services/seatd/` |
|
||||
| P5 AMD acceleration / IOMMU | Partial, but no longer blocked on basic QEMU first-use proof | `local/recipes/gpu/amdgpu/`, `local/recipes/system/iommu/` |
|
||||
| P6 KDE Plasma | In progress with mixed real builds and stubs/shims | `config/redbear-kde.toml`, `local/recipes/kde/`, `local/docs/QT6-PORT-STATUS.md` |
|
||||
@@ -67,9 +67,9 @@ implemented phase with its own config/recipe/doc boundary.
|
||||
|
||||
| API | Status | Where to implement | Effort |
|
||||
|-----|--------|--------------------|--------|
|
||||
| `signalfd`/`signalfd4` | **Implemented in-tree** | `relibc/src/header/signal/mod.rs` + `signal/signalfd.rs` | Runtime validation still needed |
|
||||
| `timerfd_create/settime/gettime` | **Implemented in-tree** | `relibc/src/header/sys_timerfd/` | Runtime validation still needed |
|
||||
| `eventfd`/`eventfd_read`/`eventfd_write` | **Implemented in-tree** | `relibc/src/header/sys_eventfd/` | Runtime validation still needed |
|
||||
| `signalfd`/`signalfd4` | **Implemented and runtime-tested in-tree** | `relibc/src/header/signal/mod.rs` + `signal/signalfd.rs` | Strict Redox-target relibc runtime test now passes; broader consumer semantics still need continued confirmation |
|
||||
| `timerfd_create/settime/gettime` | **Implemented and runtime-tested in-tree** | `relibc/src/header/sys_timerfd/` | Strict Redox-target relibc runtime test now passes; broader consumer semantics still need continued confirmation |
|
||||
| `eventfd`/`eventfd_read`/`eventfd_write` | **Implemented and runtime-tested in-tree** | `relibc/src/header/sys_eventfd/` | Strict Redox-target relibc runtime test now passes; broader consumer semantics still need continued confirmation |
|
||||
| `F_DUPFD_CLOEXEC` | **Implemented in-tree** | `relibc/src/header/fcntl/mod.rs` | Verify against downstream consumers |
|
||||
| `MSG_CMSG_CLOEXEC` | **Implemented in-tree** | `relibc/src/header/sys_socket/mod.rs` | Verify against downstream consumers |
|
||||
| `MSG_NOSIGNAL` | **Implemented in-tree** | `relibc/src/header/sys_socket/mod.rs` | Verify against downstream consumers |
|
||||
@@ -89,7 +89,7 @@ implemented phase with its own config/recipe/doc boundary.
|
||||
| GPU driver (Intel) | Experimental modeset only | `redox-drm/src/drivers/intel/` | [04 §3](04-LINUX-DRIVER-COMPAT.md) |
|
||||
| GEM buffers | **Present in-tree** | `local/recipes/gpu/redox-drm/source/src/gem.rs` | [04 §3](04-LINUX-DRIVER-COMPAT.md) |
|
||||
| DMA-BUF sharing | ✅ Implemented | PRIME export/import via opaque tokens in `scheme.rs` | [DMA-BUF plan](../local/docs/DMA-BUF-IMPROVEMENT-PLAN.md) |
|
||||
| Mesa hardware backend | **Missing** | Mesa winsys for Redox DRM | [03 §3.4](03-WAYLAND-ON-REDOX.md) |
|
||||
| Mesa hardware backend | **Missing** | Mesa winsys for Redox DRM | `../local/docs/WAYLAND-IMPLEMENTATION-PLAN.md` |
|
||||
| GPU OpenGL | Software only | Blocked on GPU driver | [04](04-LINUX-DRIVER-COMPAT.md) |
|
||||
|
||||
### Layer 3: Input Stack
|
||||
@@ -101,9 +101,9 @@ implemented phase with its own config/recipe/doc boundary.
|
||||
|
||||
| Component | Status | Where to implement | Concrete doc |
|
||||
|-----------|--------|--------------------|-------------|
|
||||
| evdev daemon | **Present in-tree** | `local/recipes/system/evdevd/` | [03 §2](03-WAYLAND-ON-REDOX.md) |
|
||||
| udev shim | **Present in-tree** | `local/recipes/system/udev-shim/` | [03 §2](03-WAYLAND-ON-REDOX.md) |
|
||||
| libinput | **Present as WIP port** | `recipes/wip/libs/other/libinput/` | [03 §2](03-WAYLAND-ON-REDOX.md) |
|
||||
| evdev daemon | **Present in-tree** | `local/recipes/system/evdevd/` | `../local/docs/WAYLAND-IMPLEMENTATION-PLAN.md` |
|
||||
| udev shim | **Present in-tree** | `local/recipes/system/udev-shim/` | `../local/docs/WAYLAND-IMPLEMENTATION-PLAN.md` |
|
||||
| libinput | **Present as WIP port** | `recipes/wip/libs/other/libinput/` | `../local/docs/WAYLAND-IMPLEMENTATION-PLAN.md` |
|
||||
| XKB layouts | **Done** | `xkeyboard-config` ported | — |
|
||||
| seatd | Builds and is wired into KDE config, runtime unvalidated | `recipes/wip/services/seatd/`, `config/redbear-kde.toml` | — |
|
||||
|
||||
|
||||
@@ -1,581 +0,0 @@
|
||||
# 03 — Wayland on Redox: Concrete Implementation Path
|
||||
|
||||
## Goal
|
||||
|
||||
Get a working Wayland compositor on Redox OS that can run KDE Plasma applications.
|
||||
|
||||
For the current build/runtime truth summary of the desktop stack, use
|
||||
`local/docs/DESKTOP-STACK-CURRENT-STATUS.md` together with `local/docs/QT6-PORT-STATUS.md`.
|
||||
This file should now be read primarily as implementation history plus deeper Wayland-specific
|
||||
porting notes.
|
||||
|
||||
## Current State
|
||||
|
||||
- `config/wayland.toml` exists — it remains the bounded validation path, not the production desktop path
|
||||
- 21 Wayland recipes in `recipes/wip/wayland/` — most untested
|
||||
- `libwayland` 1.24.0 now rebuilds with a much smaller `redox.patch`; the P3 POSIX path (`signalfd`, `timerfd`, `eventfd`, `open_memstream`, `MSG_CMSG_CLOEXEC`, `MSG_NOSIGNAL`) is back on the native path, and the remaining patch is down to Redox-specific build quirks
|
||||
- the bounded validation compositor path remains separate from the production desktop goal
|
||||
- the remaining compositor/runtime issue is still input integration, not simply the absence of a libinput recipe
|
||||
- `libdrm` builds with amdgpu and Intel enabled
|
||||
- Mesa builds with EGL+GBM+GLES2 (software via LLVMpipe; hardware acceleration still requires kernel DMA-BUF)
|
||||
- **evdevd** (`scheme:evdev`) provides Linux-compatible `/dev/input/eventX` interface
|
||||
- **udev-shim** (`scheme:udev`) provides udev-like device enumeration
|
||||
- **seatd** now builds for Redox and is wired into the KDE runtime config, but DRM-lease/runtime validation is still open
|
||||
- **redox-drm** (`scheme:drm`) provides DRM/KMS with AMD + Intel GPU support
|
||||
|
||||
---
|
||||
|
||||
## Status Correction (2026-04-14)
|
||||
|
||||
This document is partly historical. The repo already contains substantial P3/P4 work in-tree,
|
||||
but the downstream Wayland stack is still not free of compatibility patches.
|
||||
|
||||
What is actually true today:
|
||||
- relibc now contains in-tree implementations for `signalfd`, `timerfd`, `eventfd`, `open_memstream`, `MSG_CMSG_CLOEXEC`, and `MSG_NOSIGNAL` support paths
|
||||
- the relibc module wiring plus the consumer-visible `signalfd` / `timerfd` / `eventfd` / `open_memstream` export path were fixed in this repo pass
|
||||
- `libwayland/redox.patch` has been reduced to residual Redox-specific build tweaks (`wayland-scanner` detection and `F_DUPFD_CLOEXEC` guard), so the old POSIX bypasses are no longer the main blocker
|
||||
- `evdevd`, `udev-shim`, and `redox-drm` exist in-tree, but full compositor/runtime validation remains open
|
||||
- `seatd` now also builds in-tree for Redox and is started by the KDE runtime config, but has not yet been validated end-to-end with the compositor/DRM path
|
||||
|
||||
Read the step-by-step sections below as design history plus implementation notes, not as an exact
|
||||
current-state checklist.
|
||||
|
||||
For the current Wayland runtime entrypoint in this repo, use:
|
||||
|
||||
- `config/redbear-wayland.toml`
|
||||
- `local/scripts/test-phase4-wayland-qemu.sh`
|
||||
|
||||
> **Numbering note:** the "Phase 4" in the script name above refers to the historical P0-P6
|
||||
> hardware-enablement sequence (see `AGENTS.md`). In the v2.0 desktop plan
|
||||
> (`local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md`), Wayland compositor work falls under Phase 2.
|
||||
> The scripts still work under their original names.
|
||||
|
||||
That path is the current bounded validation target. The production desktop path is
|
||||
`config/redbear-kde.toml` with `kwin_wayland`.
|
||||
|
||||
Current runtime evidence for that target:
|
||||
|
||||
- `redbear-wayland` builds to a bootable image
|
||||
- the image boots to a real login prompt in QEMU/UEFI
|
||||
- `redbear-phase4-wayland-check` runs in-guest and confirms the Wayland launch surface is present
|
||||
- the compositor reaches xkbcommon initialization and selects the Redox EGL platform in the live guest
|
||||
- the direct launcher `local/scripts/test-phase4-wayland-qemu.sh` now boots the built
|
||||
`redbear-wayland` disk image instead of re-entering the build pipeline
|
||||
|
||||
For the runtime-validation pass, keep the **validation target** intentionally small as a bounded
|
||||
compositor harness and not as the production desktop goal. The current `redbear-wayland`
|
||||
profile still inherits the broader desktop package set from `desktop.toml`, but this repo's
|
||||
Wayland validation remains a bounded regression harness subordinate to the `redbear-kde` /
|
||||
`kwin_wayland` production path, not a peer desktop direction.
|
||||
|
||||
---
|
||||
|
||||
## Historical Step 1: Fix relibc POSIX Gaps (1-2 weeks)
|
||||
|
||||
### Historical implementation sketch
|
||||
|
||||
Historically these were the 7 APIs that `libwayland/redox.patch` worked around. They now exist
|
||||
in-tree in relibc, and this repo pass restored the full build-side path for `signalfd`, `timerfd`,
|
||||
`eventfd`, `open_memstream`, and the related message flags. The remaining work is no longer basic
|
||||
POSIX availability, but runtime validation of the full Wayland stack.
|
||||
|
||||
#### 1.1 `signalfd` / `signalfd4`
|
||||
|
||||
**Files to create/modify in relibc:**
|
||||
```
|
||||
src/header/signal/mod.rs — add signalfd(), signalfd4()
|
||||
src/header/signal/src.rs — add SFD_CLOEXEC, SFD_NONBLOCK constants
|
||||
src/header/signal/types.rs — add signalfd_siginfo struct
|
||||
src/platform/redox/mod.rs — wire to kernel event scheme or userspace signal handler
|
||||
```
|
||||
|
||||
**Implementation approach:**
|
||||
```rust
|
||||
// src/header/signal/mod.rs
|
||||
pub fn signalfd(fd: c_int, mask: *const sigset_t, flags: c_int) -> c_int {
|
||||
// If fd == -1, create a new "signal FD" using event scheme
|
||||
// Register signal mask with the signal handling infrastructure
|
||||
// Return FD that becomes readable when signals arrive
|
||||
// Map to Redox: use event: scheme + signal userspace handler
|
||||
}
|
||||
```
|
||||
|
||||
**Approximate effort**: ~200 lines of Rust.
|
||||
|
||||
#### 1.2 `timerfd`
|
||||
|
||||
**Files to create in relibc:**
|
||||
```
|
||||
src/header/sys_timerfd/mod.rs — NEW: timerfd_create(), timerfd_settime(), timerfd_gettime()
|
||||
src/header/sys_timerfd/types.rs — NEW: itimerspec, TFD_CLOEXEC, TFD_NONBLOCK, TFD_TIMER_ABSTIME
|
||||
src/platform/redox/mod.rs — wire to time: scheme
|
||||
```
|
||||
|
||||
**Implementation approach:**
|
||||
```rust
|
||||
// src/header/sys_timerfd/mod.rs
|
||||
pub fn timerfd_create(clockid: c_int, flags: c_int) -> c_int {
|
||||
// Create a timer FD using Redox time: scheme
|
||||
// Return FD that becomes readable when timer fires
|
||||
// Read returns uint64_t count of expirations
|
||||
}
|
||||
|
||||
pub fn timerfd_settime(fd: c_int, flags: c_int, new: *const itimerspec, old: *mut itimerspec) -> c_int {
|
||||
// Arm/disarm timer
|
||||
// Use time: scheme for absolute/relative timers
|
||||
}
|
||||
```
|
||||
|
||||
**Approximate effort**: ~300 lines of Rust.
|
||||
|
||||
#### 1.3 `eventfd`
|
||||
|
||||
**Files to create in relibc:**
|
||||
```
|
||||
src/header/sys_eventfd/mod.rs — NEW: eventfd(), eventfd_read(), eventfd_write()
|
||||
src/header/sys_eventfd/types.rs — EFD_CLOEXEC, EFD_NONBLOCK, EFD_SEMAPHORE
|
||||
```
|
||||
|
||||
**Implementation approach:**
|
||||
```rust
|
||||
// Simplest of the three — just an atomic counter accessed via read/write
|
||||
pub fn eventfd(initval: c_uint, flags: c_int) -> c_int {
|
||||
// Create a pipe-like FD backed by a shared atomic counter
|
||||
// read() blocks until counter > 0, returns counter, resets to 0
|
||||
// write() adds to counter
|
||||
// Use Redox pipe: scheme internally
|
||||
}
|
||||
```
|
||||
|
||||
**Approximate effort**: ~100 lines of Rust.
|
||||
|
||||
#### 1.4 `F_DUPFD_CLOEXEC`
|
||||
|
||||
**File to modify in relibc:**
|
||||
```
|
||||
src/header/fcntl/mod.rs — add F_DUPFD_CLOEXEC constant (value 0x40 on Linux x86_64)
|
||||
src/platform/redox/alloc.rs — handle F_DUPFD_CLOEXEC in fcntl()
|
||||
```
|
||||
|
||||
```rust
|
||||
// In fcntl handler:
|
||||
pub const F_DUPFD_CLOEXEC: c_int = 0x406; // Linux value
|
||||
|
||||
// In fcntl() match:
|
||||
F_DUPFD_CLOEXEC => {
|
||||
let new_fd = syscall::dup(fd, None)?;
|
||||
// Set CLOEXEC flag on new_fd
|
||||
// Return new_fd
|
||||
}
|
||||
```
|
||||
|
||||
**Approximate effort**: ~20 lines.
|
||||
|
||||
#### 1.5 `MSG_CMSG_CLOEXEC` and `MSG_NOSIGNAL`
|
||||
|
||||
**Files to modify in relibc:**
|
||||
```
|
||||
src/header/sys_socket/mod.rs — add MSG_CMSG_CLOEXEC (0x40000000), MSG_NOSIGNAL (0x4000)
|
||||
src/platform/redox/mod.rs — handle in recvmsg/sendmsg
|
||||
```
|
||||
|
||||
`MSG_NOSIGNAL`: suppress SIGPIPE on broken connection. On Redox, SIGPIPE handling
|
||||
is already userspace — just don't send the signal when this flag is set.
|
||||
|
||||
`MSG_CMSG_CLOEXEC`: set CLOEXEC on FDs received via SCM_RIGHTS. Apply the flag
|
||||
when processing ancillary data in recvmsg.
|
||||
|
||||
**Approximate effort**: ~50 lines.
|
||||
|
||||
#### 1.6 `open_memstream`
|
||||
|
||||
**File to modify in relibc:**
|
||||
```
|
||||
src/header/stdio/mod.rs — add open_memstream()
|
||||
src/header/stdio/src.rs — implementation
|
||||
```
|
||||
|
||||
```rust
|
||||
pub fn open_memstream(bufp: *mut *mut c_char, sizep: *mut usize) -> *mut FILE {
|
||||
// Create a write-only stream that dynamically grows a buffer
|
||||
// On close or flush, update *bufp and *sizep
|
||||
// Can be implemented using a backing Vec<u8> and custom FILE vtable
|
||||
}
|
||||
```
|
||||
|
||||
**Approximate effort**: ~200 lines.
|
||||
|
||||
### Verification
|
||||
|
||||
After implementing all 7 APIs:
|
||||
1. Rebuild relibc: `./target/release/repo cook recipes/core/relibc`
|
||||
2. Rebuild libwayland **without** `redox.patch` — it should compile natively
|
||||
3. Test: `wayland-rs_simple_window` runs without crashes
|
||||
|
||||
---
|
||||
|
||||
## Historical Step 2: evdev Input Daemon (4-6 weeks)
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
┌──────────────────┐ ┌──────────────────────┐ ┌──────────────┐
|
||||
│ libinput │────→│ /dev/input/eventX │────→│ evdevd │
|
||||
│ (ported) │ │ (character devices) │ │ (daemon) │
|
||||
└──────────────────┘ └──────────────────────┘ └──────┬───────┘
|
||||
│
|
||||
reads Redox schemes:
|
||||
input:, scheme:irq
|
||||
```
|
||||
|
||||
### What to build
|
||||
|
||||
**New daemon: `evdevd`** (userspace, like all Redox drivers)
|
||||
|
||||
Create as a new recipe: `recipes/core/evdevd/`
|
||||
|
||||
**Source structure:**
|
||||
```
|
||||
evdevd/
|
||||
├── Cargo.toml
|
||||
├── src/
|
||||
│ ├── main.rs — daemon entry, scheme registration
|
||||
│ ├── scheme.rs — implements "evdev" scheme
|
||||
│ ├── device.rs — translates Redox events to input_event
|
||||
│ └── ioctl.rs — handles EVIOCG* ioctls
|
||||
```
|
||||
|
||||
**Key implementation:**
|
||||
|
||||
```rust
|
||||
// src/main.rs
|
||||
fn main() {
|
||||
// 1. Open existing Redox input sources
|
||||
let keyboard = File::open("scheme:input/keyboard")?;
|
||||
let mouse = File::open("scheme:input/mouse")?;
|
||||
|
||||
// 2. Create /dev/input symlinks (pointing to our scheme)
|
||||
// /dev/input/event0 → /scheme/evdev/keyboard
|
||||
// /dev/input/event1 → /scheme/evdev/mouse
|
||||
|
||||
// 3. Register evdev scheme
|
||||
let scheme = File::create(":evdev")?;
|
||||
|
||||
// 4. Event loop: read from Redox input schemes, translate, write to evdev clients
|
||||
loop {
|
||||
let redox_event = read_redox_event(&keyboard)?;
|
||||
let evdev_event = translate_to_input_event(redox_event);
|
||||
// Deliver to subscribed clients
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```rust
|
||||
// src/ioctl.rs — implement evdev ioctls
|
||||
fn handle_ioctl(fd: usize, request: usize, arg: usize) -> Result<usize> {
|
||||
match request {
|
||||
EVIOCGNAME => { /* write device name string to arg */ },
|
||||
EVIOCGBIT => { /* write supported event types bitmap to arg */ },
|
||||
EVIOCGABS => { /* write absinfo struct for absolute axes */ },
|
||||
EVIOCGRAB => { /* grab/exclusive access to device */ },
|
||||
EVIOCGPROP => { /* write device properties bitmap */ },
|
||||
_ => Err(syscall::Error::new(syscall::EINVAL)),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Also needed: udev shim**
|
||||
|
||||
> **Historical path note:** the `recipes/wip/...` paths in the example steps below document the
|
||||
> original upstream-oriented implementation path. Under the current Red Bear policy, upstream WIP is
|
||||
> an input/reference, but the shipping/fixed version may live under `local/recipes/` instead.
|
||||
|
||||
Create `recipes/wip/wayland/udev-shim/` — a minimal udev implementation that:
|
||||
- Enumerates `/dev/input/event*` devices
|
||||
- Emits "add"/"remove" events via netlink-compatible socket
|
||||
- Provides `udev_device_get_property_value()` for `ID_INPUT_*` properties
|
||||
|
||||
libinput needs this for hotplug. A minimal shim is ~500 lines of Rust.
|
||||
|
||||
**Then port libinput:**
|
||||
|
||||
Modify `recipes/wip/wayland/libinput/` (currently missing — create it):
|
||||
```toml
|
||||
[source]
|
||||
tar = "https://gitlab.freedesktop.org/wayland/libinput/-/archive/1.27.0/libinput-1.27.0.tar.gz"
|
||||
patches = ["redox.patch"]
|
||||
|
||||
[build]
|
||||
template = "meson"
|
||||
dependencies = [
|
||||
"evdevd",
|
||||
"libffi",
|
||||
"libwayland",
|
||||
"udev-shim",
|
||||
"mtdev", # touchpad multi-touch
|
||||
"libevdev", # evdev wrapper library
|
||||
]
|
||||
mesonflags = [
|
||||
"-Ddocumentation=false",
|
||||
"-Dtests=false",
|
||||
"-Ddebug-gui=false",
|
||||
]
|
||||
```
|
||||
|
||||
### Verification
|
||||
|
||||
1. Build and run `evdevd`
|
||||
2. `cat /dev/input/event0` shows keyboard events
|
||||
3. Build libinput against evdevd
|
||||
4. `libinput list-devices` shows keyboard and mouse
|
||||
|
||||
---
|
||||
|
||||
## Historical Step 3: DRM/KMS Scheme (8-12 weeks)
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
┌──────────────┐ ┌───────────────────┐ ┌────────────────┐
|
||||
│ libdrm │───→│ scheme:drm/card0 │───→│ drmd (daemon) │
|
||||
│ (ported) │ │ DRM ioctls via │ │ GPU driver │
|
||||
│ │ │ scheme protocol │ │ userspace │
|
||||
└──────────────┘ └───────────────────┘ └───────┬────────┘
|
||||
│
|
||||
scheme:memory + scheme:irq
|
||||
│
|
||||
Hardware (GPU)
|
||||
```
|
||||
|
||||
### What to build
|
||||
|
||||
**New daemon: `drmd`** (DRM daemon — starts with Intel support)
|
||||
|
||||
Create as: `recipes/core/drmd/`
|
||||
|
||||
**Source structure:**
|
||||
```
|
||||
drmd/
|
||||
├── Cargo.toml
|
||||
├── src/
|
||||
│ ├── main.rs — daemon entry, PCI enumeration
|
||||
│ ├── scheme.rs — registers "drm" scheme
|
||||
│ ├── kms/
|
||||
│ │ ├── mod.rs — KMS object management
|
||||
│ │ ├── crtc.rs — CRTC implementation
|
||||
│ │ ├── connector.rs — connector (HDMI, DP, eDP)
|
||||
│ │ ├── encoder.rs — encoder
|
||||
│ │ ├── plane.rs — primary + cursor planes
|
||||
│ │ └── framebuffer.rs — framebuffer allocation
|
||||
│ ├── gem/
|
||||
│ │ └── mod.rs — GEM buffer management
|
||||
│ └── drivers/
|
||||
│ ├── mod.rs — driver trait
|
||||
│ └── intel.rs — Intel GPU driver (modesetting)
|
||||
```
|
||||
|
||||
**Core DRM scheme protocol:**
|
||||
|
||||
```rust
|
||||
// src/scheme.rs
|
||||
// DRM scheme implements the same ioctls as Linux /dev/dri/card0
|
||||
// but via Redox scheme read/write/packet protocol
|
||||
|
||||
enum DrmRequest {
|
||||
// Core
|
||||
GetVersion,
|
||||
GetCap { capability: u64 },
|
||||
|
||||
// KMS
|
||||
ModeGetResources,
|
||||
ModeGetConnector { connector_id: u32 },
|
||||
ModeGetEncoder { encoder_id: u32 },
|
||||
ModeGetCrtc { crtc_id: u32 },
|
||||
ModeSetCrtc { crtc_id: u32, fb_id: u32, x: u32, y: u32, connectors: Vec<u32>, mode: ModeModeInfo },
|
||||
ModePageFlip { crtc_id: u32, fb_id: u32, flags: u32, user_data: u64 },
|
||||
ModeAtomicCommit { flags: u32, props: Vec<AtomicProp> },
|
||||
|
||||
// GEM
|
||||
GemCreate { size: u64 },
|
||||
GemClose { handle: u32 },
|
||||
GemMmap { handle: u32 },
|
||||
|
||||
// Prime/DMA-BUF
|
||||
PrimeHandleToFd { handle: u32, flags: u32 },
|
||||
PrimeFdToHandle { fd: i32 },
|
||||
}
|
||||
```
|
||||
|
||||
**Intel driver (starting point):**
|
||||
|
||||
```rust
|
||||
// src/drivers/intel.rs
|
||||
// Based on public Intel GPU documentation:
|
||||
// https://01.org/linuxgraphics/documentation/hardware-specification-prm
|
||||
|
||||
pub struct IntelDriver {
|
||||
mmio: *mut u8, // Memory-mapped I/O registers (via scheme:memory)
|
||||
gtt_size: usize, // Graphics Translation Table size
|
||||
framebuffer: PhysAddr, // Current scanout buffer
|
||||
}
|
||||
|
||||
impl IntelDriver {
|
||||
pub fn new(pci_dev: &PciDev) -> Result<Self> {
|
||||
// Map MMIO registers via scheme:memory/physical
|
||||
let mmio = map_physical_memory(pci_dev.bar[0], pci_dev.bar_size[0])?;
|
||||
|
||||
// Initialize GTT (Graphics Translation Table)
|
||||
// Set up display pipeline
|
||||
|
||||
Ok(Self { mmio, gtt_size, framebuffer })
|
||||
}
|
||||
|
||||
pub fn modeset(&self, mode: &ModeInfo) -> Result<()> {
|
||||
// 1. Allocate framebuffer in GTT
|
||||
// 2. Configure pipe (timing, PLL)
|
||||
// 3. Configure transcoder
|
||||
// 4. Configure port (HDMI/DP)
|
||||
// 5. Enable scanout from new framebuffer
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn page_flip(&self, crtc: u32, fb: PhysAddr) -> Result<()> {
|
||||
// 1. Update GTT entry to point to new framebuffer
|
||||
// 2. Trigger page flip on next VBlank
|
||||
// 3. VBlank interrupt signals completion (via scheme:irq)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Verification
|
||||
|
||||
1. `drmd` registers `scheme:drm/card0`
|
||||
2. Port `modetest` (from libdrm tests) — shows connector info and modes
|
||||
3. `modetest -M intel -s 0:1920x1080` sets a mode and shows test pattern
|
||||
|
||||
---
|
||||
|
||||
## Historical Step 4: Working Wayland Compositor (4-6 weeks after Steps 1-3)
|
||||
|
||||
### Historical staging note: bounded compositor validation before KWin
|
||||
|
||||
This section is historical context only. It explains why a smaller compositor was used earlier as a bounded
|
||||
validation compositor before the KWin-first production path became the repo's architecture.
|
||||
|
||||
**Why a smaller compositor was used first as a validation compositor:**
|
||||
- Pure Rust — no C++ toolchain issues
|
||||
- Already has a Redox branch (`https://github.com/jackpot51/smithay`, branch `redox`)
|
||||
- Smithay's input backend is pluggable — write a Redox-specific one
|
||||
- Provided an earlier bounded compositor proof before the KWin session path was viable
|
||||
|
||||
**What to modify in Smithay:**
|
||||
|
||||
```
|
||||
smithay/
|
||||
├── src/backend/
|
||||
│ ├── input/
|
||||
│ │ └── redox.rs — NEW: Redox input backend (reads evdev scheme)
|
||||
│ ├── drm/
|
||||
│ │ └── redox.rs — NEW: Redox DRM backend (uses scheme:drm)
|
||||
│ └── egl/
|
||||
│ └── redox.rs — NEW: Redox EGL display (uses Mesa)
|
||||
```
|
||||
|
||||
**Redox input backend:**
|
||||
```rust
|
||||
// src/backend/input/redox.rs
|
||||
pub struct RedoxInputBackend {
|
||||
devices: Vec<EvdevDevice>, // opened from /dev/input/eventX
|
||||
}
|
||||
|
||||
impl InputBackend for RedoxInputBackend {
|
||||
fn dispatch(&mut self) -> Vec<InputEvent> {
|
||||
// Read from all evdev devices via evdevd
|
||||
// Translate to Smithay's InternalEvent type
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Redox DRM backend:**
|
||||
```rust
|
||||
// src/backend/drm/redox.rs
|
||||
pub struct RedoxDrmBackend {
|
||||
drm_fd: File, // opened from /scheme/drm/card0
|
||||
}
|
||||
|
||||
impl DrmBackend for RedoxDrmBackend {
|
||||
fn create_surface(&self, size: Size) -> Surface {
|
||||
// Create framebuffer via DRM GEM
|
||||
// Set KMS mode via scheme:drm
|
||||
}
|
||||
|
||||
fn page_flip(&self, surface: &Surface) -> Result<VBlank> {
|
||||
// DRM page flip via scheme
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Recipe to add/modify
|
||||
|
||||
```toml
|
||||
# recipes/wip/wayland/<validation-compositor>/recipe.toml (modify existing)
|
||||
[source]
|
||||
git = "https://github.com/jackpot51/smithay"
|
||||
branch = "redox"
|
||||
|
||||
[build]
|
||||
template = "cargo"
|
||||
dependencies = [
|
||||
"libffi",
|
||||
"libwayland",
|
||||
"libxkbcommon",
|
||||
"mesa", # for EGL
|
||||
"libdrm", # for DRM backend
|
||||
"evdevd", # for input
|
||||
"seatd", # for session management
|
||||
]
|
||||
cargopackages = ["<validation-compositor>"]
|
||||
```
|
||||
|
||||
### Verification
|
||||
|
||||
1. the validation compositor launches with DRM backend — takes over display
|
||||
2. Keyboard and mouse work via evdevd
|
||||
3. `libcosmic-wayland_application` renders a window on the compositor
|
||||
4. Screenshot shows the window
|
||||
|
||||
---
|
||||
|
||||
## Historical Step 5: Additional compositor experiments
|
||||
|
||||
Once Steps 1-4 are done:
|
||||
|
||||
1. Re-enable additional historical compositor experiments only if they serve bounded validation needs
|
||||
2. Keep DRM + libinput + GBM experimentation explicitly subordinate to the canonical KWin path
|
||||
3. Treat any extra compositor work as historical/reference exploration rather than a forward desktop path
|
||||
4. For the canonical desktop path, see `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md`; for historical rationale, see `05-KDE-PLASMA-ON-REDOX.md`
|
||||
|
||||
---
|
||||
|
||||
## Fastest Path Summary
|
||||
|
||||
```
|
||||
Week 1-2: Implement signalfd/timerfd/eventfd/etc in relibc
|
||||
→ libwayland builds without patches
|
||||
|
||||
Week 3-8: Build evdevd (input daemon) + udev shim
|
||||
→ libinput works
|
||||
|
||||
Week 9-20: Build drmd (DRM daemon) with Intel modesetting
|
||||
→ libdrm works, modesetting functional
|
||||
|
||||
Week 21-26: Smithay Redox backends (input + DRM + EGL)
|
||||
→ Working Wayland compositor with hardware display
|
||||
|
||||
Week 27+: Port Qt, KDE Frameworks, Plasma Shell
|
||||
→ KDE Plasma desktop (see doc 05)
|
||||
```
|
||||
|
||||
**Key insight**: Steps 2 (evdev) and 3 (DRM) can run in parallel.
|
||||
With 2 developers, the Wayland compositor is achievable in ~6 months.
|
||||
+2
-5
@@ -25,7 +25,6 @@ For current Red Bear OS status, also read:
|
||||
docs/
|
||||
├── 01-REDOX-ARCHITECTURE.md # Architecture reference: microkernel, scheme system, driver model, display architecture
|
||||
├── 02-GAP-ANALYSIS.md # Historical gap matrix with corrected current-state notes
|
||||
├── 03-WAYLAND-ON-REDOX.md # Historical Wayland implementation path + deeper rationale
|
||||
├── 04-LINUX-DRIVER-COMPAT.md # Driver-compat architecture reference + historical porting path
|
||||
├── 05-KDE-PLASMA-ON-REDOX.md # Historical KDE implementation path + deeper rationale
|
||||
├── 06-BUILD-SYSTEM-SETUP.md # Build/setup mechanics guide (not canonical policy)
|
||||
@@ -46,11 +45,9 @@ docs/
|
||||
| What is the current Wi-Fi architecture and validation path? | local/docs/WIFI-IMPLEMENTATION-PLAN.md / local/docs/WIFI-VALIDATION-RUNBOOK.md | Entire document |
|
||||
| What is the current desktop-stack truth? | local/docs/DESKTOP-STACK-CURRENT-STATUS.md | Entire document |
|
||||
| What is the current Qt/KF6 status? | local/docs/QT6-PORT-STATUS.md | Entire document |
|
||||
| What's missing for Wayland? | 02 | Status correction + ordered remaining gaps |
|
||||
| What's missing for Wayland? | local/docs/WAYLAND-IMPLEMENTATION-PLAN.md | Entire document |
|
||||
| How to fix POSIX gaps? | local/docs/RELIBC-COMPLETENESS-AND-ENHANCEMENT-PLAN.md | Current relibc completeness work |
|
||||
| How to build evdevd? | 03 | §2 (evdev input daemon architecture) |
|
||||
| How to build DRM/KMS? | 03 | §3 (drmd daemon, Intel driver) |
|
||||
| How to port a Wayland compositor? | 03 | §4 (Smithay Redox backends) |
|
||||
| What is the current Wayland plan? | local/docs/WAYLAND-IMPLEMENTATION-PLAN.md | Entire document |
|
||||
| How to run Linux GPU drivers? | 04 | Architecture diagram, i915 porting example |
|
||||
| What is redox-driver-sys? | 04 | Crate 1: memory, IRQ, PCI, DMA wrappers |
|
||||
| What is linux-kpi? | 04 | Crate 2: C headers translating Linux→Redox APIs |
|
||||
|
||||
Reference in New Issue
Block a user