Red Bear OS — microkernel OS in Rust, based on Redox
Derivative of Redox OS (https://www.redox-os.org) adding: - AMD GPU driver (amdgpu) via LinuxKPI compat layer - ext4 filesystem support (ext4d scheme daemon) - ACPI fixes for AMD bare metal (x2APIC, DMAR, IVRS, MCFG) - Custom branding (hostname, os-release, boot identity) Build system is full upstream Redox with RBOS overlay in local/. Patches for kernel, base, and relibc are symlinked from local/patches/ and protected from make clean/distclean. Custom recipes live in local/recipes/ with symlinks into the recipes/ search path. Build: make all CONFIG_NAME=redbear-full Sync: ./local/scripts/sync-upstream.sh
This commit is contained in:
@@ -0,0 +1,264 @@
|
||||
# 01 — Redox OS Architecture Overview
|
||||
|
||||
## 1. Microkernel Design
|
||||
|
||||
Redox is a **pure microkernel** written in Rust (~20-40k LoC). Only essential services
|
||||
live in kernel space:
|
||||
|
||||
- Process and thread management
|
||||
- Memory management (address spaces, page tables, grants)
|
||||
- IPC via schemes (packet-based, io_uring-like SQE/CQE format)
|
||||
- Context switching and scheduling
|
||||
- Minimal kernel schemes: `debug`, `event`, `memory`, `pipe`, `irq`, `time`, `sys`, `proc`, `serio`
|
||||
|
||||
Everything else — drivers, filesystems, display server, networking — runs in **userspace**
|
||||
as separate processes with isolated address spaces. Crashes are contained; no kernel panics
|
||||
from driver bugs.
|
||||
|
||||
### Syscall Interface
|
||||
|
||||
The syscall ABI is **intentionally unstable**. Stability is provided by `libredox` and `relibc`.
|
||||
On x86_64, syscalls use `int 0x80` with registers:
|
||||
|
||||
```
|
||||
eax = syscall number
|
||||
ebx, ecx, edx, esi, edi = arguments
|
||||
eax = return value
|
||||
```
|
||||
|
||||
Key syscalls: `open`, `close`, `read`, `write`, `seek`, `fmap`, `funmap`, `dup`, `fork`, `execve`,
|
||||
`clone`, `mmap`, `munmap`, `mprotect`, `setrens`, `yield`.
|
||||
|
||||
### Userspace-ification Trend
|
||||
|
||||
Redox is actively moving POSIX functionality out of the kernel:
|
||||
- **fork/exec** → userspace via `thisproc:` scheme
|
||||
- **Signal handling** → userspace with kernel-shared page for low-cost `sigprocmask`
|
||||
- **Process manager** → planned userspace daemon
|
||||
|
||||
This reduces TCB and allows faster iteration without kernel changes.
|
||||
|
||||
## 2. The Scheme System — Everything is a URL
|
||||
|
||||
Inspired by Plan 9. Every resource is accessed through a **scheme** — a named service
|
||||
providing file-like operations (`open`, `read`, `write`, `fmap`).
|
||||
|
||||
### How Schemes Work
|
||||
|
||||
```
|
||||
User program: open("/scheme/orbital:myapp/800/600/Title")
|
||||
↓
|
||||
Kernel: Routes to "orbital" scheme daemon
|
||||
↓
|
||||
Orbital: Creates window, returns file handle
|
||||
↓
|
||||
User program: write(fd, pixel_data) // renders to window
|
||||
```
|
||||
|
||||
### Kernel Schemes
|
||||
|
||||
| Scheme | Purpose |
|
||||
|--------|---------|
|
||||
| `debug` | Debug output |
|
||||
| `event` | epoll-like event notification |
|
||||
| `irq` | Interrupt → message conversion |
|
||||
| `pipe` | Pipe implementation |
|
||||
| `memory` | Physical memory mapping |
|
||||
| `time` / `itimer` | Timers |
|
||||
| `proc` / `thisproc` | Process context |
|
||||
| `sys` | System information |
|
||||
| `serio` | PS/2 driver (kernel-space due to protocol constraints) |
|
||||
|
||||
### Userspace Schemes (Daemons)
|
||||
|
||||
| Category | Schemes | Daemon |
|
||||
|----------|---------|--------|
|
||||
| Storage | `disk.*` | ided, ahcid, nvmed |
|
||||
| Filesystem | `file` | redoxfs |
|
||||
| Network | `ip`, `tcp`, `udp`, `icmp` | smolnetd |
|
||||
| Display | `display.vesa`, `display.virtio-gpu`, `orbital` | vesad, virtio-gpud, orbital |
|
||||
| IPC | `chan`, `shm`, `uds_stream`, `uds_dgram` | ipcd |
|
||||
| Audio | `audio` | audiorw |
|
||||
| Input | `input` | inputd |
|
||||
| USB | `usb.*` | usbhidd |
|
||||
| Misc | `rand`, `null`, `zero`, `log`, `pty`, `sudo` | various |
|
||||
|
||||
### Scheme Registration
|
||||
|
||||
A daemon registers a scheme by:
|
||||
1. `File::create(":myscheme")` — creates root scheme
|
||||
2. Opens needed resources (`/scheme/irq/{irq}`, `/scheme/event`)
|
||||
3. `setrens(0, 0)` — moves to null namespace (security sandbox)
|
||||
4. Registers FDs with event scheme for async I/O
|
||||
5. Loops: block on event → handle request → respond
|
||||
|
||||
### Namespace Isolation
|
||||
|
||||
- **Root namespace**: all processes start here
|
||||
- **Null namespace**: process can only use existing FDs, cannot open new resources
|
||||
- Namespaces inherited by children
|
||||
- Enables sandboxing and privilege separation
|
||||
|
||||
## 3. Driver Model
|
||||
|
||||
All drivers are **userspace daemons** that access hardware through:
|
||||
|
||||
- **`iopl` syscall** — sets I/O privilege level for port I/O
|
||||
- **`/scheme/memory/physical`** — maps physical memory (writeback, uncacheable, write-combining)
|
||||
- **`/scheme/irq`** — converts hardware interrupts to messages
|
||||
|
||||
### Current Drivers
|
||||
|
||||
**Storage**: ided (IDE), ahcid (SATA), nvmed (NVMe), usbscsid (USB SCSI)
|
||||
|
||||
**Network**: e1000d (Intel GigE), rtl8168d (Realtek), ixgbed (Intel 10G)
|
||||
|
||||
**Audio**: ac97d, ihdad (Intel HD Audio), sb16d (Sound Blaster)
|
||||
|
||||
**Display**: vesad (VESA framebuffer), virtio-gpud (VirtIO 2D)
|
||||
|
||||
**Other**: pcid (PCI enumeration), acpid (ACPI), usbhidd (USB HID), inputd (input multiplexor)
|
||||
|
||||
### GPU Driver Status
|
||||
|
||||
- **No hardware-accelerated GPU drivers**
|
||||
- Only BIOS VESA and UEFI GOP framebuffers
|
||||
- Experimental Intel modesetting (Kaby Lake, Tiger Lake) — no acceleration
|
||||
- AMD, NVIDIA, ARM, PowerVR: not supported
|
||||
|
||||
## 4. Orbital Display Server
|
||||
|
||||
Orbital is Redox's display server, window manager, and compositor — all in one userspace daemon.
|
||||
|
||||
### Window Creation (via Scheme)
|
||||
|
||||
```rust
|
||||
// Open a window through the orbital scheme
|
||||
let window = File::create("orbital:myapp/800/600/My Title")?;
|
||||
|
||||
// Read input events
|
||||
let mut event = [0u8; 32];
|
||||
window.read(&mut event)?;
|
||||
|
||||
// Write pixel data (RGBA)
|
||||
window.write(&pixel_data)?;
|
||||
window.sync_all()?;
|
||||
```
|
||||
|
||||
### Supported Toolkits
|
||||
|
||||
- SDL1.2, SDL2 — games and emulators
|
||||
- winit — Rust GUI abstraction (has Orbital backend)
|
||||
- softbuffer — software rendering
|
||||
- Iced, egui, Slint — via winit/softbuffer
|
||||
|
||||
### Graphics Stack
|
||||
|
||||
```
|
||||
Application
|
||||
↓ (SDL2 / winit / liborbital)
|
||||
Orbital (display server + compositor)
|
||||
↓ (scheme: display.vesa or display.virtio-gpu)
|
||||
vesad / virtio-gpud (display driver daemon)
|
||||
↓ (scheme: memory + irq)
|
||||
Hardware (framebuffer / VirtIO GPU)
|
||||
```
|
||||
|
||||
Rendering is software-only via LLVMpipe (Mesa CPU OpenGL emulation).
|
||||
No GPU acceleration pipeline exists yet.
|
||||
|
||||
## 5. relibc — C Library
|
||||
|
||||
relibc is a **POSIX-compatible C library written in Rust**. Provides:
|
||||
- Standard C library functions
|
||||
- POSIX syscalls (section 2 + 3)
|
||||
- Linux/BSD extensions
|
||||
|
||||
Targets: Redox (via `redox-rt`), Linux (direct syscalls).
|
||||
Architectures: i586, x86_64, aarch64, riscv64gc.
|
||||
|
||||
### Known POSIX Gaps (blocking Wayland)
|
||||
|
||||
These are the specific missing features found in libwayland's `redox.patch`:
|
||||
|
||||
| Missing API | Used By | Status |
|
||||
|-------------|---------|--------|
|
||||
| `signalfd` / `SFD_CLOEXEC` | libwayland event loop | Not implemented |
|
||||
| `timerfd` / `TFD_CLOEXEC` / `TFD_TIMER_ABSTIME` | libwayland timers | Not implemented |
|
||||
| `eventfd` / `EFD_CLOEXEC` | libwayland server | Not implemented |
|
||||
| `F_DUPFD_CLOEXEC` | libwayland fd management | Not implemented |
|
||||
| `MSG_CMSG_CLOEXEC` | libwayland socket recv | Not implemented |
|
||||
| `MSG_NOSIGNAL` | libwayland connection | Not implemented |
|
||||
| `open_memstream` | libdrm, libwayland | Not implemented |
|
||||
|
||||
## 6. Build System (This Repository)
|
||||
|
||||
This repository is the **build system** — it orchestrates fetching, building, and packaging
|
||||
components from ~100+ Git repositories into a bootable Redox image.
|
||||
|
||||
### Key Directories
|
||||
|
||||
| Directory | Purpose |
|
||||
|-----------|---------|
|
||||
| `config/` | Build configurations (desktop, server, wayland, x11, minimal) |
|
||||
| `recipes/` | Package recipes (source + build instructions) |
|
||||
| `recipes/core/` | Essential: kernel, bootloader, relibc, init |
|
||||
| `recipes/gui/` | Orbital, orbterm, orbutils |
|
||||
| `recipes/libs/` | Libraries: mesa, cairo, pango, SDL, etc. |
|
||||
| `recipes/wip/` | Work-in-progress packages (wayland/, kde/, gnome/, etc.) |
|
||||
| `mk/` | Makefile infrastructure |
|
||||
| `src/` | Build system source (cookbook tool in Rust) |
|
||||
|
||||
### Config System
|
||||
|
||||
Configs are TOML files that include each other:
|
||||
|
||||
```
|
||||
wayland.toml → desktop.toml → desktop-minimal.toml → minimal.toml → base.toml
|
||||
```
|
||||
|
||||
Each config selects packages and overrides init scripts. For example, `wayland.toml`
|
||||
overrides the orbital init to launch `cosmic-comp` instead of `orblogin`.
|
||||
|
||||
### Build Flow
|
||||
|
||||
```bash
|
||||
make all
|
||||
→ downloads cross-toolchain (Clang/LLVM for x86_64-unknown-redox)
|
||||
→ fetches recipe sources (git/tar)
|
||||
→ applies patches (redox.patch files)
|
||||
→ builds each recipe (cargo, meson, cmake, make, custom)
|
||||
→ stages into sysroot
|
||||
→ creates RedoxFS image
|
||||
→ produces harddrive.img / redox-live.iso
|
||||
```
|
||||
|
||||
## 7. Existing Wayland/X11 Support
|
||||
|
||||
### X11 (Working)
|
||||
|
||||
Config: `config/x11.toml`
|
||||
- X.org with dummy video driver inside Orbital
|
||||
- GTK3, MATE desktop, Mesa EGL
|
||||
- DRI3 enabled
|
||||
- Software rendering only
|
||||
|
||||
### Wayland (Experimental, WIP)
|
||||
|
||||
Config: `config/wayland.toml`
|
||||
- **21 Wayland recipes** in `recipes/wip/wayland/`
|
||||
- **cosmic-comp**: partially working, performance issues, no keyboard input
|
||||
- **smallvil** (Smithay): ported, basic compositor running
|
||||
- **wlroots**: not compiled or tested
|
||||
- **sway**: not compiled or tested
|
||||
- **hyprland**: not compiled or tested
|
||||
- **niri**: needs Smithay port
|
||||
- **xwayland**: partially patched, needs wayland-client fixes
|
||||
|
||||
### Key Blockers for Wayland
|
||||
|
||||
1. **relibc POSIX gaps** (signalfd, timerfd, eventfd, open_memstream)
|
||||
2. **No GPU acceleration** (only software rendering)
|
||||
3. **No libinput** (requires evdev + udev)
|
||||
4. **No DRM/KMS** (libdrm has all GPU drivers disabled)
|
||||
5. **cosmic-comp**: missing keyboard input, performance issues
|
||||
@@ -0,0 +1,184 @@
|
||||
# 02 — Gap Analysis & Roadmap
|
||||
|
||||
## 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)
|
||||
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)
|
||||
|
||||
## Dependency Chain: Hardware → KDE Desktop
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ KDE Plasma Desktop │
|
||||
│ (KWin compositor, Plasma Shell, Qt, KDE Frameworks) │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Wayland Protocol │
|
||||
│ (libwayland, wayland-protocols, compositor) │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Graphics Stack │
|
||||
│ (Mesa3D OpenGL/Vulkan, GBM, libdrm, GPU driver) │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Kernel Interfaces │
|
||||
│ (DRM/KMS, GEM/TTM, DMA-BUF, evdev, udev) │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Hardware │
|
||||
│ (GPU: AMD/Intel/NVIDIA, Input: keyboard/mouse/touch) │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Gap Matrix with Concrete File References
|
||||
|
||||
### Layer 1: POSIX Interfaces (relibc)
|
||||
|
||||
| API | Status | Where to implement | Effort |
|
||||
|-----|--------|--------------------|--------|
|
||||
| `signalfd`/`signalfd4` | **Missing** | `relibc/src/header/signal/mod.rs` + `signal/types.rs` | Medium |
|
||||
| `timerfd_create/settime/gettime` | **Missing** | `relibc/src/header/sys_timerfd/` (NEW directory) | Medium |
|
||||
| `eventfd`/`eventfd_read`/`eventfd_write` | **Missing** | `relibc/src/header/sys_eventfd/` (NEW directory) | Low |
|
||||
| `F_DUPFD_CLOEXEC` | **Missing** | `relibc/src/header/fcntl/mod.rs` (add constant) | Low |
|
||||
| `MSG_CMSG_CLOEXEC` | **Missing** | `relibc/src/header/sys_socket/mod.rs` | Low |
|
||||
| `MSG_NOSIGNAL` | **Missing** | `relibc/src/header/sys_socket/mod.rs` | Low |
|
||||
| `open_memstream` | **Missing** | `relibc/src/header/stdio/src.rs` | Low |
|
||||
| UDS + FD passing | **Done** | Already implemented | — |
|
||||
| `epoll` (event scheme) | **Done** | Redox `scheme:event` | — |
|
||||
| `mmap`/`mprotect` | **Done** | Kernel syscalls | — |
|
||||
| `fork`/`exec` | **Done** | Userspace via `thisproc:` scheme | — |
|
||||
|
||||
**Proof of gap**: See `recipes/wip/wayland/libwayland/redox.patch` — all 7 missing APIs are stubbed there.
|
||||
|
||||
### Layer 2: GPU / Display Infrastructure
|
||||
|
||||
| Component | Status | Where to implement | Concrete doc |
|
||||
|-----------|--------|--------------------|-------------|
|
||||
| DRM/KMS scheme | **Missing** | New daemon: `redox-drm` crate | [04 §3](04-LINUX-DRIVER-COMPAT.md) |
|
||||
| GPU driver (Intel) | Experimental modeset only | `redox-drm/src/drivers/intel/` | [04 §3](04-LINUX-DRIVER-COMPAT.md) |
|
||||
| GEM buffers | **Missing** | `redox-drm/src/gem.rs` | [04 §3](04-LINUX-DRIVER-COMPAT.md) |
|
||||
| DMA-BUF sharing | **Missing** | `redox-drm/src/dmabuf.rs` | [04 §3](04-LINUX-DRIVER-COMPAT.md) |
|
||||
| Mesa hardware backend | **Missing** | Mesa winsys for Redox DRM | [03 §3.4](03-WAYLAND-ON-REDOX.md) |
|
||||
| GPU OpenGL | Software only | Blocked on GPU driver | [04](04-LINUX-DRIVER-COMPAT.md) |
|
||||
|
||||
### Layer 3: Input Stack
|
||||
|
||||
| Component | Status | Where to implement | Concrete doc |
|
||||
|-----------|--------|--------------------|-------------|
|
||||
| evdev daemon | **Missing** | New: `recipes/core/evdevd/` | [03 §2](03-WAYLAND-ON-REDOX.md) |
|
||||
| udev shim | **Missing** | New: `recipes/wip/wayland/udev-shim/` | [03 §2](03-WAYLAND-ON-REDOX.md) |
|
||||
| libinput | **Missing** | `recipes/wip/wayland/libinput/` (NEW) | [03 §2](03-WAYLAND-ON-REDOX.md) |
|
||||
| XKB layouts | **Done** | `xkeyboard-config` ported | — |
|
||||
| seatd | Recipe exists, untested | `recipes/wip/wayland/seatd/` | — |
|
||||
|
||||
### Layer 4: Wayland Protocol
|
||||
|
||||
| Component | Status | Recipe | Blocker |
|
||||
|-----------|--------|--------|---------|
|
||||
| libwayland | Patched, broken timers | `recipes/wip/wayland/libwayland/` | Layer 1 POSIX gaps |
|
||||
| cosmic-comp | No keyboard input | `recipes/wip/wayland/cosmic-comp/` | Layer 3 libinput |
|
||||
| smallvil (Smithay) | Basic, slow | `recipes/wip/wayland/smallvil/` | Layer 2+3 for DRM+input |
|
||||
| wlroots/sway/hyprland | Not tested | `recipes/wip/wayland/wlroots/` | Layer 2+3 |
|
||||
|
||||
### Layer 5: KDE Plasma
|
||||
|
||||
| Component | Status | Concrete doc |
|
||||
|-----------|--------|-------------|
|
||||
| Qt 6 | Not ported | [05 Phase KDE-A](05-KDE-PLASMA-ON-REDOX.md) |
|
||||
| KDE Frameworks | Not ported | [05 Phase KDE-B](05-KDE-PLASMA-ON-REDOX.md) |
|
||||
| KWin | Not ported | [05 Phase KDE-C](05-KDE-PLASMA-ON-REDOX.md) |
|
||||
| Plasma Shell | Not ported | [05 Phase KDE-C](05-KDE-PLASMA-ON-REDOX.md) |
|
||||
| D-Bus | **Ported** | `config/x11.toml` has it working |
|
||||
|
||||
### Layer 6: Linux Driver Compatibility
|
||||
|
||||
| Component | Status | Concrete doc |
|
||||
|-----------|--------|-------------|
|
||||
| `redox-driver-sys` crate | Not started | [04 §3](04-LINUX-DRIVER-COMPAT.md) |
|
||||
| `linux-kpi` C headers | Not started | [04 §3](04-LINUX-DRIVER-COMPAT.md) |
|
||||
| i915 C driver port | Not started | [04 §4](04-LINUX-DRIVER-COMPAT.md) |
|
||||
| amdgpu C driver port | Not started | [04 §5](04-LINUX-DRIVER-COMPAT.md) |
|
||||
|
||||
---
|
||||
|
||||
## Concrete Roadmap with Milestones
|
||||
|
||||
### Milestone M1: "libwayland works natively" (2-4 weeks)
|
||||
- Implement 7 POSIX APIs in relibc (see Layer 1 table)
|
||||
- Remove `redox.patch` from libwayland recipe
|
||||
- **Test**: `wayland-rs_simple_window` runs without crashes
|
||||
- **Delivers**: libwayland, wayland-protocols, libdrm all build natively
|
||||
|
||||
### Milestone M2: "Input works via libinput" (4-6 weeks after M1)
|
||||
- Build `evdevd` daemon (reads Redox input schemes, exposes /dev/input/eventX)
|
||||
- Build `udev-shim` for hotplug
|
||||
- Port libinput with evdev backend
|
||||
- **Test**: `libinput list-devices` shows keyboard and mouse
|
||||
- **Delivers**: Full input stack for any Wayland compositor
|
||||
|
||||
### Milestone M3: "Display output via DRM" (8-12 weeks, parallel with M2)
|
||||
- Build `redox-driver-sys` crate
|
||||
- Build `redox-drm` daemon with Intel native driver
|
||||
- Register `scheme:drm/card0`
|
||||
- **Test**: `modetest -M intel` shows display modes
|
||||
- **Delivers**: KMS modesetting, hardware display control
|
||||
|
||||
### Milestone M4: "Wayland compositor with input + display" (2-4 weeks after M2+M3)
|
||||
- Add Redox backends to Smithay (input + DRM + EGL)
|
||||
- Build `smallvil` with Redox backends
|
||||
- **Test**: Compositor takes over display, keyboard/mouse work
|
||||
- **Delivers**: First fully functional Wayland compositor on Redox
|
||||
|
||||
### Milestone M5: "Qt application runs" (6-8 weeks after M4)
|
||||
- Port `qtbase` with Wayland QPA
|
||||
- Port `qtwayland`, `qtdeclarative`
|
||||
- **Test**: Qt widget app shows window on compositor
|
||||
- **Delivers**: Qt development on Redox
|
||||
|
||||
### Milestone M6: "KDE app runs" (6-8 weeks after M5)
|
||||
- Port KDE Frameworks (25 frameworks)
|
||||
- Port one KDE app (e.g., Kate)
|
||||
- **Test**: Kate editor opens and edits a file
|
||||
- **Delivers**: KDE application ecosystem begins
|
||||
|
||||
### Milestone M7: "KDE Plasma desktop" (4-6 weeks after M6)
|
||||
- Port KWin (DRM/Wayland backend)
|
||||
- Port Plasma Shell
|
||||
- Create `config/kde.toml`
|
||||
- **Test**: Full Plasma session boots
|
||||
- **Delivers**: KDE Plasma as a usable desktop
|
||||
|
||||
### Milestone M8: "Linux GPU drivers" (8-12 weeks, parallel track from M3)
|
||||
- Build `linux-kpi` C headers
|
||||
- Port i915 as proof of concept
|
||||
- Port amdgpu for AMD support
|
||||
- **Test**: amdgpu drives AMD GPU on Redox
|
||||
- **Delivers**: Broad GPU hardware support via Linux driver ports
|
||||
|
||||
---
|
||||
|
||||
## Parallel Execution Plan
|
||||
|
||||
```
|
||||
Week 1-4: M1 (relibc POSIX gaps)
|
||||
Week 3-12: M2 (evdev input) ──── parallel ──── M3 (DRM/KMS)
|
||||
Week 13-16: M4 (Wayland compositor = M2 + M3 + M1)
|
||||
Week 13-24: M8 (Linux driver compat, parallel with M4-M6)
|
||||
Week 17-24: M5 (Qt Foundation)
|
||||
Week 25-32: M6 (KDE Frameworks)
|
||||
Week 33-38: M7 (Plasma Desktop)
|
||||
```
|
||||
|
||||
**Total to KDE Plasma**: ~38 weeks (~9 months) with 2 developers.
|
||||
**Total to Linux driver compat**: ~24 weeks (~6 months) in parallel.
|
||||
|
||||
## Critical Path
|
||||
|
||||
```
|
||||
M1 (POSIX) ──────────────────────────────────────┐
|
||||
│
|
||||
M3 (DRM/KMS) ─────────── M4 (Compositor) ── M5 (Qt) ── M6 (KDE) ── M7 (Plasma)
|
||||
│ ↑ │
|
||||
M2 (Input) ──────────────┘ M8 (Linux drivers, parallel)
|
||||
```
|
||||
|
||||
**Shortest path to a desktop**: M1 → M2 → M3 (parallel) → M4 → M5 → M6 → M7
|
||||
**Shortest path to GPU drivers**: M3 → M8 (can start as soon as `redox-driver-sys` exists)
|
||||
@@ -0,0 +1,519 @@
|
||||
# 03 — Wayland on Redox: Concrete Implementation Path
|
||||
|
||||
## Goal
|
||||
|
||||
Get a working Wayland compositor on Redox OS that can run KDE Plasma applications.
|
||||
|
||||
## Current State
|
||||
|
||||
- `config/wayland.toml` exists — launches `cosmic-comp` or `smallvil` via `orbital-wayland`
|
||||
- 21 Wayland recipes in `recipes/wip/wayland/` — most untested
|
||||
- `libwayland` 1.24.0 builds with `redox.patch` that stubs out 7 POSIX APIs
|
||||
- `smallvil` (Smithay) runs as basic compositor, performance poor
|
||||
- `cosmic-comp` builds but has no keyboard input (missing libinput)
|
||||
- `libdrm` builds with all GPU drivers disabled
|
||||
- Mesa uses OSMesa (software rendering only)
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Fix relibc POSIX Gaps (1-2 weeks)
|
||||
|
||||
### What to implement
|
||||
|
||||
These are the 7 APIs that libwayland's `redox.patch` removes. Each must be added
|
||||
to `relibc` (repo: https://gitlab.redox-os.org/redox-os/relibc).
|
||||
|
||||
#### 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
|
||||
|
||||
---
|
||||
|
||||
## 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**
|
||||
|
||||
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
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
│ │ └── dmabuf.rs — DMA-BUF export/import
|
||||
│ └── 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
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Working Wayland Compositor (4-6 weeks after Steps 1-3)
|
||||
|
||||
### Recommended: Smithay/smallvil first, then KWin
|
||||
|
||||
**Why Smithay first:**
|
||||
- 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
|
||||
- Gets us a working compositor months before KWin is ported
|
||||
|
||||
**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/smallvil/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 = ["smallvil"]
|
||||
```
|
||||
|
||||
### Verification
|
||||
|
||||
1. `smallvil` 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
|
||||
|
||||
---
|
||||
|
||||
## Step 5: Enable cosmic-comp and Other Compositors
|
||||
|
||||
Once Steps 1-4 are done:
|
||||
|
||||
1. **cosmic-comp**: Uncomment libinput dependency in recipe, rebuild
|
||||
2. **wlroots**: Build with libdrm + libinput + GBM
|
||||
3. **sway**: Should work once wlroots builds
|
||||
4. **KWin**: See `05-KDE-PLASMA-ON-REDOX.md` for the full path
|
||||
|
||||
---
|
||||
|
||||
## 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.
|
||||
@@ -0,0 +1,483 @@
|
||||
# 04 — Linux Driver Compatibility Layer: Concrete Implementation Path
|
||||
|
||||
## Goal
|
||||
|
||||
Enable running Linux GPU drivers (amdgpu, i915, nouveau) on Redox OS with minimal
|
||||
changes to the driver source code, by providing a FreeBSD LinuxKPI-style compatibility shim.
|
||||
|
||||
## Why This Is Needed
|
||||
|
||||
Writing native Rust GPU drivers for every vendor is years of work. Linux has mature,
|
||||
vendor-supported GPU drivers. A compatibility layer lets us port them with `#ifdef __redox__`
|
||||
patches instead of full rewrites.
|
||||
|
||||
**Target drivers** (in priority order):
|
||||
1. **i915** (Intel) — best documented, most relevant for laptops
|
||||
2. **amdgpu** (AMD) — large market share, good open-source driver
|
||||
3. **nouveau / nvk** (NVIDIA) — community driver, limited performance
|
||||
4. **Skip**: NVIDIA proprietary (binary-only, impossible without full Linux kernel)
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
### Two-Mode Design
|
||||
|
||||
The compat layer operates in two modes:
|
||||
|
||||
**Mode A: C Driver Port** — Compile Linux C driver against our headers, run as userspace daemon
|
||||
**Mode B: Rust Wrapper** — Rust crate provides idiomatic API, internally calls compat layer
|
||||
|
||||
Both modes share the same bottom layer: `redox-driver-sys`.
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────┐
|
||||
│ Mode A: C Driver Port │
|
||||
│ Linux C driver (i915.ko source) │
|
||||
│ compiled with -D__redox__ against linux-kpi headers │
|
||||
├────────────────────────────────────────────────────────────┤
|
||||
│ Mode B: Rust Wrapper │
|
||||
│ Rust crate (redox-intel-gpu) using compat APIs │
|
||||
├────────────────────────────────────────────────────────────┤
|
||||
│ linux-kpi (C header compatibility) │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ linux/ │ │ linux/ │ │ linux/ │ │ linux/ │ │
|
||||
│ │ slab.h │ │ mutex.h │ │ pci.h │ │ drm*.h │ │
|
||||
│ │ (malloc) │ │ (pthread)│ │ (pcid) │ │ (scheme) │ │
|
||||
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
||||
├────────────────────────────────────────────────────────────┤
|
||||
│ redox-driver-sys (Rust crate) │
|
||||
│ Provides: memory mapping, IRQ, DMA, PCI, DRM scheme │
|
||||
├────────────────────────────────────────────────────────────┤
|
||||
│ Redox OS │
|
||||
│ scheme:memory scheme:irq scheme:pci scheme:drm │
|
||||
└────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementation: Crate and File Layout
|
||||
|
||||
### Crate 1: `redox-driver-sys` (Low-level Redox driver primitives)
|
||||
|
||||
**Repository**: New crate in the Redox ecosystem.
|
||||
**Purpose**: Safe Rust wrappers around Redox's scheme-based hardware access.
|
||||
|
||||
```
|
||||
redox-driver-sys/
|
||||
├── Cargo.toml
|
||||
├── src/
|
||||
│ ├── lib.rs — Re-exports
|
||||
│ ├── memory.rs — Physical memory mapping (scheme:memory)
|
||||
│ ├── irq.rs — Interrupt handling (scheme:irq)
|
||||
│ ├── pci.rs — PCI device access (scheme:pci / pcid)
|
||||
│ ├── io.rs — Port I/O (iopl syscall)
|
||||
│ └── dma.rs — DMA buffer management
|
||||
```
|
||||
|
||||
**Key implementations:**
|
||||
|
||||
```rust
|
||||
// src/memory.rs
|
||||
pub fn map_physical(phys: u64, size: usize, flags: MapFlags) -> Result<*mut u8> {
|
||||
// Open scheme:memory/physical
|
||||
// Use fmap to map physical address range
|
||||
// flags: WriteCombine, Uncacheable, WriteBack
|
||||
let fd = File::open("scheme:memory/physical")?;
|
||||
let ptr = syscall::fmap(fd.as_raw_fd(), &Map {
|
||||
offset: phys,
|
||||
size,
|
||||
flags: flags.to_syscall_flags(),
|
||||
})?;
|
||||
Ok(ptr as *mut u8)
|
||||
}
|
||||
|
||||
pub fn unmap_physical(ptr: *mut u8, size: usize) -> Result<()> {
|
||||
syscall::funmap(ptr as usize, size)?;
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
```rust
|
||||
// src/irq.rs
|
||||
pub struct IrqHandle { fd: File }
|
||||
|
||||
impl IrqHandle {
|
||||
pub fn request(irq_num: u32) -> Result<Self> {
|
||||
// Open /scheme/irq/{irq_num}
|
||||
// Read blocks until interrupt fires
|
||||
let fd = File::open(&format!("scheme:irq/{}", irq_num))?;
|
||||
Ok(Self { fd })
|
||||
}
|
||||
|
||||
pub fn wait(&mut self) -> Result<()> {
|
||||
let mut buf = [0u8; 8];
|
||||
self.fd.read(&mut buf)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```rust
|
||||
// src/pci.rs
|
||||
pub struct PciDevice {
|
||||
bus: u8, dev: u8, func: u8,
|
||||
vendor_id: u16, device_id: u16,
|
||||
bars: [u64; 6],
|
||||
bar_sizes: [usize; 6],
|
||||
irq: u32,
|
||||
}
|
||||
|
||||
pub fn enumerate() -> Result<Vec<PciDevice>> {
|
||||
// Read from pcid-spawner or scheme:pci
|
||||
// Parse PCI configuration space for each device
|
||||
// Filter to GPU devices (class 0x030000-0x0302xx)
|
||||
}
|
||||
```
|
||||
|
||||
### Crate 2: `linux-kpi` (Linux kernel API compatibility)
|
||||
|
||||
**Repository**: New crate. Installs C headers for use by Linux C drivers.
|
||||
**Purpose**: Provides `linux/*.h` headers that translate Linux kernel APIs to `redox-driver-sys`.
|
||||
|
||||
```
|
||||
linux-kpi/
|
||||
├── Cargo.toml
|
||||
├── src/
|
||||
│ ├── lib.rs — Rust API for Rust drivers
|
||||
│ ├── c_headers/ — C headers for C driver ports
|
||||
│ │ ├── linux/
|
||||
│ │ │ ├── slab.h → malloc/kfree (redox-driver-sys::memory)
|
||||
│ │ │ ├── mutex.h → pthread mutex (redox-driver-sys::sync)
|
||||
│ │ │ ├── spinlock.h → atomic lock
|
||||
│ │ │ ├── pci.h → redox-driver-sys::pci
|
||||
│ │ │ ├── io.h → port I/O (iopl)
|
||||
│ │ │ ├── irq.h → redox-driver-sys::irq
|
||||
│ │ │ ├── device.h → struct device wrapper
|
||||
│ │ │ ├── kobject.h → reference-counted object
|
||||
│ │ │ ├── workqueue.h → thread pool
|
||||
│ │ │ ├── idr.h → ID allocation
|
||||
│ │ │ └── dma-mapping.h → bus DMA (redox-driver-sys::dma)
|
||||
│ │ ├── drm/
|
||||
│ │ │ ├── drm.h → DRM core types
|
||||
│ │ │ ├── drm_crtc.h → KMS types
|
||||
│ │ │ ├── drm_gem.h → GEM buffer objects
|
||||
│ │ │ └── drm_ioctl.h → DRM ioctl definitions
|
||||
│ │ └── asm/
|
||||
│ │ └── io.h → inl/outl port I/O
|
||||
│ └── rust_impl/ — Rust implementations backing the C headers
|
||||
│ ├── memory.rs — kzalloc, kmalloc, kfree
|
||||
│ ├── sync.rs — mutex, spinlock, completion
|
||||
│ ├── workqueue.rs — work queue thread pool
|
||||
│ ├── pci.rs — pci_register_driver, etc.
|
||||
│ └── drm_shim.rs — DRM core shim (connects to scheme:drm)
|
||||
```
|
||||
|
||||
**Example C header:**
|
||||
|
||||
```c
|
||||
// c_headers/linux/slab.h
|
||||
#ifndef _LINUX_SLAB_H
|
||||
#define _LINUX_SLAB_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
// GFP flags — on Redox, these are no-ops (userspace allocation)
|
||||
#define GFP_KERNEL 0
|
||||
#define GFP_ATOMIC 1
|
||||
#define GFP_DMA32 2
|
||||
|
||||
void *kmalloc(size_t size, unsigned int flags);
|
||||
void *kzalloc(size_t size, unsigned int flags);
|
||||
void kfree(const void *ptr);
|
||||
|
||||
#endif
|
||||
```
|
||||
|
||||
**Corresponding Rust implementation:**
|
||||
|
||||
```rust
|
||||
// src/rust_impl/memory.rs
|
||||
use std::alloc::{alloc, alloc_zeroed, dealloc, Layout};
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn kmalloc(size: usize, _flags: u32) -> *mut u8 {
|
||||
unsafe {
|
||||
let layout = Layout::from_size_align(size, 64).unwrap(); // cache-line aligned
|
||||
alloc(layout)
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn kzalloc(size: usize, _flags: u32) -> *mut u8 {
|
||||
unsafe {
|
||||
let layout = Layout::from_size_align(size, 64).unwrap();
|
||||
alloc_zeroed(layout)
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn kfree(ptr: *const u8) {
|
||||
if !ptr.is_null() {
|
||||
unsafe {
|
||||
// Note: Linux kfree doesn't take size. We need a size-tracking allocator.
|
||||
// Use a HashMap<ptr, Layout> for tracking, or switch to a custom allocator.
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Crate 3: `redox-drm` (DRM scheme implementation)
|
||||
|
||||
**Repository**: Part of the Redox base repo or new crate.
|
||||
**Purpose**: The daemon that registers `scheme:drm` and talks to GPU hardware.
|
||||
|
||||
```
|
||||
redox-drm/
|
||||
├── Cargo.toml
|
||||
├── src/
|
||||
│ ├── main.rs — Daemon entry, scheme registration
|
||||
│ ├── scheme.rs — "drm" scheme handler (processes ioctls)
|
||||
│ ├── kms/
|
||||
│ │ ├── mod.rs — KMS core
|
||||
│ │ ├── crtc.rs — CRTC state machine
|
||||
│ │ ├── connector.rs — Hotplug detection, EDID reading
|
||||
│ │ ├── encoder.rs — Encoder management
|
||||
│ │ └── plane.rs — Primary/cursor planes
|
||||
│ ├── gem.rs — GEM buffer object management
|
||||
│ ├── dmabuf.rs — DMA-BUF export/import via FD passing
|
||||
│ └── drivers/
|
||||
│ ├── mod.rs — trait GpuDriver
|
||||
│ ├── intel/
|
||||
│ │ ├── mod.rs — Intel driver entry
|
||||
│ │ ├── gtt.rs — Graphics Translation Table
|
||||
│ │ ├── display.rs — Display pipe configuration
|
||||
│ │ └── ring.rs — Command ring buffer (for acceleration later)
|
||||
│ └── amd/
|
||||
│ ├── mod.rs — AMD driver entry (from amdgpu port)
|
||||
│ └── ... — Wrapped amdgpu C code
|
||||
```
|
||||
|
||||
```rust
|
||||
// src/drivers/mod.rs
|
||||
pub trait GpuDriver: Send + Sync {
|
||||
fn driver_name(&self) -> &str;
|
||||
fn driver_desc(&self) -> &str;
|
||||
fn driver_date(&self) -> &str;
|
||||
|
||||
// KMS
|
||||
fn get_modes(&self, connector: u32) -> Vec<ModeInfo>;
|
||||
fn set_crtc(&self, crtc: u32, fb: u32, connectors: &[u32], mode: &ModeInfo) -> Result<()>;
|
||||
fn page_flip(&self, crtc: u32, fb: u32, flags: u32) -> Result<u64>;
|
||||
fn get_vblank(&self, crtc: u32) -> Result<u64>;
|
||||
|
||||
// GEM
|
||||
fn gem_create(&self, size: u64) -> Result<GemHandle>;
|
||||
fn gem_close(&self, handle: GemHandle) -> Result<()>;
|
||||
fn gem_mmap(&self, handle: GemHandle) -> Result<*mut u8>;
|
||||
fn gem_export_dmafd(&self, handle: GemHandle) -> Result<RawFd>;
|
||||
fn gem_import_dmafd(&self, fd: RawFd) -> Result<GemHandle>;
|
||||
|
||||
// Connector info
|
||||
fn detect_connectors(&self) -> Vec<ConnectorInfo>;
|
||||
fn get_edid(&self, connector: u32) -> Vec<u8>;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Concrete Porting Example: Intel i915 Driver
|
||||
|
||||
### Step 1: Extract i915 from Linux kernel
|
||||
|
||||
```bash
|
||||
# Clone Linux kernel
|
||||
git clone --depth 1 https://github.com/torvalds/linux.git
|
||||
# Extract relevant directories
|
||||
tar cf intel-driver.tar linux/drivers/gpu/drm/i915/ \
|
||||
linux/include/drm/ \
|
||||
linux/include/linux/ \
|
||||
linux/arch/x86/include/
|
||||
```
|
||||
|
||||
### Step 2: Create recipe
|
||||
|
||||
```toml
|
||||
# recipes/wip/drivers/i915/recipe.toml
|
||||
[source]
|
||||
tar = "intel-driver.tar"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
dependencies = [
|
||||
"redox-driver-sys",
|
||||
"linux-kpi",
|
||||
"redox-drm",
|
||||
]
|
||||
script = """
|
||||
DYNAMIC_INIT
|
||||
|
||||
# Build i915 driver as a shared library
|
||||
# linked against linux-kpi and redox-driver-sys
|
||||
export CFLAGS="-I${COOKBOOK_SYSROOT}/include/linux-kpi -D__redox__"
|
||||
export LDFLAGS="-lredox_driver_sys -llinux_kpi -lredox_drm"
|
||||
|
||||
# Compile the driver source files
|
||||
find drivers/gpu/drm/i915/ -name '*.c' | while read src; do
|
||||
x86_64-unknown-redox-gcc -c $CFLAGS "$src" -o "${src%.c}.o" || true
|
||||
done
|
||||
|
||||
# Link into a single shared library
|
||||
x86_64-unknown-redox-gcc -shared -o i915_redox.so \
|
||||
$(find drivers/gpu/drm/i915/ -name '*.o') \
|
||||
$LDFLAGS
|
||||
|
||||
mkdir -p ${COOKBOOK_STAGE}/usr/lib/redox/drivers
|
||||
cp i915_redox.so ${COOKBOOK_STAGE}/usr/lib/redox/drivers/
|
||||
"""
|
||||
```
|
||||
|
||||
### Step 3: Minimal patches needed
|
||||
|
||||
For i915 on Redox, these are the typical `#ifdef __redox__` changes:
|
||||
|
||||
```c
|
||||
// Example patches (conceptual):
|
||||
|
||||
// 1. Replace Linux module init with daemon main()
|
||||
#ifdef __redox__
|
||||
int main(int argc, char **argv) {
|
||||
return i915_driver_init();
|
||||
}
|
||||
#else
|
||||
module_init(i915_init);
|
||||
module_exit(i915_exit);
|
||||
#endif
|
||||
|
||||
// 2. Replace kernel memory allocation
|
||||
#ifdef __redox__
|
||||
#include <linux/slab.h> // Our compat header
|
||||
// kzalloc/kfree still work, but go to userspace allocator
|
||||
#else
|
||||
#include <linux/slab.h> // Real Linux
|
||||
#endif
|
||||
|
||||
// 3. Replace PCI access
|
||||
#ifdef __redox__
|
||||
// Use redox-driver-sys PCI API instead of linux/pci.h internals
|
||||
struct pci_dev *pdev = redox_pci_find_device(PCI_VENDOR_ID_INTEL, device_id);
|
||||
#else
|
||||
pdev = pci_get_device(PCI_VENDOR_ID_INTEL, device_id, NULL);
|
||||
#endif
|
||||
|
||||
// 4. Replace MMIO mapping
|
||||
#ifdef __redox__
|
||||
void __iomem *regs = redox_ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
|
||||
#else
|
||||
void __iomem *regs = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
|
||||
#endif
|
||||
```
|
||||
|
||||
### Step 4: Run as daemon
|
||||
|
||||
```bash
|
||||
# In Redox init:
|
||||
i915d # Registers scheme:drm/card0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Concrete Porting Example: AMD amdgpu Driver
|
||||
|
||||
AMD's driver is larger and more complex than Intel's. The LinuxKPI approach is essential.
|
||||
|
||||
### Key challenges for amdgpu:
|
||||
|
||||
1. **Firmware loading**: amdgpu needs proprietary firmware blobs. Redox has no firmware
|
||||
loading infrastructure yet. Need to implement:
|
||||
```
|
||||
scheme:firmware/amdgpu/ — firmware blob storage
|
||||
request_firmware() — compat function that reads from scheme
|
||||
```
|
||||
|
||||
2. **TTM memory manager**: amdgpu uses TTM (Translation Table Maps) for GPU memory.
|
||||
Need to port TTM to use Redox's memory scheme:
|
||||
```rust
|
||||
// TTM → Redox mapping:
|
||||
// ttm_tt → allocated pages via scheme:memory
|
||||
// ttm_buffer_object → GemHandle in scheme:drm
|
||||
// ttm_bo_move → page table updates via GPU MMIO
|
||||
```
|
||||
|
||||
3. **Display Core (DC)**: AMD's display code is ~100K lines. Need to:
|
||||
- Port DCN (Display Core Next) hardware programming
|
||||
- Adapt to Redox's DRM scheme instead of Linux kernel DRM
|
||||
- Keep most code unchanged, just redirect memory/register access
|
||||
|
||||
4. **Power management**: amdgpu uses Linux power management APIs. Need stubs:
|
||||
```c
|
||||
#ifdef __redox__
|
||||
// No power management on Redox yet — always-on
|
||||
#define pm_runtime_get_sync(dev) 0
|
||||
#define pm_runtime_put_autosuspend(dev) 0
|
||||
#define pm_runtime_allow(dev) 0
|
||||
#endif
|
||||
```
|
||||
|
||||
### Estimated patches for amdgpu: ~2000-3000 lines of `#ifdef __redox__`
|
||||
|
||||
---
|
||||
|
||||
## evdev Compatibility Layer
|
||||
|
||||
In addition to GPU drivers, we need an evdev compat layer for input:
|
||||
|
||||
### Crate: `redox-evdev`
|
||||
|
||||
```
|
||||
redox-evdev/
|
||||
├── src/
|
||||
│ ├── lib.rs — evdev API for Rust
|
||||
│ ├── c_headers/
|
||||
│ │ └── linux/
|
||||
│ │ └── input.h — struct input_event, EV_*, KEY_*, etc.
|
||||
│ └── daemon/
|
||||
│ └── main.rs — evdevd daemon (see doc 03)
|
||||
```
|
||||
|
||||
The C header `linux/input.h` provides:
|
||||
- `struct input_event` — identical to Linux
|
||||
- `EV_KEY`, `EV_REL`, `EV_ABS` — event types
|
||||
- `KEY_*`, `BTN_*`, `REL_*`, `ABS_*` — event codes
|
||||
- `EVIOCG*` ioctl numbers — same values as Linux
|
||||
|
||||
The daemon reads from Redox input schemes and exposes `/dev/input/eventX` nodes.
|
||||
|
||||
---
|
||||
|
||||
## Implementation Priority and Timeline
|
||||
|
||||
| Phase | Component | Effort | Delivers |
|
||||
|-------|-----------|--------|----------|
|
||||
| 1 | `redox-driver-sys` crate | 2-3 weeks | Memory, IRQ, PCI, I/O primitives |
|
||||
| 2 | Intel native driver (in `redox-drm`) | 6-8 weeks | First working GPU driver, modesetting |
|
||||
| 3 | `linux-kpi` C headers (core subset) | 3-4 weeks | Memory, sync, PCI, workqueue headers |
|
||||
| 4 | `linux-kpi` DRM headers | 2-3 weeks | DRM/KMS/GEM C API headers |
|
||||
| 5 | i915 C driver port | 3-4 weeks | Proves LinuxKPI approach works |
|
||||
| 6 | `linux-kpi` extended (TTM, firmware) | 4-6 weeks | Enables AMD driver |
|
||||
| 7 | amdgpu C driver port | 6-8 weeks | AMD GPU support |
|
||||
|
||||
**Phase 1-2 is the critical path** — a native Rust Intel driver proves the architecture
|
||||
and provides immediate value. Phases 3-7 can happen in parallel or later.
|
||||
|
||||
### With 2 developers:
|
||||
- **Month 1-2**: redox-driver-sys + Intel native driver → first display output
|
||||
- **Month 3-4**: linux-kpi core + DRM headers → i915 C port proof of concept
|
||||
- **Month 5-8**: linux-kpi TTM + amdgpu port → AMD support
|
||||
- **Total: 6-8 months** to support both Intel and AMD GPUs
|
||||
|
||||
### With 1 developer:
|
||||
- **Month 1-3**: redox-driver-sys + Intel native driver
|
||||
- **Month 4-6**: linux-kpi core + i915 port
|
||||
- **Month 7-10**: amdgpu port
|
||||
- **Total: 8-10 months**
|
||||
@@ -0,0 +1,484 @@
|
||||
# 05 — KDE Plasma on Redox: Concrete Implementation Path
|
||||
|
||||
## Goal
|
||||
|
||||
Run KDE Plasma 6 desktop environment on Redox OS, starting with a minimal viable
|
||||
desktop and expanding to full Plasma.
|
||||
|
||||
## Prerequisites (from docs 03 and 04)
|
||||
|
||||
Before KDE work begins, these MUST be complete:
|
||||
- [x] relibc POSIX gaps fixed (signalfd, timerfd, eventfd, etc.)
|
||||
- [x] evdevd + libinput working
|
||||
- [x] DRM/KMS scheme working (at least Intel modesetting)
|
||||
- [x] Wayland compositor running (Smithay/smallvil)
|
||||
- [x] Mesa EGL + software OpenGL (already ported)
|
||||
|
||||
## Three-Phase KDE Implementation
|
||||
|
||||
### Phase KDE-A: Qt Foundation (2-3 months)
|
||||
|
||||
**Goal**: A Qt application displays a window on the Redox Wayland compositor.
|
||||
|
||||
#### Step 1: Port `qtbase` (6-8 weeks)
|
||||
|
||||
**Create recipe**: `recipes/wip/qt/qtbase/recipe.toml`
|
||||
|
||||
```toml
|
||||
[source]
|
||||
tar = "https://download.qt.io/official_releases/qt/6.8/6.8.2/submodules/qtbase-everywhere-src-6.8.2.tar.xz"
|
||||
patches = ["redox.patch"]
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
dependencies = [
|
||||
"libwayland",
|
||||
"mesa", # EGL + OpenGL
|
||||
"libdrm",
|
||||
"libxkbcommon",
|
||||
"zlib",
|
||||
"openssl1",
|
||||
"glib",
|
||||
"pcre2",
|
||||
"expat",
|
||||
"fontconfig",
|
||||
"freetype2",
|
||||
]
|
||||
|
||||
script = """
|
||||
DYNAMIC_INIT
|
||||
|
||||
# Qt 6 uses CMake
|
||||
mkdir -p build && cd build
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DQT_BUILD_EXAMPLES=OFF \
|
||||
-DQT_BUILD_TESTS=OFF \
|
||||
-DFEATURE_wayland=ON \
|
||||
-DFEATURE_wayland_client=ON \
|
||||
-DFEATURE_xcb=OFF \
|
||||
-DFEATURE_xlib=OFF \
|
||||
-DFEATURE_opengl=ON \
|
||||
-DFEATURE_openssl=ON \
|
||||
-DFEATURE_dbus=ON \
|
||||
-DFEATURE_system_pcre2=ON \
|
||||
-DFEATURE_system_zlib=ON \
|
||||
-DINPUT_opengl=desktop \
|
||||
-DQT_QPA_PLATFORMS=wayland \
|
||||
-DQT_FEATURE_vulkan=OFF
|
||||
|
||||
cmake --build . -j${COOKBOOK_MAKE_JOBS}
|
||||
cmake --install . --prefix ${COOKBOOK_STAGE}/usr
|
||||
"""
|
||||
```
|
||||
|
||||
**What `redox.patch` for qtbase needs to fix**:
|
||||
|
||||
1. **Platform detection**: Add `__redox__` as a POSIX-like platform
|
||||
```
|
||||
qtbase/src/corelib/global/qsystemdetection.h — add Redox detection
|
||||
qtbase/src/corelib/io/qfilesystemengine_unix.cpp — Redox path handling
|
||||
```
|
||||
|
||||
2. **Shared memory**: Qt uses `shm_open()` for Wayland buffers
|
||||
```
|
||||
qtbase/src/corelib/kernel/qsharedmemory.cpp — map to Redox shm scheme
|
||||
```
|
||||
|
||||
3. **Process handling**: `fork`/`exec` differences
|
||||
```
|
||||
qtbase/src/corelib/io/qprocess_unix.cpp — already works (relibc POSIX)
|
||||
```
|
||||
|
||||
4. **Network**: Qt uses BSD sockets — already work via relibc
|
||||
```
|
||||
qtbase/src/network/ — should compile with relibc sockets
|
||||
```
|
||||
|
||||
**Estimated patch size**: ~500-800 lines for qtbase.
|
||||
|
||||
#### Step 2: Port `qtwayland` (1-2 weeks)
|
||||
|
||||
```toml
|
||||
# recipes/wip/qt/qtwayland/recipe.toml
|
||||
[source]
|
||||
tar = "https://download.qt.io/official_releases/qt/6.8/6.8.2/submodules/qtwayland-everywhere-src-6.8.2.tar.xz"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
dependencies = ["qtbase", "libwayland", "wayland-protocols"]
|
||||
|
||||
script = """
|
||||
DYNAMIC_INIT
|
||||
mkdir -p build && cd build
|
||||
cmake .. \
|
||||
-DCMAKE_PREFIX_PATH=${COOKBOOK_SYSROOT}/usr \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DQT_BUILD_TESTS=OFF
|
||||
cmake --build . -j${COOKBOOK_MAKE_JOBS}
|
||||
cmake --install . --prefix ${COOKBOOK_STAGE}/usr
|
||||
"""
|
||||
```
|
||||
|
||||
#### Step 3: Port `qtdeclarative` (QML) (2-3 weeks)
|
||||
|
||||
```toml
|
||||
# recipes/wip/qt/qtdeclarative/recipe.toml
|
||||
[source]
|
||||
tar = "https://download.qt.io/official_releases/qt/6.8/6.8.2/submodules/qtdeclarative-everywhere-src-6.8.2.tar.xz"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
dependencies = ["qtbase"]
|
||||
|
||||
script = """
|
||||
# Same cmake pattern as qtwayland
|
||||
"""
|
||||
```
|
||||
|
||||
#### Step 4: Verify
|
||||
|
||||
```bash
|
||||
# Build and run a simple Qt Wayland app:
|
||||
cat > test.cpp << 'EOF'
|
||||
#include <QApplication>
|
||||
#include <QLabel>
|
||||
int main(int argc, char *argv[]) {
|
||||
QApplication app(argc, argv);
|
||||
QLabel label("Hello from Qt on Redox!");
|
||||
label.show();
|
||||
return app.exec();
|
||||
}
|
||||
EOF
|
||||
|
||||
x86_64-unknown-redox-g++ test.cpp -o test-qt -I/usr/include/qt6 -lQt6Widgets -lQt6Gui -lQt6Core
|
||||
# Run on compositor: WAYLAND_DISPLAY=wayland-0 ./test-qt
|
||||
```
|
||||
|
||||
**Milestone**: Window with "Hello from Qt on Redox!" appears on Wayland compositor.
|
||||
|
||||
---
|
||||
|
||||
### Phase KDE-B: KDE Frameworks (2-3 months)
|
||||
|
||||
**Goal**: KDE applications can be built and run.
|
||||
|
||||
#### KDE Frameworks Tier 1 (2-3 weeks)
|
||||
|
||||
These have minimal dependencies — just Qt and CMake.
|
||||
|
||||
| Framework | Purpose | Estimated Patches |
|
||||
|---|---|---|
|
||||
| `extra-cmake-modules` | CMake modules for KDE | None — pure CMake |
|
||||
| `kcoreaddons` | Core utilities | ~50 lines (process detection) |
|
||||
| `kconfig` | Configuration system | ~30 lines (filesystem paths) |
|
||||
| `kwidgetsaddons` | Extra Qt widgets | None — pure Qt |
|
||||
| `kitemmodels` | Model/view classes | None — pure Qt |
|
||||
| `kitemviews` | Item view classes | None — pure Qt |
|
||||
| `kcodecs` | String encoding | None — pure Qt |
|
||||
| `kguiaddons` | GUI utilities | None — pure Qt |
|
||||
|
||||
**Recipe pattern** (same for all Tier 1):
|
||||
```toml
|
||||
# recipes/wip/kde/kcoreaddons/recipe.toml
|
||||
[source]
|
||||
tar = "https://download.kde.org/stable/frameworks/6.10/kcoreaddons-6.10.0.tar.xz"
|
||||
patches = ["redox.patch"]
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
dependencies = ["qtbase", "extra-cmake-modules"]
|
||||
|
||||
script = """
|
||||
DYNAMIC_INIT
|
||||
mkdir -p build && cd build
|
||||
cmake .. \
|
||||
-DCMAKE_PREFIX_PATH=${COOKBOOK_SYSROOT}/usr \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DBUILD_TESTING=OFF \
|
||||
-DBUILD_QCH=OFF
|
||||
cmake --build . -j${COOKBOOK_MAKE_JOBS}
|
||||
cmake --install . --prefix ${COOKBOOK_STAGE}/usr
|
||||
"""
|
||||
```
|
||||
|
||||
#### KDE Frameworks Tier 2 (2-3 weeks)
|
||||
|
||||
| Framework | Dependencies | Notes |
|
||||
|---|---|---|
|
||||
| `ki18n` | `kcoreaddons`, gettext | Internationalization |
|
||||
| `kauth` | `kcoreaddons` | PolicyKit stub needed |
|
||||
| `kwindowsystem` | `qtbase` | Window management — needs Wayland backend |
|
||||
| `kcrash` | `kcoreaddons` | Crash handler — may need signal adjustments |
|
||||
| `karchive` | `qtbase`, zlib | Archive handling — should port cleanly |
|
||||
| `kiconthemes` | `kwidgetsaddons`, `karchive` | Icon loading |
|
||||
|
||||
#### KDE Frameworks Tier 3 (3-4 weeks) — Plasma essentials only
|
||||
|
||||
| Framework | Purpose | Key for Plasma? |
|
||||
|---|---|---|
|
||||
| `kio` | File I/O abstraction | **Yes** — file dialogs, I/O slaves |
|
||||
| `kservice` | Plugin/service management | **Yes** — app discovery |
|
||||
| `kxmlgui` | GUI framework | **Yes** — menus, toolbars |
|
||||
| `plasma-framework` | Plasma applets/containments | **Yes** — the desktop shell |
|
||||
| `knotifications` | Desktop notifications | **Yes** — notification system |
|
||||
| `kpackage` | Package/asset management | **Yes** — Plasma packages |
|
||||
| `kconfigwidgets` | Configuration widgets | **Yes** — settings UI |
|
||||
| `ktextwidgets` | Text editing widgets | Nice-to-have |
|
||||
| `kbookmarks` | Bookmark management | Nice-to-have |
|
||||
|
||||
**Total frameworks needed for minimal Plasma: ~25**
|
||||
|
||||
**Estimated total patch effort for all frameworks: ~1500-2000 lines**
|
||||
|
||||
---
|
||||
|
||||
### Phase KDE-C: Plasma Desktop (2-3 months)
|
||||
|
||||
**Goal**: Full KDE Plasma desktop session.
|
||||
|
||||
#### Step 1: Port KWin (4-6 weeks)
|
||||
|
||||
KWin is the hardest component. It needs:
|
||||
- DRM/KMS (for display control) → via our DRM scheme
|
||||
- libinput (for input) → via our evdevd
|
||||
- OpenGL ES 2.0+ (for effects) → via Mesa
|
||||
- Wayland (for compositor protocol) → via libwayland
|
||||
|
||||
```toml
|
||||
# recipes/wip/kde/kwin/recipe.toml
|
||||
[source]
|
||||
tar = "https://download.kde.org/stable/plasma/6.3.4/kwin-6.3.4.tar.xz"
|
||||
patches = ["redox.patch"]
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
dependencies = [
|
||||
"qtbase", "qtwayland", "qtdeclarative",
|
||||
"kcoreaddons", "kconfig", "kwindowsystem",
|
||||
"knotifications", "kxmlgui", "plasma-framework",
|
||||
"libwayland", "wayland-protocols",
|
||||
"mesa", "libdrm", "libinput", "seatd",
|
||||
"libxkbcommon",
|
||||
]
|
||||
|
||||
script = """
|
||||
DYNAMIC_INIT
|
||||
mkdir -p build && cd build
|
||||
cmake .. \
|
||||
-DCMAKE_PREFIX_PATH=${COOKBOOK_SYSROOT}/usr \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DBUILD_TESTING=OFF \
|
||||
-DKWIN_BUILD_SCREENLOCKING=OFF \
|
||||
-DKWIN_BUILD_TABBOX=OFF \
|
||||
-DKWIN_BUILD_EFFECTS=ON
|
||||
cmake --build . -j${COOKBOOK_MAKE_JOBS}
|
||||
cmake --install . --prefix ${COOKBOOK_STAGE}/usr
|
||||
"""
|
||||
```
|
||||
|
||||
**What `redox.patch` for KWin needs to fix**:
|
||||
|
||||
1. **DRM backend**: Replace `/dev/dri/card0` with `scheme:drm/card0`
|
||||
```
|
||||
src/backends/drm/drm_backend.cpp — open DRM scheme instead of device node
|
||||
src/backends/drm/drm_output.cpp — use scheme ioctl equivalents
|
||||
```
|
||||
|
||||
2. **libinput backend**: Should work via evdevd if `/dev/input/eventX` exists
|
||||
```
|
||||
src/backends/libinput/connection.cpp — may need path adjustments
|
||||
```
|
||||
|
||||
3. **EGL/OpenGL**: KWin uses EGL + OpenGL ES
|
||||
```
|
||||
src/libkwineglbackend.cpp — Mesa EGL should work (already ported)
|
||||
```
|
||||
|
||||
4. **Session management**: KWin expects logind. Need to stub or implement:
|
||||
```
|
||||
src/session.h/cpp — stub LogindIntegration, use seatd instead
|
||||
```
|
||||
|
||||
5. **udev**: KWin uses udev for device enumeration
|
||||
```
|
||||
src/udev.h/cpp — redirect to our udev-shim
|
||||
```
|
||||
|
||||
**Estimated KWin patches**: ~1000-1500 lines.
|
||||
|
||||
#### Step 2: Port `plasma-workspace` (2-3 weeks)
|
||||
|
||||
```toml
|
||||
# recipes/wip/kde/plasma-workspace/recipe.toml
|
||||
[source]
|
||||
tar = "https://download.kde.org/stable/plasma/6.3.4/plasma-workspace-6.3.4.tar.xz"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
dependencies = [
|
||||
# All KDE Frameworks above + kwin
|
||||
"kwin", "plasma-framework", "kio", "kservice", "knotifications",
|
||||
"kpackage", "kconfigwidgets",
|
||||
"qtbase", "qtwayland", "qtdeclarative",
|
||||
# System services
|
||||
"dbus",
|
||||
]
|
||||
```
|
||||
|
||||
**Key component**: `plasmashell` — the desktop shell. Creates panels, desktop containment,
|
||||
applet loader. Depends heavily on QML (qtdeclarative).
|
||||
|
||||
#### Step 3: Port `plasma-desktop` (1-2 weeks)
|
||||
|
||||
System settings, desktop containment configuration. Mostly Qt/QML.
|
||||
|
||||
#### Step 4: Create session config
|
||||
|
||||
```toml
|
||||
# config/kde.toml (new file)
|
||||
include = ["desktop.toml"]
|
||||
|
||||
[general]
|
||||
filesystem_size = 4096
|
||||
|
||||
[packages]
|
||||
# Qt
|
||||
qtbase = {}
|
||||
qtwayland = {}
|
||||
qtdeclarative = {}
|
||||
qtsvg = {}
|
||||
# KDE Frameworks (minimal set)
|
||||
extra-cmake-modules = {}
|
||||
kcoreaddons = {}
|
||||
kconfig = {}
|
||||
kwidgetsaddons = {}
|
||||
ki18n = {}
|
||||
kwindowsystem = {}
|
||||
kio = {}
|
||||
kservice = {}
|
||||
kxmlgui = {}
|
||||
knotifications = {}
|
||||
kpackage = {}
|
||||
plasma-framework = {}
|
||||
kconfigwidgets = {}
|
||||
# KDE Plasma
|
||||
kwin = {}
|
||||
plasma-workspace = {}
|
||||
plasma-desktop = {}
|
||||
kde-cli-tools = {}
|
||||
# Support
|
||||
dbus = {}
|
||||
mesa = {}
|
||||
libdrm = {}
|
||||
libinput = {}
|
||||
seatd = {}
|
||||
evdevd = {}
|
||||
drmd = {}
|
||||
|
||||
# Override init to launch KDE session
|
||||
[[files]]
|
||||
path = "/usr/lib/init.d/20_orbital"
|
||||
data = """
|
||||
requires_weak 10_net
|
||||
notify audiod
|
||||
nowait VT=3 orbital orbital-kde
|
||||
"""
|
||||
|
||||
[[files]]
|
||||
path = "/usr/bin/orbital-kde"
|
||||
mode = 0o755
|
||||
data = """
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
export DISPLAY=""
|
||||
export WAYLAND_DISPLAY=wayland-0
|
||||
export XDG_RUNTIME_DIR=/tmp/run/user/0
|
||||
export XDG_SESSION_TYPE=wayland
|
||||
export KDE_FULL_SESSION=true
|
||||
export XDG_CURRENT_DESKTOP=KDE
|
||||
|
||||
mkdir -p /tmp/run/user/0
|
||||
|
||||
# Start D-Bus
|
||||
dbus-daemon --system &
|
||||
|
||||
# Start D-Bus session
|
||||
eval $(dbus-launch --sh-syntax)
|
||||
|
||||
# Start KWin (Wayland compositor + window manager)
|
||||
kwin_wayland --replace &
|
||||
|
||||
# Start Plasma Shell
|
||||
sleep 2
|
||||
plasmashell &
|
||||
"""
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## KDE Applications (Build on 19 WIP Recipes)
|
||||
|
||||
These are already partially ported in `recipes/wip/kde/`:
|
||||
|
||||
| App | Status | Notes |
|
||||
|-----|--------|-------|
|
||||
| kde-dolphin | WIP recipe exists | File manager — needs kio |
|
||||
| kdenlive | WIP recipe exists | Video editor — needs MLT framework |
|
||||
| krita | WIP recipe exists | Painting — needs Qt + OpenGL |
|
||||
| kdevelop | WIP recipe exists | IDE — needs Qt + kio |
|
||||
| okteta | WIP recipe exists | Hex editor |
|
||||
| ktorrent | WIP recipe exists | BitTorrent client |
|
||||
| ark | WIP recipe exists | Archive manager |
|
||||
| kamoso | WIP recipe exists | Camera — needs PipeWire |
|
||||
| kpatience | WIP recipe exists | Card game |
|
||||
|
||||
Once Qt + KDE Frameworks are ported, these apps should compile with minimal patches.
|
||||
|
||||
---
|
||||
|
||||
## System Integration Points
|
||||
|
||||
### D-Bus (Already Working)
|
||||
D-Bus is ported and working in the X11 config. KDE uses D-Bus extensively.
|
||||
Already configured in `config/x11.toml`.
|
||||
|
||||
### Audio: PulseAudio PipeWire Shim Needed
|
||||
KDE expects PulseAudio or PipeWire for audio. Redox has its own `scheme:audio`.
|
||||
|
||||
**Option A**: Port PipeWire to Redox (large effort)
|
||||
**Option B**: Write a PulseAudio compatibility shim that translates to Redox audio scheme
|
||||
**Option C**: Use KDE without audio initially (just disable audio notifications)
|
||||
|
||||
### Service Management: D-Bus Service Files
|
||||
KDE services register via D-Bus `.service` files. Redox init starts services.
|
||||
Need a translation layer that:
|
||||
1. Reads `/usr/share/dbus-1/services/*.service` files
|
||||
2. Maps to Redox init scripts
|
||||
3. Responds to D-Bus StartServiceByName calls
|
||||
|
||||
### Network: KDE NetworkManager integration
|
||||
KDE uses NetworkManager for network configuration. Redox has `smolnetd`.
|
||||
|
||||
**Option A**: Port NetworkManager (massive effort, needs systemd)
|
||||
**Option B**: Write a NetworkManager D-Bus shim that talks to smolnetd
|
||||
**Option C**: Skip network configuration UI initially
|
||||
|
||||
---
|
||||
|
||||
## Timeline
|
||||
|
||||
| Phase | Duration | Milestone |
|
||||
|-------|----------|-----------|
|
||||
| Qt Foundation | 8-12 weeks | Qt app shows a window |
|
||||
| KDE Frameworks | 8-12 weeks | KDE app (kate) runs |
|
||||
| KWin + Plasma Shell | 6-8 weeks | KDE desktop visible |
|
||||
| KDE Apps | 4-6 weeks | Dolphin, Konsole, Kate working |
|
||||
| **Total** | **10-15 months** | Full KDE Plasma session |
|
||||
|
||||
**Critical insight**: The Qt Foundation phase is the highest-risk phase.
|
||||
If Qt compilation hits unexpected relibc gaps, the entire KDE timeline shifts.
|
||||
Mitigation: start Qt porting early, even before DRM/input is complete,
|
||||
using software rendering and Orbital backend as a test environment.
|
||||
@@ -0,0 +1,291 @@
|
||||
# 06 — Build System Setup Guide
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### System Requirements
|
||||
|
||||
- **OS**: Linux (Arch/Manjaro, Debian/Ubuntu, Fedora, Gentoo)
|
||||
- **Architecture**: x86_64 (primary), also supports aarch64, i586, riscv64gc
|
||||
- **RAM**: 4GB minimum, 8GB+ recommended
|
||||
- **Disk**: 20GB+ free space (full build with all recipes)
|
||||
- **Network**: Required for downloading sources and toolchain
|
||||
|
||||
### Install Build Dependencies
|
||||
|
||||
#### Arch / Manjaro
|
||||
|
||||
```bash
|
||||
sudo pacman -S --needed --noconfirm \
|
||||
autoconf automake bison cmake curl doxygen expat file flex fuse3 \
|
||||
gdb git gmp libjpeg-turbo libpng libtool m4 make meson nasm \
|
||||
ninja openssl patch patchelf perl pkgconf po4a protobuf python \
|
||||
python-mako rsync scons sdl12-compat syslinux texinfo unzip \
|
||||
wget xdg-utils zip zstd qemu-system-x86 qemu-system-arm qemu-system-riscv
|
||||
```
|
||||
|
||||
#### Debian / Ubuntu
|
||||
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install --assume-yes \
|
||||
ant autoconf automake bison build-essential cmake curl doxygen \
|
||||
expect file flex fuse3 g++ gdb-multiarch git libc6-dev-i386 \
|
||||
libfuse3-dev libgdk-pixbuf2.0-bin libglib2.0-dev-bin libgmp-dev \
|
||||
libhtml-parser-perl libjpeg-dev libmpfr-dev libsdl1.2-dev \
|
||||
libsdl2-ttf-dev llvm m4 make meson nasm ninja-build patch \
|
||||
patchelf perl pkg-config po4a protobuf-compiler python3 \
|
||||
python3-dev python3-mako rsync ruby scons texinfo unzip wget \
|
||||
xdg-utils xxd zip zstd qemu-system-x86 qemu-kvm
|
||||
```
|
||||
|
||||
#### Fedora
|
||||
|
||||
```bash
|
||||
sudo dnf install --assumeyes \
|
||||
@development-tools autoconf automake bison cmake curl doxygen \
|
||||
expat-devel file flex fuse3-devel gcc gcc-c++ gdb genisoimage \
|
||||
gettext-devel glibc-devel.i686 gmp-devel libjpeg-turbo-devel \
|
||||
libpng-devel libtool m4 make meson nasm ninja-build openssl \
|
||||
patch patchelf perl po4a protobuf-compiler python3-mako \
|
||||
SDL2_ttf-devel sdl12-compat-devel syslinux texinfo unzip vim \
|
||||
zip zstd qemu-system-x86 qemu-kvm
|
||||
```
|
||||
|
||||
### Install Rust and Cargo Tools
|
||||
|
||||
```bash
|
||||
# Install Rust via rustup
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
source "$HOME/.cargo/env"
|
||||
|
||||
# Install required cargo tools
|
||||
cargo install just cbindgen
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Native Build (No Container)
|
||||
|
||||
```bash
|
||||
# In the redox-master directory:
|
||||
echo 'PODMAN_BUILD?=0' > .config
|
||||
```
|
||||
|
||||
### Podman Build (Containerized, Default)
|
||||
|
||||
```bash
|
||||
# Default uses Podman — no configuration needed
|
||||
# Ensure Podman is installed:
|
||||
# Arch: sudo pacman -S podman
|
||||
# Debian: sudo apt-get install podman
|
||||
```
|
||||
|
||||
### Select Build Configuration
|
||||
|
||||
Available configs (in `config/`):
|
||||
|
||||
| Config | Description |
|
||||
|---|---|
|
||||
| `minimal` | Bare minimum bootable system |
|
||||
| `server` | Server-oriented (no GUI) |
|
||||
| `desktop-minimal` | Orbital + basic GUI apps |
|
||||
| `desktop` | COSMIC apps + installer |
|
||||
| `wayland` | Wayland compositor (experimental) |
|
||||
| `x11` | X.org + MATE desktop |
|
||||
| `demo` | Demo apps |
|
||||
|
||||
## Building
|
||||
|
||||
### Full Build (Desktop)
|
||||
|
||||
```bash
|
||||
make all
|
||||
```
|
||||
|
||||
This produces `build/x86_64/desktop/harddrive.img`.
|
||||
|
||||
### Build with Specific Config
|
||||
|
||||
```bash
|
||||
# Using build.sh wrapper:
|
||||
./build.sh -c wayland all # Wayland config
|
||||
./build.sh -c server all # Server config
|
||||
./build.sh -c x11 all # X11 config
|
||||
./build.sh -a aarch64 -c desktop all # ARM64 build
|
||||
```
|
||||
|
||||
### Build a Live ISO
|
||||
|
||||
```bash
|
||||
make live
|
||||
# Produces: build/x86_64/desktop/redox-live.iso
|
||||
```
|
||||
|
||||
### Rebuild After Changes
|
||||
|
||||
```bash
|
||||
make rebuild # Clean rebuild of filesystem image
|
||||
```
|
||||
|
||||
## Running
|
||||
|
||||
### QEMU (Recommended)
|
||||
|
||||
```bash
|
||||
# Desktop with Orbital GUI:
|
||||
make qemu
|
||||
|
||||
# With more RAM:
|
||||
make qemu QEMUFLAGS="-m 4G"
|
||||
|
||||
# Without GUI (serial console):
|
||||
make qemu QEMUFLAGS="-nographic"
|
||||
|
||||
# With network (port forwarding):
|
||||
make qemu QEMUFLAGS="-net nic -net user,hostfwd=tcp::8080-:80"
|
||||
```
|
||||
|
||||
### VirtualBox
|
||||
|
||||
```bash
|
||||
make virtualbox
|
||||
```
|
||||
|
||||
### Live USB
|
||||
|
||||
```bash
|
||||
# Write image to USB device (replace sdX with your device):
|
||||
sudo dd if=build/x86_64/desktop/harddrive.img of=/dev/sdX bs=4M status=progress
|
||||
```
|
||||
|
||||
## Building Specific Packages (Recipes)
|
||||
|
||||
### Build a Single Recipe
|
||||
|
||||
```bash
|
||||
# Using the repo tool:
|
||||
./target/release/repo cook recipes/libs/mesa
|
||||
./target/release/repo cook recipes/gui/orbital
|
||||
```
|
||||
|
||||
### Understanding Recipe Format
|
||||
|
||||
Each recipe is in `recipes/<category>/<name>/recipe.toml`:
|
||||
|
||||
```toml
|
||||
[source]
|
||||
git = "https://example.com/repo.git" # Git source
|
||||
# tar = "https://example.com/source.tar.gz" # Or tar source
|
||||
# branch = "main" # Git branch
|
||||
# rev = "abc123" # Or specific commit
|
||||
# patches = ["redox.patch"] # Patches to apply
|
||||
|
||||
[build]
|
||||
template = "cargo" # Build template: cargo, meson, cmake, make, custom
|
||||
dependencies = [
|
||||
"dep1", # Other recipe names
|
||||
"dep2",
|
||||
]
|
||||
|
||||
# For custom builds:
|
||||
script = """
|
||||
DYNAMIC_INIT
|
||||
cookbook_cargo --release
|
||||
mkdir -p ${COOKBOOK_STAGE}/usr/bin
|
||||
cp target/release/myapp ${COOKBOOK_STAGE}/usr/bin/
|
||||
"""
|
||||
```
|
||||
|
||||
### Build Templates
|
||||
|
||||
| Template | Description |
|
||||
|---|---|
|
||||
| `cargo` | Rust project (cargo build) |
|
||||
| `meson` | Meson build system |
|
||||
| `cmake` | CMake build system |
|
||||
| `make` | GNU Make |
|
||||
| `custom` | Custom script in `script` field |
|
||||
|
||||
## Key Build Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|---|---|---|
|
||||
| `ARCH` | Host arch | Target architecture (x86_64, aarch64, i586, riscv64gc) |
|
||||
| `CONFIG_NAME` | `desktop` | Build config name |
|
||||
| `PODMAN_BUILD` | `1` | Use Podman container |
|
||||
| `PREFIX_BINARY` | `1` | Use prebuilt toolchain (faster) |
|
||||
| `REPO_BINARY` | `0` | Use prebuilt packages (faster, no compilation) |
|
||||
| `REPO_NONSTOP` | `0` | Continue on build errors |
|
||||
| `REPO_OFFLINE` | `0` | Don't update source repos |
|
||||
|
||||
### Environment Variables for Recipes
|
||||
|
||||
Inside recipe scripts, these are available:
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
| `COOKBOOK_SOURCE` | Path to extracted source |
|
||||
| `COOKBOOK_STAGE` | Path to staging directory (install target) |
|
||||
| `COOKBOOK_SYSROOT` | Path to sysroot with deps |
|
||||
| `COOKBOOK_TARGET` | Target triple (e.g., x86_64-unknown-redox) |
|
||||
| `COOKBOOK_CARGO` | Cargo command with correct target |
|
||||
| `COOKBOOK_MAKE` | Make command with correct flags |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Toolchain Download Fails
|
||||
|
||||
```bash
|
||||
# Clean and retry:
|
||||
rm -rf prefix/
|
||||
make prefix # Re-download toolchain
|
||||
```
|
||||
|
||||
### Build Errors in Specific Recipes
|
||||
|
||||
```bash
|
||||
# Rebuild a specific recipe:
|
||||
./target/release/repo cook recipes/<category>/<name>
|
||||
|
||||
# Skip failing recipes:
|
||||
make all REPO_NONSTOP=1
|
||||
```
|
||||
|
||||
### SELinux Issues (Fedora/RHEL)
|
||||
|
||||
```bash
|
||||
make all USE_SELINUX=0
|
||||
```
|
||||
|
||||
### Out of Disk Space
|
||||
|
||||
```bash
|
||||
# Clean everything:
|
||||
make clean
|
||||
|
||||
# Clean only fetched sources:
|
||||
make distclean
|
||||
```
|
||||
|
||||
## Directory Layout After Build
|
||||
|
||||
```
|
||||
redox-master/
|
||||
├── build/
|
||||
│ └── x86_64/
|
||||
│ └── desktop/
|
||||
│ ├── harddrive.img # Bootable disk image
|
||||
│ ├── redox-live.iso # Live CD ISO
|
||||
│ ├── filesystem/ # Mounted filesystem (during build)
|
||||
│ └── repo.tag # Build completion marker
|
||||
├── prefix/
|
||||
│ └── x86_64-unknown-redox/
|
||||
│ └── clang-install/ # Cross-compilation toolchain
|
||||
├── repo/
|
||||
│ └── *.pkgar # Built packages
|
||||
├── source/
|
||||
│ └── <recipe-name>/ # Extracted recipe sources
|
||||
└── target/
|
||||
└── release/
|
||||
└── repo # Build system binary
|
||||
```
|
||||
@@ -0,0 +1,46 @@
|
||||
# DOCS — ARCHITECTURE & INTEGRATION DOCUMENTATION
|
||||
|
||||
7 comprehensive technical documents covering Redox architecture, gap analysis, and integration paths.
|
||||
For AMD-first integration, see `local/docs/AMD-FIRST-INTEGRATION.md`.
|
||||
|
||||
## STRUCTURE
|
||||
|
||||
```
|
||||
docs/
|
||||
├── 01-REDOX-ARCHITECTURE.md # Microkernel design, scheme system, driver model, Orbital
|
||||
├── 02-GAP-ANALYSIS.md # Dependency chain, gap matrix, milestone roadmap
|
||||
├── 03-WAYLAND-ON-REDOX.md # Wayland implementation path (5 steps, ~26 weeks)
|
||||
├── 04-LINUX-DRIVER-COMPAT.md # LinuxKPI-style driver compat layer (3 crates)
|
||||
├── 05-KDE-PLASMA-ON-REDOX.md # KDE Plasma port (3 phases, ~38 weeks)
|
||||
├── 06-BUILD-SYSTEM-SETUP.md # Build prerequisites, config, commands, troubleshooting
|
||||
└── README.md # Index of all docs
|
||||
```
|
||||
|
||||
## WHERE TO LOOK
|
||||
|
||||
| Question | Document | Key Section |
|
||||
|----------|----------|-------------|
|
||||
| How does the kernel work? | 01 | §1 Microkernel, §2 Scheme System |
|
||||
| How do drivers access hardware? | 01 | §3 Driver Model, §6 Build System |
|
||||
| What's missing for Wayland? | 02 | Layer 1-4 gap matrix |
|
||||
| How to fix POSIX gaps? | 03 | §1 (signalfd, timerfd, eventfd implementations) |
|
||||
| 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) |
|
||||
| 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 |
|
||||
| How to port Qt? | 05 | Phase KDE-A (qtbase patches, ~500-800 lines) |
|
||||
| How to port KDE Frameworks? | 05 | Phase KDE-B (25 frameworks, tiered approach) |
|
||||
| How to port KDE Plasma? | 05 | Phase KDE-C (KWin, Plasma Shell, session config) |
|
||||
| How to set up the build? | 06 | Prerequisites per distro, build commands |
|
||||
| What's the milestone timeline? | 02 | M1-M8 roadmap, parallel execution plan |
|
||||
|
||||
## KEY NUMBERS
|
||||
|
||||
- **POSIX gaps**: 7 APIs blocking libwayland (signalfd, timerfd, eventfd, F_DUPFD_CLOEXEC, MSG_CMSG_CLOEXEC, MSG_NOSIGNAL, open_memstream)
|
||||
- **Wayland recipes**: 21 in `recipes/wip/wayland/`
|
||||
- **KDE apps**: 9 WIP recipes in `recipes/wip/kde/`
|
||||
- **To Wayland compositor**: ~26 weeks (2 developers)
|
||||
- **To KDE Plasma**: ~38 weeks (2 developers)
|
||||
- **To Linux driver compat**: ~24 weeks (parallel track)
|
||||
@@ -0,0 +1,61 @@
|
||||
# Redox OS Fork — Wayland, KDE & Linux Driver Compatibility
|
||||
|
||||
Technical documentation for forking Redox OS to include Wayland protocol support,
|
||||
KDE Plasma desktop environment, and a Linux driver compatibility layer.
|
||||
|
||||
## Documents
|
||||
|
||||
| # | Document | Description |
|
||||
|---|----------|-------------|
|
||||
| 01 | [Architecture Overview](01-REDOX-ARCHITECTURE.md) | Redox OS internals: microkernel, scheme system, driver model, display stack |
|
||||
| 02 | [Gap Analysis & Roadmap](02-GAP-ANALYSIS.md) | What's missing between current Redox and our Wayland/KDE/driver-compat goals |
|
||||
| 03 | [Wayland on Redox](03-WAYLAND-ON-REDOX.md) | Deep-dive into Wayland protocol requirements and current porting status |
|
||||
| 04 | [Linux Driver Compatibility Layer](04-LINUX-DRIVER-COMPAT.md) | Design for a FreeBSD LinuxKPI-style driver compatibility shim |
|
||||
| 05 | [KDE Plasma on Redox](05-KDE-PLASMA-ON-REDOX.md) | Feasibility study and implementation plan for KDE Plasma |
|
||||
| 06 | [Build System Setup](06-BUILD-SYSTEM-SETUP.md) | How to build Redox from this repository |
|
||||
|
||||
## Current State Summary (as of Redox 0.9.0)
|
||||
|
||||
- **Display server**: Orbital (custom, scheme-based) — works
|
||||
- **Wayland**: Experimental, WIP. Smallvil (Smithay) and cosmic-comp partially working.
|
||||
libwayland patched with shimmed-out `signalfd`, `timerfd`, `eventfd`.
|
||||
- **X11**: Working via X.org dummy driver inside Orbital.
|
||||
- **Mesa**: Software-rendered only (LLVMpipe/OSMesa). No GPU acceleration.
|
||||
- **GPU drivers**: VESA framebuffer + VirtIO GPU only. Experimental Intel modesetting.
|
||||
- **KDE**: 19 app recipes in WIP, no KDE Plasma infrastructure.
|
||||
- **Linux driver compat**: None. Redox explicitly chose source-level porting over binary compat.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# 1. Install dependencies (Arch/Manjaro)
|
||||
sudo pacman -S --needed --noconfirm gdb meson nasm patchelf python-mako \
|
||||
doxygen expat file fuse3 gmp libjpeg-turbo libpng po4a scons \
|
||||
sdl12-compat syslinux texinfo xdg-utils zstd
|
||||
|
||||
# 2. Install Rust + tools
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
source "$HOME/.cargo/env"
|
||||
cargo install just cbindgen
|
||||
|
||||
# 3. Configure for native build (no Podman)
|
||||
echo 'PODMAN_BUILD?=0' > .config
|
||||
|
||||
# 4. Build (downloads cross-toolchain, then compiles)
|
||||
make all
|
||||
|
||||
# 5. Run in QEMU
|
||||
make qemu
|
||||
```
|
||||
|
||||
## Key Repositories
|
||||
|
||||
| Repo | Purpose | URL |
|
||||
|------|---------|-----|
|
||||
| Kernel | Microkernel | https://gitlab.redox-os.org/redox-os/kernel |
|
||||
| Base | Drivers + system components | https://gitlab.redox-os.org/redox-os/base |
|
||||
| relibc | C library (Rust) | https://gitlab.redox-os.org/redox-os/relibc |
|
||||
| Orbital | Display server + WM | https://gitlab.redox-os.org/redox-os/orbital |
|
||||
| RedoxFS | Default filesystem | https://gitlab.redox-os.org/redox-os/redoxfs |
|
||||
| libredox | System library | https://gitlab.redox-os.org/redox-os/libredox |
|
||||
| This repo | Build system | https://gitlab.redox-os.org/redox-os/redox |
|
||||
Reference in New Issue
Block a user