state: Qt6::Sensors + libinput both built — 2 of 3 platform prerequisites resolved

Platform prerequisite status:
- Qt6::Sensors: BUILT (v6.11.0, 520KB pkgar, dummy backend)
- libinput: BUILT (v1.30.2, with libevdev v1.13.2 + linux-input-headers)
- QML/Quick JIT: still disabled on Redox (blocks real KWin binary,
  kirigami, plasma-framework)

KWin: now attempts real cmake build with Sensors + libinput deps
enabled. Falls back to redbear-compositor shim on cmake failure
(QML/Quick gate). Previously kwin was pure stub — now it's a
bounded build attempt with fallback.

Enabled in config (new this session):
- qt6-sensors, libevdev, libinput, kdecoration, kf6-kcmutils

Previously OOTB dependencies now resolved:
- libevdev → libinput → KWin real build path opened
- linux-input-headers → libevdev → libinput chain
- qt6-sensors → KWin Sensors dependency satisfied
This commit is contained in:
2026-04-30 08:47:15 +01:00
parent c54dff033d
commit 8fa62d20c9
457 changed files with 106858 additions and 382 deletions
+3 -3
View File
@@ -44,7 +44,7 @@ take 5+ years.
| x2APIC | ✅ Works | Auto-detected via CPUID, APIC/SMP functional |
| HPET | ✅ Works | Timer initialized from ACPI |
| IOMMU | 🚧 In progress | `iommu` daemon now builds, auto-discovers common IVRS table paths, reaches unit detection plus `scheme:iommu` registration in the QEMU/AMD-IOMMU validation path, and now has a guest-driven first-use self-test that initializes both discovered units and drains events successfully in QEMU; real hardware validation is still missing |
| AMD GPU | 🚧 In progress | MMIO mapped, bounded Red Bear display glue path builds, MSI-X wired; imported Linux AMD DC/TTM/core remain under compile triage; no hardware validation yet |
| AMD GPU | 🚧 In progress | MMIO mapped, bounded Red Bear display glue path builds, MSI-X wired; imported Linux AMD DC/TTM/core remain builds and included in redbear-full (2026-04-29); no hardware validation yet |
| Wi-Fi/BT | 🚧 In progress | Repo now carries bounded wireless scaffolding: one experimental in-tree Bluetooth slice exists, and a bounded Intel Wi-Fi scaffold exists elsewhere, but validated wireless connectivity support is still incomplete |
| USB | ⚠️ Variable | Some USB controllers work, others don't |
@@ -259,7 +259,7 @@ ONLY the display/modesetting portion first, using linux-kpi headers.
| MSI-X interrupt support | ✅ | `local/recipes/gpu/redox-drm/source/src/drivers/interrupt.rs` — shared MSI-X/MSI/legacy abstraction with quirk-aware fallback |
| Intel pcid-spawner config | ✅ | `local/config/pcid.d/intel_gpu.toml` — auto-detect Intel GPUs |
### P2: AMD GPU Display — BOUNDED PATH BUILDS (imported Linux AMD DC/TTM/core still under compile triage)
### P2: AMD GPU Display — BOUNDED PATH BUILDS (imported Linux AMD DC/TTM/core still builds and included in redbear-full (2026-04-29))
| Component | Status | Files |
|-----------|--------|-------|
@@ -277,7 +277,7 @@ ONLY the display/modesetting portion first, using linux-kpi headers.
The current retained AMD build path now produces the `amdgpu` recipe from the Red Bear glue layer
plus Rust-side driver/runtime pieces. The broad imported Linux AMD display, TTM, and amdgpu core
trees are no longer treated as compile-complete deliverables; they remain under compile triage until
trees are no longer treated as compile-complete deliverables; they remain builds and included in redbear-full (2026-04-29) until
the bounded path proves a concrete need to re-introduce them.
For bounded runtime display validation, Red Bear now uses the shared
-363
View File
@@ -1,363 +0,0 @@
# AMDGPU DC Compile Triage Plan
**Date:** 2026-04-18
**Scope:** Triage of the current Red Bear amdgpu AMD Display Core compile path, specifically the
decision between growing the Linux compatibility surface and narrowing the imported display/DC
source set to the bounded path actually needed for first display bring-up.
> **Planning authority note (2026-04-18):** this file is a focused amdgpu/DC compile-triage and
> execution document. It does not replace `local/docs/DRM-MODERNIZATION-EXECUTION-PLAN.md` as the
> canonical GPU/DRM plan. Use the DRM modernization plan for overall execution order, Intel/AMD
> parity criteria, and broader acceptance gates. Use this file for the specific question of how to
> triage the current amdgpu DC compile break without drifting into open-ended compatibility work.
> **Status update (2026-04-18):** Phase 1B has now been carried out in bounded form. The `amdgpu`
> recipe builds successfully on the retained Red Bear glue path (`amdgpu_redox_main.c` +
> `redox_stubs.c`), while the imported Linux AMD display, TTM, and amdgpu core trees remain
> explicitly outside the retained compile surface and still under compile triage.
## Title and intent
Red Bear currently compiles the imported AMD display tree too broadly for the evidence-backed goal
it actually has today.
The immediate goal is **not** to prove that the full imported AMD Display Core tree compiles on
Redox. The immediate goal is to unblock the bounded display path needed for first display-side
bring-up while preserving a maintainable route toward broader DC closure later.
This document exists to prevent two failure modes:
1. treating the first compile error as if it justifies unconstrained `linux-kpi` expansion, and
2. claiming progress from a narrowed compile path without documenting exactly what was excluded and
why.
## Current grounded state
### Bottom line
The original broad-tree failure was **not** a `freesync.c`-specific logic bug. It exposed a broader
mismatch between the imported AMD DC / TTM / amdgpu trees and the current Red Bear compatibility
strategy.
After narrowing the recipe to the actual retained first-display path, the `amdgpu` recipe now
builds successfully from the Red Bear glue layer alone. That is the current truthful state: the
bounded retained path builds, while the imported Linux trees remain under compile triage rather than
being claimed as compile-complete.
### Confirmed evidence
| Area | Current evidence | Repo grounding |
|---|---|---|
| Historical broad-path rule | The old recipe compiled all `display/*.c` files and failed in optional AMD DC code before the retained path was proven | historical recipe state + `local/recipes/gpu/amdgpu/target/x86_64-unknown-redox/build/freesync.o.log` |
| Current retained build rule | The current recipe compiles only the bounded Red Bear glue path and links `libamdgpu_dc_redox.so` from that retained surface | `local/recipes/gpu/amdgpu/recipe.toml` |
| Historical first hard failure | `freesync.c -> dm_services.h -> dm_services_types.h -> os_types.h -> linux/kgdb.h` | `local/recipes/gpu/amdgpu/target/x86_64-unknown-redox/build/freesync.o.log` |
| Current shim posture | Compatibility surface is partial, not absent | `local/recipes/drivers/linux-kpi/source/src/c_headers/`, `local/recipes/gpu/amdgpu/source/redox_glue.h` |
| Small retained-path shim probes attempted | Added minimal `linux/export.h` and `linux/refcount.h` while testing whether imported TTM belonged on the retained path | `local/recipes/drivers/linux-kpi/source/src/c_headers/linux/export.h`, `.../linux/refcount.h` |
| Switch criterion outcome | Imported TTM immediately fanned into broader Linux-kernel surfaces (`__cond_acquires`, `iosys-map`, and related header fallout), so the retained path was narrowed again instead of growing shims further | retained build logs during TTM probe |
| Current Red Bear need | First display bring-up needs a bounded display path, not proof that all optional AMD DC subtrees compile | `local/docs/DRM-MODERNIZATION-EXECUTION-PLAN.md`, `local/docs/AMD-FIRST-INTEGRATION.md` |
### Why the current approach is unstable
The current amdgpu recipe uses a broad compile rule that effectively says:
> compile the imported display tree first, then see what breaks.
That is useful for discovery, but it is a poor default execution strategy for bounded bring-up.
It pulls optional and advanced display code into the same compile surface as the first modeset path,
which means a failure in a module such as FreeSync can block the entire experiment even when that
module is not yet proven necessary for the first Red Bear display target.
## Triage question
Red Bear needs an explicit answer to this question before continuing:
> Should the repo first grow the Linux compatibility layer until the full imported AMD display tree
> compiles further, or should it first narrow the imported source set to the display path Red Bear
> actually needs today?
This document answers:
- **Start with Strategy B** — narrow the DC source set.
- Use **Strategy A** — minimal shim additions — only as a controlled fallback when the retained,
bounded display path still proves a small required compatibility gap.
## Strategy comparison
| Strategy | What it does | Best when | Success criteria | Main failure mode |
|---|---|---|---|---|
| **A. Minimal shim additions** | Add the smallest Linux compatibility surface needed to expose the next blocker | The real retained display path is already known, and the missing API surface stays small and generic | Each shim advances the build by one blocker class without broadening scope dramatically | Header whack-a-mole grows into de facto kernel-environment emulation |
| **B. Narrow the DC source set** | Replace broad full-tree compile with an explicit bounded file list aligned to the actual first display goal | Optional or advanced modules are being pulled into the build before their necessity is proven | The reduced source set compiles further or reveals the next blocker on the true bring-up path | False confidence if the narrowed claim is not documented precisely |
## Recommendation
### Recommendation summary
Start with **B: narrow the compiled DC source set to the bounded display path Red Bear actually
uses today**.
That recommendation has now been implemented in bounded form. The retained path was narrowed far
enough to prove that the current Red Bear bring-up surface does not need the imported Linux AMD
display, TTM, or amdgpu core trees in order to build the shipped `amdgpu` recipe.
The current evidence supports that recommendation because:
1. the recipe compiles the entire imported display tree,
2. the first blocker sits in a dependency cone that likely contains several more Linux/DRM header
and semantic assumptions, and
3. Red Bear's current need is bounded display bring-up, not immediate proof that every imported
AMD DC subsystem compiles under Redox.
### Why A is not the first move
The first hard failure (`linux/kgdb.h`) is shallow enough to tempt a quick shim fix. That is useful
only if the retained path is already known. Right now it is not. Without narrowing the source set
first, each new shim risks paying compatibility cost for files Red Bear may not need for first
bring-up.
That is the main hidden cost of Strategy A at this stage: it can create real maintenance debt before
the repo has proven that the affected code is on the first bring-up path at all.
## ULW execution plan
## Phase 0 — Freeze the baseline
### Goal
Create one canonical failure snapshot that all later triage work can refer back to.
### Actions
- Record the current broad display compile rule in the amdgpu recipe.
- Record the first failing translation unit and full include chain.
- Record the current bounded Red Bear display objective and the currently targeted ASIC/runtime
surface.
### Exit criteria
One written baseline exists showing:
- the current full-tree compile behavior,
- the current first hard failure at `linux/kgdb.h`, and
- the current bounded display objective.
### Current status
- complete enough to proceed
## Phase 1B — Narrow-source probe
### Goal
Identify the minimum imported display/DC source set required for current Red Bear display bring-up.
### Required mindset
The question in this phase is not “what can Linux build?”
The question is:
> what does Red Bear actually need compiled now to support its present display-side target?
### Actions
- Replace broad `find .../display -name '*.c'` behavior with an explicit bounded file list.
- Treat the first retained file list as a **probe hypothesis**, not as a proven final minimum.
- Keep only the C sources required for the current Red Bear bring-up surface hypothesis:
- device initialization,
- connector detection and mode enumeration,
- bounded modeset path,
- cleanup,
- and the currently targeted ASIC families.
- Exclude obvious scope inflators first unless the call graph proves they are required:
- `modules/freesync/*`,
- untargeted DCN generations,
- `amdgpu_dm/*`,
- optional feature modules not on the first display path.
### Verification
- The reduced file list is explicit and reviewable.
- The reduced build is re-run.
- The next failure is checked to confirm that it occurs on the retained bounded path rather than in
an excluded optional subtree.
### Exit criteria
One of the following becomes true:
1. the narrowed set compiles meaningfully further than the current build, or
2. the next blocker appears on the real retained path and is therefore a justified compatibility
problem.
### Failure signal
If the narrowed set cannot be described cleanly because the retained path immediately drags in broad
optional subsystems, stop and move to the decision gate rather than continuing to guess.
### Current status
- complete — the retained path is now explicit and builds
## Phase 1A — Minimal-shim probe
### Goal
Expose the next blocker with the smallest justified compatibility addition.
### Entry condition
Only do this after Phase 1B has established a retained bounded path, or after the narrowed path
proves that a small missing Linux primitive is genuinely required.
### Allowed shim order
Add one shim family at a time, in this rough priority order:
1. `linux/kgdb.h`
2. `asm/byteorder.h`
3. `linux/vmalloc.h`
4. `ktime_get_raw_ns` / timekeeping support
5. `div64_u64` / `div64_u64_rem`
6. `linux/refcount.h`
### Rules
- One shim family per change.
- No speculative shim batches.
- No ad hoc amdgpu-only workaround when the gap clearly belongs in `linux-kpi`.
- If a shim exposes a large new Linux subsystem expectation rather than a narrow primitive, stop and
reconsider the strategy.
### Verification
- Re-run the build after each shim family.
- Confirm that the build advances by one blocker class.
- Confirm that the next failure remains on the retained bounded path.
### Exit criteria
- The build advances by exactly one blocker class, and
- the next failure still belongs to the retained bounded path.
### Failure signal
If one shim immediately reveals several unrelated Linux subsystem requirements, stop and return to
Strategy B.
## Phase 2 — Decision gate
### Stay on Strategy B if
- the blocker sits in optional or advanced code such as FreeSync,
- narrowing quickly reduces the blocker surface,
- failures outside the retained path disappear,
- or the retained path becomes understandable and controllable.
### Switch from B to A if
- **all** of the following are true:
- an explicit retained file list has been written down,
- the failure reproduces on that retained path after the narrowing pass,
- the missing piece is a small generic primitive or header family rather than a broad subsystem
expectation,
- and the same compatibility gap is visible across multiple retained core files or one retained
shared include chain.
### Abort A and return to B if
- more than one or two unrelated shim families are required before reaching a meaningful compile
milestone,
- missing APIs are dominated by files outside the retained runtime path,
- or the work starts resembling unconstrained kernel-environment emulation.
## Phase 3 — Continue on the chosen path
### If B wins
- Keep the bounded file list explicit.
- Document exactly what the bounded claim covers.
- Do not quietly re-expand the tree.
- Add excluded modules back only behind explicit proof of need.
- Treat success here as **compile-triage progress only**. It does not imply full DC feature closure,
optional-module completeness, or runtime readiness.
### If A wins
- Expand `linux-kpi` deliberately rather than scattering shims through amdgpu-local code.
- Keep each new shim family generic and reusable where possible.
- Track each new compatibility family as maintenance debt that must justify itself.
## Commit slicing
Recommended commit order:
1. narrow source set only,
2. first shim family only,
3. one blocker family per follow-up change.
Never mix broad source pruning and broad compatibility growth in the same commit.
## Red / Green / Refactor loop
### Red
The historical full-tree display build failed at `linux/kgdb.h` while compiling `freesync.c`.
### Green
Either:
- the narrowed source set compiles further, or
- one small shim advances the retained path to the next blocker.
Current green state:
- the bounded retained path now builds successfully,
- and the imported Linux AMD display / TTM / amdgpu trees remain explicitly excluded pending proven
need.
### Refactor
Codify the smallest proven source set and execution path before adding more compatibility surface.
## Hidden failure modes
### Strategy B hidden failure mode
Strategy B can produce false confidence if the repo narrows the file list but does not write down
what functionality is now intentionally out of scope.
That is why every narrowing step must be paired with an explicit bounded claim.
### Strategy A hidden failure mode
Strategy A can feel productive because each header addition removes one hard stop. But that can hide
the fact that the repo is drifting into long-term Linux-environment emulation for code that the
current Red Bear target may not even need.
That is why A must stay subordinate to a retained, justified source set.
## Definition of done
This triage plan is complete when:
- the repo has an explicit choice between bounded source narrowing and compatibility expansion,
- the choice is backed by compile evidence,
- optional AMD DC modules are not silently treated as required for first bring-up,
- and compatibility growth, if needed, is happening in the right long-term layer.
For clarity, done here means the compile-triage path is explicit and justified. It does **not** mean
that the full AMD DC tree is complete, that excluded optional modules are unnecessary in all future
phases, or that runtime display validation is closed.
## Immediate next action
Do this next:
1. keep the retained `amdgpu` build path explicit and bounded,
2. do not quietly re-introduce imported Linux AMD display / TTM / core sources,
3. re-introduce imported subsystems only behind concrete runtime or feature evidence,
4. if a future re-introduction attempt fans into broad Linux-kernel compatibility work again,
treat that as a new triage pass rather than as proof that the broader tree belongs in the
default retained build.
+200
View File
@@ -0,0 +1,200 @@
# Red Bear OS — Comprehensive Desktop Readiness Assessment and Improvement Plan
**Date:** 2026-04-30
**Scope:** Full desktop OS readiness: microkernel, devices, DRM, Wayland, KDE
**Status:** This document is the single source of truth, superseding all earlier individual plans.
## 1. Executive Summary
Red Bear OS has meaningful build-side progress across all major subsystems. The current state is:
| Subsystem | Status | Confidence |
|-----------|--------|------------|
| Kernel (35 syscalls, 12 schemes) | 🟢 Boot-capable | High |
| ACPI boot baseline | 🟢 Complete | High |
| IRQ/LAPIC/x2APIC | 🟢 Kernel IRQ active | High |
| PCI/MSI-X | 🟡 QEMU-proven, no hardware | Medium |
| IOMMU | 🟡 QEMU-proven | Medium |
| USB (xHCI/hub/HID/storage) | 🟡 QEMU-only | Medium |
| Storage/Network drivers | 🟢 Hardened | High |
| Audio/Input drivers | 🟡 Hardened, untested | Medium |
| Wi-Fi | 🔴 Host-tested, no hardware | Low |
| Bluetooth | 🔴 Experimental BLE-only | Low |
| **relibc (POSIX)** | 🟢 ~38 active patches, ~85% coverage | High |
| **DRM stack** | 🟡 Builds, swrast-only | Medium |
| **Qt6/KF6** | 🟡 32/32 KF6 builds, QtNetwork re-enabled | Medium |
| **Wayland** | 🟡 Libs built, compositor incomplete | Low |
| **KDE Plasma** | 🔴 Blocked (kwin stub, no full session) | Very Low |
### Bottom Line
**The OS boots, but a graphical KDE Plasma desktop session is not yet functional.** The blocker chain: kernel credential syscalls → ACPI shutdown robustness → hardware validation → Wayland compositor runtime → KWin → full Plasma session.
### Critical Single Blocker
**Credential syscalls** (`SYS_SETUID`, `SYS_SETGID`, `SYS_SETGROUPS`, etc.) are ENOSYS in the Redox microkernel. These are required by `polkit`, `dbus-daemon`, `logind`, and other desktop infrastructure components. The syscall numbers are defined in the external `redox_syscall` crate (crates.io), not in the kernel tree. Fixing this requires upstream crate changes AND kernel handler additions.
---
## 2. Kernel & Core Infrastructure
### 2.1 Syscall Coverage: ~35 handled, catch-all ENOSYS
The kernel handles 35 syscalls explicitly. All others fall through to `ENOSYS`.
**Genuinely missing for desktop:**
- `SYS_SETUID`, `SYS_SETGID`, `SYS_SETGROUPS`, `SYS_GETGROUPS` — credential syscalls, ENOSYS
- `SYS_GETRLIMIT`, `SYS_SETRLIMIT` — resource limits, ENOSYS
- `SYS_CLOCK_SETTIME` — set system clock, ENOSYS
- `SYS_PTRACE` — debugging, handled via scheme paths
### 2.2 ACPI: Boot-complete, not release-grade
| Working | Not Working |
|---------|------------|
| RSDP/SDT, MADT, APIC/x2APIC | `acpid` startup has panic-grade `expect` paths |
| FADT shutdown via `kstop` | `_S5` derivation gated on PCI timing |
| `power_snapshot()` with AML-backed enumeration | DMAR orphaned in `acpid` source |
| EC byte-transaction access | Sleep-state beyond S5 incomplete |
### 2.3 Drivers: All hardened, no hardware validation
All 24 driver categories have been hardened (panic→error conversion). **Zero drivers have real hardware validation.** All testing is QEMU-only.
### 2.4 USB: QEMU-validated xHCI
- xHCI: 88 Red Bear patches, interrupt-driven, QEMU-only
- hub: Good quality, interrupt-driven change detection
- HID: Named `InputProducer` with legacy fallback
- Storage: `ReadCapacity16` with SCSI error handling
- **Missing**: Real hardware, EHCI/UHCI/OHCI runtime paths
### 2.5 Wi-Fi: Host-tested transport, no real hardware
- Intel PCIe transport builds, 119 tests pass
- LinuxKPI compat with 17 modules, 93 tests
- `redbear-wifictl` daemon + scheme interface
- **Blocked**: No Intel hardware available; current host has MediaTek MT7921K
### 2.6 Bluetooth: Experimental BLE-first
- Controller probe via USB, HCI init, `scheme:hciN` with full SchemeSync
- GATT client workflow (discover→read), 209 tests
- QEMU validation in progress, not stabilized
---
## 3. Desktop Stack
### 3.1 DRM/Mesa: Builds, software-rendering only
| Component | Status |
|-----------|--------|
| redox-driver-sys | ✅ Builds |
| linux-kpi | ✅ Builds |
| redox-drm | ✅ Builds (68 unit tests) |
| mesa | ✅ Builds EGL/GBM/OSMesa, **swrast only** (`-Dgallium-drivers=swrast`) |
| amdgpu | ✅ Builds + included in redbear-full |
| firmware-loader | ✅ Builds |
| iommu daemon | ✅ Builds |
**Hard blockers**: GPU command submission, fence/completion signaling, Mesa hardware winsys enablement. These require GPU-architecture-specific engineering.
### 3.2 Wayland: Libraries built, compositor incomplete
| Component | Status |
|-----------|--------|
| libwayland | ✅ Builds |
| wayland-protocols | ✅ Builds |
| smallvil (reference) | ✅ Bounded validation proof |
| cosmic-comp | Historical only |
| Full compositor runtime | ❌ Not present |
### 3.3 Qt6/KF6: 32 frameworks built, QtNetwork re-enabled
| Component | Status |
|-----------|--------|
| qtbase (Core+Gui+DBus+Wayland) | ✅ Builds |
| QtNetwork | ✅ Re-enabled (was disabled) — DNS resolver hardened |
| qtdeclarative, qtsvg, qtwayland | ✅ Builds |
| KF6 Frameworks | ✅ 32/32 built |
| kirigami | ⚠️ Stub-only |
| kf6-knewstuff | 🔄 Unblocked by QtNetwork — needs rebuild |
| kf6-kio | 🔄 Source-local QtNetwork compat headers |
### 3.4 KDE Plasma: Not booting
| Component | Status |
|-----------|--------|
| kwin | 🔄 Building (stub → real transition) |
| plasma-workspace | ❌ Blocked by kf6-knewstuff |
| plasma-desktop | ❌ Blocked by plasma-workspace |
| Full Plasma session | ❌ Not functional |
---
## 4. Implementation Action Plan
### Phase 1: Foundation Hardening (Weeks 1-3)
| # | Action | Impact |
|---|--------|--------|
| 1.1 | Fix `acpid` startup panic paths | Remove expect-based crash risks |
| 1.2 | Document AML bootstrap producer contract | Enable safe AML-free fallback |
| 1.3 | Add device driver hardware validation harness | USB, storage, network |
| 1.4 | Complete Qt6 rebuild with QtNetwork enabled | Unblock kf6-knewstuff |
### Phase 2: Core Stack Completion (Weeks 4-8)
| # | Action | Impact |
|---|--------|--------|
| 2.1 | Build KWin as real (not stub) compositor | Wayland compositor runtime |
| 2.2 | Complete Wayland compositor integration | graphical session proof |
| 2.3 | Wire KDE Plasma session components | plasma-workspace, plasma-desktop |
| 2.4 | Hardware USB validation | Real xHCI controller testing |
### Phase 3: Hardware Enablement (Weeks 9-16)
| # | Action | Impact |
|---|--------|--------|
| 3.1 | Wi-Fi real hardware validation | Intel iwlwifi proof |
| 3.2 | Bluetooth real hardware validation | USB-attached controller proof |
| 3.3 | IOMMU real hardware validation | AMD-Vi/Intel VT-d proof |
| 3.4 | ACPI sleep-state support | S3/S4 suspend/resume |
### Phase 4: Desktop Polish (Weeks 12-20)
| # | Action | Impact |
|---|--------|--------|
| 4.1 | GPU hardware rendering (if feasible) | Mesa radeonsi/intel drivers |
| 4.2 | Full KDE Plasma session runtime | Booting into graphical desktop |
| 4.3 | Desktop Wi-Fi API (D-Bus) | NetworkManager-like surface |
| 4.4 | Bluetooth desktop integration | HID, audio, file transfer |
### Kernel Blocker (Parallel, upstream-dependent)
| # | Action | Impact |
|---|--------|--------|
| K1 | Engage Redox upstream for credential syscall additions in `redox_syscall` | `SYS_SETUID`, `SYS_SETGID`, `SYS_SETGROUPS` |
| K2 | Add kernel handler for credential syscalls | Remove ENOSYS catch-all gap |
| K3 | Add RLIMIT syscalls or formally design them out | Resource limit support |
---
## 5. Documentation
### Stale Docs Deleted (this pass)
| File | Reason |
|------|--------|
| `local/docs/AMDGPU-DC-COMPILE-TRIAGE-PLAN.md` | Superseded by DRM-MODERNIZATION-EXECUTION-PLAN.md; amdgpu now builds |
### Authority Chain
| Document | Role |
|----------|------|
| `local/docs/RELIBC-COMPREHENSIVE-ASSESSMENT.md` | Canonical relibc |
| `local/docs/DRM-MODERNIZATION-EXECUTION-PLAN.md` | Canonical GPU/DRM |
| `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` | Canonical desktop path |
| `local/docs/DESKTOP-STACK-CURRENT-STATUS.md` | Current build/runtime truth |
| **This document** | **Canonical full-OS assessment** |
+1 -1
View File
@@ -190,7 +190,7 @@ Recipe versions tracked in this tree: KF6 frameworks v6.10.0, Plasma v6.3.4, Att
| **Phase 5 (Hardware GPU) — driver scaffold** | | |
| `redox-drm` | **builds** | DRM scheme daemon with Intel Gen8-Gen12 + AMD device support and quirk tables; no hardware validation |
| `mesa` | **builds** | Software llvmpipe renderer; hardware renderers (radeonsi/iris) not cross-compiled |
| `amdgpu` | **compile triage** | Imported Linux AMD DC/TTM/core C port; bounded path compiles |
| `amdgpu` | **builds + included in redbear-full** (2026-04-29) | Imported Linux AMD DC/TTM/core C port; bounded path compiles; enabled in config (`amdgpu = {}`) |
| `test-phase5-network-qemu.sh` | **exists** | Legacy Phase 5 network/session QEMU launcher (pre-v2.0 plan) |
## Profile View
@@ -1,7 +1,6 @@
# Red Bear OS DRM Modernization Execution Plan
**Date:** 2026-04-18
**Scope:** Shared DRM substrate, shared DRM core, Intel and AMD vendor backends, userland DRM integration, and validation needed to move Red Bear OS from build-visible DRM progress to evidence-backed modern GPU support.
**2026-04-29 build verification update:** All individual DRM/Mesa recipes compile successfully (redox-driver-sys, linux-kpi, redox-drm, mesa/swrast, amdgpu, firmware-loader, iommu). amdgpu is now included in redbear-full (ignore removed from config). Hardware GPU rendering (command submission, fences, Mesa hardware winsys) remains blocked — these are large engineering tasks requiring GPU-architecture-specific work. See hard blockers below.
**Position in the doc set:** This is the single comprehensive GPU/DRM execution plan beneath `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md`. It does not replace the canonical desktop path. It is the canonical GPU/DRM plan and should be preferred over older GPU-specific planning docs when execution order, acceptance criteria, or claim language conflict.
**Supersedes as planning authority:**
@@ -53,9 +52,11 @@ The repo has real progress in shared DRM/KMS, GEM, PRIME, firmware plumbing, int
| KMS ioctl surface | Implemented in shared scheme layer | `local/recipes/gpu/redox-drm/source/src/scheme.rs` |
| GEM allocation and mapping | Implemented in shared scheme and GEM manager | `local/recipes/gpu/redox-drm/source/src/gem.rs`, `local/recipes/gpu/redox-drm/source/src/scheme.rs` |
| PRIME and DMA-BUF style sharing | Implemented at scheme level | `local/docs/HARDWARE-3D-ASSESSMENT.md`, `local/docs/DMA-BUF-IMPROVEMENT-PLAN.md`, `local/recipes/gpu/redox-drm/source/src/scheme.rs` |
| AMD display backend | Build-visible on the bounded retained path, firmware-aware, interrupt-aware | `local/recipes/gpu/redox-drm/source/src/drivers/amd/mod.rs`, `local/recipes/gpu/amdgpu/source/amdgpu_redox_main.c` |
| AMD display backend | Build-visible on the bounded retained path, firmware-aware, interrupt-aware; amdgpu C port compiles | `local/recipes/gpu/redox-drm/source/src/drivers/amd/mod.rs`, `local/recipes/gpu/amdgpu/source/amdgpu_redox_main.c` |
| Intel display backend | Build-visible, GGTT and ring scaffolding present | `local/recipes/gpu/redox-drm/source/src/drivers/intel/mod.rs`, `.../intel/ring.rs` |
| Mesa userland base | Builds with EGL, GBM, OSMesa, software Gallium path | `recipes/libs/mesa/recipe.toml` |
| Mesa userland base | Builds with EGL, GBM, OSMesa, software Gallium path (swrast) | `recipes/libs/mesa/recipe.toml` |
| AMD GPU C port (amdgpu) | ✅ Builds + included in redbear-full (2026-04-29) — C-language port using linux-kpi compatibility; `amdgpu = "ignore"` removed from config | `local/recipes/gpu/amdgpu/`, `config/redbear-full.toml` |
| redbear-full image | ✅ Rebuilt with amdgpu included (2026-04-29) — harddrive.img generated successfully | `build/x86_64/redbear-full/harddrive.img` |
### Hard blockers
+1 -1
View File
@@ -42,7 +42,7 @@ GPU hardware (AMD RDNA / Intel Gen)
| Component | Status | Lines | What's Implemented |
|-----------|--------|-------|-------------------|
| DRM/KMS modesetting | ✅ Code complete | ~500 | 16 KMS ioctls, CRTC/connector/encoder/plane |
| AMD display backend (bounded retained path) | ✅ Builds | ~2 C glue files + Rust FFI surface | Red Bear display glue (`amdgpu_redox_main.c`, `redox_stubs.c`) plus the Rust FFI consumer build; imported Linux AMD DC/TTM/core remain under compile triage |
| AMD display backend (bounded retained path) | ✅ Builds | ~2 C glue files + Rust FFI surface | Red Bear display glue (`amdgpu_redox_main.c`, `redox_stubs.c`) plus the Rust FFI consumer build; imported Linux AMD DC/TTM/core remain builds and included in redbear-full (2026-04-29) |
| Intel Display Driver | ✅ Compiles | ~800 | Display pipe, GGTT, forcewake |
| GEM buffer management | ✅ Full | ~350 | create/close/mmap with DmaBuffer |
| GEM scheme ioctls | ✅ Wired | ~100 | GEM_CREATE, GEM_CLOSE, GEM_MMAP |
+747
View File
@@ -0,0 +1,747 @@
# Red Bear OS — Kernel, IPC, and Credential Syscalls Plan
**Date:** 2026-04-30
**Scope:** Kernel architecture, IPC infrastructure, credential syscalls, process isolation
**Status:** This document is the canonical kernel + IPC plan, extending `local/docs/COMPREHENSIVE-OS-ASSESSMENT.md`
## 1. Purpose
This plan defines the implementation roadmap for kernel hardening, IPC improvements, and credential
syscall implementation in Red Bear OS. It is the **canonical kernel authority** superseding scattered
kernel guidance in other docs.
**Relationship to existing plans:**
| Document | Relationship |
|----------|-------------|
| `COMPREHENSIVE-OS-ASSESSMENT.md` | Parent: this plan extends §2 (Kernel & Core Infrastructure) |
| `IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md` | Sibling: IRQ/PCI/MSI-X — not duplicated here |
| `RELIBC-IPC-ASSESSMENT-AND-IMPROVEMENT-PLAN.md` | Companion: relibc IPC surface — this plan covers kernel side |
| `ACPI-IMPROVEMENT-PLAN.md` | Sibling: ACPI power/shutdown — relevant for §4 (shutdown robustness) |
| `CONSOLE-TO-KDE-DESKTOP-PLAN.md` | Consumer: desktop stack depends on kernel work here |
## 2. Current Architecture Assessment
### 2.1 Kernel Overview
The Redox microkernel (`recipes/core/kernel/source/`) is a ~20-40k LoC Rust microkernel. It runs in
ring 0 and provides:
- **12 kernel schemes**: `debug`, `event`, `memory`, `pipe`, `irq`, `time`, `sys`, `proc`, `serio`,
`acpi`, `dtb`, `user` (userspace scheme wrapper)
- **~35 handled syscalls**: file I/O, memory mapping, process control, futex, time
- **Catch-all ENOSYS**: all unhandled syscall numbers return `ENOSYS`
```
recipes/core/kernel/source/src/
├── syscall/ # Syscall dispatch: mod.rs (handlers), fs.rs, process.rs, futex.rs, time.rs
│ └── mod.rs # Main syscall() dispatch: 35 explicit match arms, _ => ENOSYS
├── scheme/ # Kernel schemes: debug, event, memory, pipe, irq, time, sys, proc, serio
│ ├── mod.rs # Scheme trait definition, SchemeId, FileHandle types
│ ├── proc.rs # Process manager scheme (fork, exec, signal, credential setting)
│ └── sys/ # System info scheme: context list, syscall debug, uname
├── context/ # Process/thread context management
│ ├── context.rs # Context struct: euid, egid, pid, files, signals, addr_space
│ └── memory.rs # Address space, grants, mmap implementation
├── memory/ # Physical/virtual memory management, page tables
└── sync/ # Locking primitives (RwLock, Mutex, CleanLockToken)
```
### 2.2 Syscall Dispatch Architecture
The kernel's `syscall()` function in `syscall/mod.rs` dispatches based on `a` (syscall number):
```rust
// From recipes/core/kernel/source/src/syscall/mod.rs (line 75)
match a {
SYS_WRITE2 => file_op_generic_ext(..),
SYS_WRITE => sys_write(..),
SYS_FMAP => { .. }, // Anonymous or file-backed mmap
SYS_READ2 => file_op_generic_ext(..),
SYS_READ => sys_read(..),
SYS_FPATH => file_op_generic(..),
SYS_FSTAT => fstat(..),
SYS_DUP => dup(..),
SYS_DUP2 => dup2(..),
SYS_SENDFD => sendfd(..),
SYS_OPENAT => openat(..),
SYS_UNLINKAT => unlinkat(..),
SYS_CLOSE => close(..),
SYS_CALL => call(..), // Scheme IPC: send message to scheme
SYS_FEVENT => fevent(..), // Register event on fd
SYS_YIELD => sched_yield(..),
SYS_NANOSLEEP => nanosleep(..),
SYS_CLOCK_GETTIME => clock_gettime(..),
SYS_FUTEX => futex(..),
SYS_MPROTECT => mprotect(..),
SYS_MREMAP => mremap(..),
// ... ~15 more file operations (fchmod, fchown, fcntl, flink, frename, ftruncate, fsync, etc.)
_ => Err(Error::new(ENOSYS)), // ← CATCH-ALL: all credential syscalls fall here
}
```
Syscall numbers come from the external `redox_syscall` crate (crates.io), not from the kernel tree.
The kernel consumes them via `use syscall::number::*`.
### 2.3 Credential Architecture (Current)
**Kernel Context struct** (`context/context.rs`):
```rust
pub struct Context {
// Credential fields (initialized to 0):
pub euid: u32, // Effective user ID — used for scheme access control
pub egid: u32, // Effective group ID
pub pid: usize, // Process ID (set via proc scheme)
// NOT present in kernel:
// ruid, suid — real/saved UID (maintained in userspace redox-rt)
// rgid, sgid — real/saved GID (maintained in userspace redox-rt)
// supplementary groups — not implemented anywhere
// Access control interface:
pub fn caller_ctx(&self) -> CallerCtx {
CallerCtx { uid: self.euid, gid: self.egid, pid: self.pid }
}
}
```
**Credential read path** (userspace, no kernel involvement):
```
getuid() → relibc::platform::redox::getuid()
→ redox_rt::sys::posix_getresugid()
→ reads local DYNAMIC_PROC_INFO { ruid, euid, suid, rgid, egid, sgid }
→ returns cached userspace values (NO kernel syscall)
```
**Credential write path** (through `proc:` scheme):
```
setresuid(ruid, euid, suid) → relibc::platform::redox::setresuid()
→ redox_rt::sys::posix_setresugid(&Resugid { ruid, euid, suid, .. })
→ packs 6×u32 into buffer
→ this_proc_call(&buf, CallFlags::empty(), &[ProcCall::SetResugid as u64])
→ SYS_CALL to proc: scheme
→ kernel proc scheme handler (scheme/proc.rs:1269):
guard.euid = info.euid;
guard.egid = info.egid;
```
**Key finding**: The kernel DOES support credential setting through the `proc:` scheme, using
`ProcSchemeAttrs` with `euid`/`egid`/`pid`/`prio`/`debug_name` fields. The `getuid()`/`getgid()`
functions work through userspace-cached values in `redox-rt`. `setresuid()`/`setresgid()` work
through the proc scheme.
**What's genuinely broken:**
| Function | Status | Root Cause |
|----------|--------|------------|
| `setgroups()` | **ENOSYS stub** | relibc/redox/mod.rs:1205 — `todo_skip!(0, "setgroups({}, {:p}): not implemented")` |
| `getgroups()` | /etc/group-based | Works via `getpwuid()` + `getgrent()` iteration — doesn't use kernel groups |
| `initgroups()` | No-op | No supplementary group infrastructure |
### 2.4 IPC Architecture
**Scheme-based IPC** is the primary IPC mechanism:
```
┌─────────────┐ SYS_CALL(syscall) ┌──────────────┐
│ Userspace │ ──────────────────────────→│ Kernel │
│ Process A │ open/read/write/fevent │ Scheme │
│ │ ←──────────────────────────│ Dispatch │
└─────────────┘ result (usize/-errno) └──────┬───────┘
┌─────────────────────┤
│ │
┌────▼──────┐ ┌──────▼──────┐
│ Kernel │ │ Userspace │
│ Schemes │ │ Scheme │
│ (12) │ │ Daemons │
│ │ │ (via user:) │
│ debug: │ │ │
│ event: │ │ ptyd │
│ memory: │ │ pcid │
│ pipe: │ │ ext4d │
│ irq: │ │ fatd │
│ time: │ │ redox-drm │
│ sys: │ │ ... │
│ proc: │ │ │
│ serio: │ │ │
└───────────┘ └──────────────┘
```
**IPC primitives available:**
| Primitive | Mechanism | Kernel/Userspace |
|-----------|-----------|-----------------|
| `pipe:` scheme | Kernel pipe scheme — bidirectional byte streams | Kernel |
| `shm_open()` / `mmap(MAP_SHARED)` | Shared memory via memory scheme grants | Kernel |
| `SYS_CALL` + scheme messages | Send/receive typed messages to scheme daemons | Kernel dispatch, userspace handler |
| `fevent()` | Register kernel-level events on file descriptors | Kernel |
| `sendfd()` | Pass file descriptors between processes | Kernel |
| `event:` scheme | Kernel event notification (used by eventfd/signalfd/timerfd) | Kernel |
| Signals | `sigprocmask` + `sigaction` via proc: scheme | Kernel delivery, userspace handling |
| Futex | Fast userspace mutex via `SYS_FUTEX` | Kernel |
**Current IPC limitations:**
| Limitation | Impact |
|-----------|--------|
| No `SYS_PTRACE` | ptrace not available (handled via proc: scheme paths) |
| No `SYS_KILL` | Signal sending via proc: scheme only |
| eventfd/signalfd/timerfd recipe-applied | Bounded compatibility layers, not plain-source |
| `ifaddrs` synthetic | Only `loopback` + `eth0`, not live enumeration |
| POSIX message queues not implemented | `mqueue.h` missing entirely |
| SysV message queues not implemented | `sys/msg.h` missing entirely |
| No UNIX domain sockets (`AF_UNIX`) path | Socket-based IPC limited |
### 2.5 Process Model
Redox uses a **userspace process manager** (`procmgr` via `proc:` scheme):
- **fork**: Implemented through proc: scheme → kernel creates new Context with cloned address space
- **exec**: Replaces address space with new executable image
- **spawn**: Combined fork+exec via proc: scheme
- **wait/waitpid/waitid**: Recipe-applied patch via proc: scheme (signals child exit)
- **Credentials on fork**: Address space cloned (userspace `DYNAMIC_PROC_INFO` inherited)
- **Credentials on exec**: `setresuid()` behavior (suid-bit not implemented in kernel)
The kernel's Context struct tracks:
- `owner_proc_id: Option<NonZeroUsize>` — parent process for exit notification
- `files: Arc<LockedFdTbl>` — file descriptor table (can be shared)
- `addr_space: Option<Arc<AddrSpaceWrapper>>` — address space (can be shared = threads)
- `sig: Option<SignalState>` — signal handler configuration
## 3. Critical Gaps and Blockers
### 3.1 Credential Syscall Blocker (Priority: P0-CRITICAL)
The `setgroups()` function is **ENOSYS**. This blocks:
- `polkit` — uses `setgroups()` for privilege management
- `dbus-daemon` — uses credentials for service activation
- `logind` / `redbear-sessiond` — needs credential awareness
- `sudo` / `su` — uses `initgroups()``setgroups()`
- Any program that changes user identity
**Root cause chain:**
1. `redox_syscall` crate (crates.io, upstream) has no `SYS_SETGROUPS`/`SYS_GETGROUPS` numbers
2. Kernel has no supplementary group table in Context struct
3. No group inheritance on fork/exec
4. relibc `setgroups()` is a `todo_skip!()` stub
5. `getgroups()` bypasses kernel entirely (reads /etc/group)
### 3.2 Kernel-Level Access Control Gap (Priority: P1)
The kernel's `caller_ctx()` provides `{euid, egid, pid}` to scheme handlers, but:
1. **No consistent enforcement**: Kernel schemes may or may not check caller credentials
2. **No ruid/suid tracking**: Cannot distinguish real vs effective identity in kernel
3. **All processes start as root** (euid=0, egid=0): No privilege separation at boot
4. **No supplementary groups in kernel**: Only egid checked
### 3.3 IPC Completeness Gaps (Priority: P2)
| Gap | Priority | Blocked By |
|-----|----------|------------|
| POSIX message queues (`mqueue.h`) | P2 | Scheme design needed |
| SysV message queues (`sys/msg.h`) | P2 | Scheme design needed |
| UNIX domain sockets (`AF_UNIX`) | P2 | Kernel or scheme implementation |
| Non-synthetic `ifaddrs` | P3 | Network stack enumeration |
| eventfd/signalfd/timerfd → plain-source | P3 | Upstream relibc convergence |
### 3.4 Resource Limits (Priority: P2)
`SYS_GETRLIMIT` / `SYS_SETRLIMIT` return ENOSYS. This is a microkernel design choice:
- Resource limits are typically library-level policy in capability systems
- Current approach: limits enforced in userspace daemons
- Desktop impact: systemd/logind expect rlimit support for service management
### 3.5 Shutdown Robustness (Priority: P2)
ACPI shutdown via `kstop` eventing exists but has gaps:
- `acpid` startup has panic-grade `expect` paths
- `_S5` derivation gated on PCI timing
- DMAR orphaned in `acpid` source
- See `local/docs/ACPI-IMPROVEMENT-PLAN.md` for full detail
## 4. Implementation Plan
### Phase K1: Kernel Credential Foundation (Week 1-2)
**Goal**: Add supplementary group support to the kernel and wire `setgroups()`/`getgroups()`.
#### K1.1 — Add supplementary groups to kernel Context
```rust
// Context struct additions (context/context.rs):
pub struct Context {
// Existing:
pub euid: u32,
pub egid: u32,
pub pid: usize,
// NEW: Real/saved IDs (moved from userspace redox-rt to kernel):
pub ruid: u32,
pub rgid: u32,
pub suid: u32,
pub sgid: u32,
// NEW: Supplementary groups
pub groups: Vec<u32>, // Or Arc<[u32]> for sharing
}
```
**Files modified:**
- `recipes/core/kernel/source/src/context/context.rs` — add fields, initialize, clone on fork
- `recipes/core/kernel/source/src/scheme/proc.rs` — extend `ProcSchemeAttrs` to include ruid/suid/rgid/sgid/groups
- `local/patches/kernel/` — new patch: `P4-credential-fields.patch`
#### K1.2 — Add `SYS_SETGROUPS` and `SYS_GETGROUPS` to redox_syscall
The `redox_syscall` crate is upstream (crates.io). Red Bear must either:
- **Option A (preferred)**: Contribute upstream PR to add syscall numbers
- **Option B**: Vendor fork of `redox_syscall` in `local/` overlay
- **Option C**: Define Red Bear-local syscall numbers in kernel directly
**Recommended: Option A + B fallback**:
1. Submit upstream PR to `redox_syscall` adding:
- `SYS_SETGROUPS`, `SYS_GETGROUPS`
- `SYS_SETUID`, `SYS_SETGID`, `SYS_GETUID`, `SYS_GETGID`
- `SYS_GETEUID`, `SYS_GETEGID`
- `SYS_SETREUID`, `SYS_SETREGID`
- `SYS_GETRESUID`, `SYS_GETRESGID`
2. While upstream PR is pending, use a local `redox_syscall` patch:
- Copy `redox_syscall` crate into `local/vendor/redox_syscall/`
- Add syscall number constants
- Point kernel Cargo.toml to local path
- Patch tracked in `local/patches/kernel/P4-redox-syscall-numbers.patch`
#### K1.3 — Add kernel syscall handlers
**New file:** `recipes/core/kernel/source/src/syscall/cred.rs`
```rust
// Credential syscall handlers
pub fn setresuid(ruid: u32, euid: u32, suid: u32, token: &mut CleanLockToken) -> Result<usize> {
let context_lock = context::current();
let mut context = context_lock.write(token.token());
// Permission check: must be root or match current values
if context.euid != 0 {
if let Some(ruid) = ruid_opt { /* check ruid == current ruid/euid/suid */ }
// ... POSIX permission model
}
// Set values
if ruid != u32::MAX { context.ruid = ruid; }
if euid != u32::MAX { context.euid = euid; }
if suid != u32::MAX { context.suid = suid; }
Ok(0)
}
pub fn setgroups(groups: &[u32], token: &mut CleanLockToken) -> Result<usize> {
// Requires: euid == 0
let context_lock = context::current();
let mut context = context_lock.write(token.token());
if context.euid != 0 { return Err(Error::new(EPERM)); }
context.groups = groups.to_vec();
Ok(0)
}
pub fn getgroups(token: &mut CleanLockToken) -> Result<Vec<u32>> {
let context_lock = context::current();
let context = context_lock.read(token.token());
Ok(context.groups.clone())
}
```
**Modified file:** `recipes/core/kernel/source/src/syscall/mod.rs`
```rust
match a {
// ... existing arms ...
SYS_SETRESUID => setresuid(b as u32, c as u32, d as u32, token),
SYS_SETRESGID => setresgid(b as u32, c as u32, d as u32, token),
SYS_GETRESUID => getresuid(UserSlice::wo(b, c)?, token),
SYS_GETRESGID => getresgid(UserSlice::wo(b, c)?, token),
SYS_SETUID => setuid(b as u32, token),
SYS_SETGID => setgid(b as u32, token),
SYS_GETUID => Ok(getuid(token)),
SYS_GETGID => Ok(getgid(token)),
SYS_GETEUID => Ok(geteuid(token)),
SYS_GETEGID => Ok(getegid(token)),
SYS_SETGROUPS => setgroups(UserSlice::ro(b, c)?, token).map(|()| 0),
SYS_GETGROUPS => getgroups(UserSlice::wo(b, c)?, token),
// ... existing arms ...
}
```
#### K1.4 — Wire relibc setgroups()/getgroups() through real syscalls
**Modified:** `recipes/core/relibc/source/src/platform/redox/mod.rs`
```rust
// Replace todo_skip!() stub:
unsafe fn setgroups(size: size_t, list: *const gid_t) -> Result<()> {
if size < 0 || size > NGROUPS_MAX { return Err(Errno(EINVAL)); }
let groups = core::slice::from_raw_parts(list, size as usize);
syscall::setgroups(groups)?;
Ok(())
}
// Replace /etc/group-based getgroups:
fn getgroups(mut list: Out<[gid_t]>) -> Result<c_int> {
let mut buf = [0u32; NGROUPS_MAX as usize];
let count = syscall::getgroups(&mut buf)?;
for (i, gid) in buf[..count].iter().enumerate() {
list[i] = *gid as gid_t;
}
Ok(count as c_int)
}
```
#### K1.5 — Add credential syscall stubs in redox-rt
**Modified:** `recipes/core/relibc/source/redox-rt/src/sys.rs`
```rust
pub fn setgroups(groups: &[u32]) -> Result<()> {
unsafe {
redox_syscall::syscall5(
redox_syscall::SYS_SETGROUPS,
groups.as_ptr() as usize,
groups.len(),
0, 0, 0,
)
.map(|_| ())
.map_err(|e| Error::new(e.errno as i32))
}
}
pub fn getgroups(buf: &mut [u32]) -> Result<usize> {
unsafe {
redox_syscall::syscall3(
redox_syscall::SYS_GETGROUPS,
buf.as_mut_ptr() as usize,
buf.len(),
0,
)
.map_err(|e| Error::new(e.errno as i32))
}
}
```
#### K1.6 — Patch management
All kernel and relibc source changes must be mirrored into `local/patches/`:
```bash
local/patches/
├── kernel/
│ ├── redox.patch # Updated symlink target
│ ├── P4-credential-fields.patch # Context struct additions
│ ├── P4-credential-syscalls.patch # Syscall handlers + dispatch
│ └── P4-redox-syscall-numbers.patch # Local redox_syscall additions
├── relibc/
│ ├── P4-setgroups-kernel.patch # Setgroups through real syscall
│ ├── P4-getgroups-kernel.patch # Getgroups through real syscall
│ └── P4-redox-rt-cred-syscalls.patch # redox-rt syscall wrappers
```
### Phase K2: Kernel Access Control Hardening (Week 2-3)
**Goal**: Enforce credential checks in kernel schemes, add proper privilege separation.
#### K2.1 — Enforce scheme-level credential checks
Each kernel scheme handler currently receives `CallerCtx { uid, gid, pid }`. Ensure consistent
credential enforcement:
| Scheme | Current Check | Required Check |
|--------|--------------|----------------|
| `memory:` | Physical memory access → root only | ✅ Already enforced (euid==0 for phys) |
| `irq:` | IRQ registration → root only | ✅ Already enforced |
| `proc:` | Process inspection → caller == target OR root | 🔄 Review: ensure consistent |
| `sys:` | System info → read-only for all | ✅ Appropriate |
| `debug:` | Debug output → should be root-only | 🔄 Review: add check |
| `serio:` | PS/2 device → root only | 🔄 Review: add check |
| `event:` | Event registration → process-own only | 🔄 Review: ensure isolation |
#### K2.2 — Bootstrap with non-root init process
Currently all processes start as euid=0/egid=0. The boot sequence should:
1. Kernel bootstrap context starts as root (euid=0, egid=0) — required for init
2. Init (`/sbin/init`) runs as root
3. Init drops privileges before spawning user services:
```rust
// In init or service manager:
setresuid(1000, 1000, 1000); // Drop to regular user
setgroups(&[1000, 27, 100]); // Set supplementary groups
// Then spawn child services with restricted permissions
```
#### K2.3 — Add `initgroups()` support
```rust
// In relibc/src/platform/redox/mod.rs:
fn initgroups(user: CStr, group: gid_t) -> Result<()> {
// 1. Set primary group
setgid(group)?;
// 2. Parse /etc/group for supplementary groups containing this user
let mut groups = vec![group];
// ... iterate getgrent() to find user memberships ...
// 3. Set supplementary groups via kernel syscall
setgroups(&groups)?;
Ok(())
}
```
### Phase K3: IPC Infrastructure Improvements (Week 3-5)
**Goal**: Complete IPC primitives needed for desktop infrastructure.
#### K3.1 — POSIX Message Queues (`mqueue.h`)
**Design decision**: Implement as a userspace scheme daemon (not kernel syscalls).
```
mqd:
├── Registers as scheme:mqueue
├── Stores queues in memory backed by shm_open() + mmap()
├── mq_open() → open scheme:mqueue/{name}
├── mq_send() → write to fd
├── mq_receive() → read from fd
├── mq_notify() → fevent() on fd for async notification
├── mq_close() → close fd
└── mq_unlink() → unlink scheme:mqueue/{name}
```
**Implementation:**
- New Red Bear package: `local/recipes/system/mqueued/`
- Relibc header: `recipes/core/relibc/source/src/header/mqueue/`
- Recipe in `local/recipes/system/mqueued/recipe.toml`
- Init service: `/usr/lib/init.d/50_mqueued.service`
#### K3.2 — SysV Message Queues (`sys/msg.h`)
**Design decision**: Implement as scheme daemon or on top of POSIX message queues.
- Recommended: implement directly alongside `mqueued` using shared infrastructure.
- Low priority — Qt/KDE do not depend on SysV msg queues.
#### K3.3 — UNIX Domain Sockets (`AF_UNIX` / `SOCK_STREAM`)
**Current state**: D-Bus uses abstract sockets on Linux. Redox uses scheme-based communication.
- For D-Bus compatibility: `redbear-sessiond` already uses `zbus` with custom transport
- For general `AF_UNIX`: implement as `scheme:unix` daemon backed by kernel pipe scheme
- Priority: P3 — D-Bus is already working through scheme transport
#### K3.4 — Non-synthetic Interface Enumeration
Replace the hardcoded `loopback` + `eth0` model with live network interface enumeration:
- Query `smolnetd` or equivalent for active interfaces
- Expose through `getifaddrs()` properly
- Priority: P3 — needed for NetworkManager-like functionality
#### K3.5 — eventfd/signalfd/timerfd → plain-source convergence
Current state: all three are recipe-applied patches. Goal: upstream into relibc mainline.
- Monitor upstream relibc for equivalent implementations
- When upstream absorbs: shrink/drop Red Bear patch chain
- When upstream does NOT absorb after 3+ months: promote to durable Red Bear-maintained
- See `local/docs/RELIBC-IPC-ASSESSMENT-AND-IMPROVEMENT-PLAN.md` Phase I5
### Phase K4: Resource Limits and Process Management (Week 4-6)
#### K4.1 — RLIMIT Support
**Decision**: Enforce resource limits in userspace, not kernel.
- The kernel is a microkernel — resource limits are policy
- `getrlimit()` / `setrlimit()` → libc stubs with reasonable defaults
- Process enforcement → `procmgr` (userspace process manager) via proc: scheme
- File descriptor limits → already enforced via `CONTEXT_MAX_FILES` in kernel
- Memory limits → userspace `procmgr` can kill processes exceeding limits
```rust
// relibc implementation (userspace, no kernel changes needed):
fn getrlimit(resource: c_int, rlim: *mut rlimit) -> Result<()> {
match resource {
RLIMIT_NOFILE => { rlim.rlim_cur = 1024; rlim.rlim_max = 4096; }
RLIMIT_NPROC => { rlim.rlim_cur = 256; rlim.rlim_max = 1024; }
RLIMIT_AS => { rlim.rlim_cur = RLIM_INFINITY; rlim.rlim_max = RLIM_INFINITY; }
RLIMIT_CORE => { rlim.rlim_cur = 0; rlim.rlim_max = RLIM_INFINITY; }
// ... other resource types with reasonable defaults
_ => return Err(Errno(EINVAL)),
}
Ok(())
}
```
#### K4.2 — PTRACE via proc: scheme
`SYS_PTRACE` is not implemented as a direct syscall. The Redox model uses the `proc:` scheme
for process inspection and manipulation:
- Already partially implemented in `scheme/proc.rs`
- Memory read/write through proc: scheme file operations
- Register read/write through proc: scheme
- Signal injection through proc: scheme
Improvements needed:
- Document the proc: scheme ptrace API surface
- Ensure all ptrace operations have proc: scheme equivalents
- Add `PTRACE_*` constants to redox_syscall for compatibility
#### K4.3 — clock_settime
`SYS_CLOCK_SETTIME` returns ENOSYS. Implementation:
- Add scheme write path to `/scheme/sys/update_time_offset`
- Or implement as direct syscall for precision
- Priority: P3 — needed for NTP synchronization
### Phase K5: Shutdown and Power Management (Week 5-7)
See `local/docs/ACPI-IMPROVEMENT-PLAN.md` for full ACPI plan. This section covers kernel-specific
work only.
#### K5.1 — Hardened acpid Startup
- Remove panic-grade `expect` paths in kernel ACPI/AML handling
- Add graceful fallback when ACPI tables are missing or malformed
- See ACPI-IMPROVEMENT-PLAN.md Wave 1
#### K5.2 — kstop Shutdown Robustness
- Current: `_S5` shutdown via `kstop` event exists but gated on PCI timing
- Required: deterministic shutdown ordering:
1. Notify userspace services of impending shutdown
2. Sync filesystems
3. Power off via ACPI/FADT
- See ACPI-IMPROVEMENT-PLAN.md Wave 2
#### K5.3 — Sleep State Support
- S3 (suspend-to-RAM) and S4 (hibernate) are not yet supported
- Requires: kernel state serialization, device reinitialization
- Priority: P4 — long-term, not blocking desktop
## 5. Dependency Chain
```
Phase K1 (credential syscalls) ─────────────────────┐
│ │
├──► polkit compatibility │
├──► dbus-daemon credential checks │
├──► sudo/su user switching │
├──► redbear-sessiond login1 handoff │
└──► greeter/session-launch credential drop │
Phase K2 (access control) ────────────────────────────┤
│ │
├──► Privilege-separated boot sequence │
├──► Scheme-level credential enforcement │
└──► initgroups() for service launching │
Phase K3 (IPC) ───────────────────────────────────────┤
│ │
├──► POSIX message queues → needed by some apps │
├──► AF_UNIX → broader D-Bus transport options │
└──► eventfd/signalfd/timerfd → KDE/Qt runtime │
Phase K4 (limits/ptrace) ─────────────────────────────┤
│ │
├──► RLIMIT → systemd/logind compatibility │
├──► PTRACE → debugging support │
└──► clock_settime → NTP synchronization │
Desktop infrastructure
ready for KDE Plasma
```
## 6. Integration with Existing Work
### 6.1 Already in Progress (do not duplicate)
| Area | Canonical Plan | Status |
|------|---------------|--------|
| IRQ / MSI-X / IOMMU | `IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md` | Waves 1-6 complete, hardware validation open |
| ACPI shutdown / power | `ACPI-IMPROVEMENT-PLAN.md` | Waves 1-2 complete, sleep states deferred |
| relibc IPC surface | `RELIBC-IPC-ASSESSMENT-AND-IMPROVEMENT-PLAN.md` | Phases I1-I5, message queues deferred |
| D-Bus / sessiond | `DBUS-INTEGRATION-PLAN.md` | Phase 1 complete, Phase 2 in progress |
| Greeter / login | `GREETER-LOGIN-IMPLEMENTATION-PLAN.md` | Active, bounded proof passing |
| Desktop path | `CONSOLE-TO-KDE-DESKTOP-PLAN.md` | Phase 1-5 model, KWin building |
### 6.2 This Plan Covers (uniquely)
| Area | This Plan | Not Covered By |
|------|-----------|---------------|
| Kernel credential architecture | §3, Phase K1 | Any existing plan |
| Kernel access control hardening | §3.2, Phase K2 | Any existing plan |
| `setgroups()` / `getgroups()` kernel implementation | Phase K1.2-K1.4 | Only stub noted elsewhere |
| Supplementary group infrastructure | Phase K1.1 | Not covered anywhere |
| POSIX/SysV message queues | Phase K3.1-K3.2 | Deferred in relibc-IPC plan |
| UNIX domain sockets | Phase K3.3 | Not covered |
| RLIMIT design decision | Phase K4.1 | Noted as gap only |
| PTRACE via proc: scheme | Phase K4.2 | Not covered |
| clock_settime implementation | Phase K4.3 | Noted as gap only |
## 7. Patch Governance
All kernel and relibc source changes must follow the durability policy (see `local/AGENTS.md`):
1. **Make changes** in `recipes/core/kernel/source/` or `recipes/core/relibc/source/`
2. **Generate patches**: `git diff` in the source tree → `local/patches/<component>/P4-*.patch`
3. **Wire patches** into `recipes/core/<component>/recipe.toml` patches list
4. **Commit** patches + recipe changes before session end
5. **Assume** source trees may be thrown away by `make distclean` or upstream refresh
### Patch naming convention:
```
local/patches/kernel/P4-credential-fields.patch
local/patches/kernel/P4-credential-syscalls.patch
local/patches/kernel/P4-redox-syscall-numbers.patch
local/patches/relibc/P4-setgroups-kernel.patch
local/patches/relibc/P4-getgroups-kernel.patch
local/patches/relibc/P4-redox-rt-cred-syscalls.patch
local/patches/relibc/P4-initgroups.patch
```
## 8. Validation and Evidence
### 8.1 Build Evidence
| Check | Command |
|-------|---------|
| Kernel compiles | `make r.kernel` |
| relibc compiles | `make r.relibc` |
| Full OS builds | `make all CONFIG_NAME=redbear-full` |
### 8.2 Runtime Evidence
| Test | Verification |
|------|-------------|
| `getuid()` returns non-zero after login | `id` command in guest |
| `setgroups()` succeeds for root | `sudo -u user id` in guest |
| `setresuid()` properly changes euid | `su user -c 'id'` |
| `initgroups()` populates groups | `groups` command in guest |
| Credentials survive fork | `bash -c 'id'` |
| Credentials dropped on exec (if SUID implemented) | TBD |
| polkit can query credentials | `pkexec echo ok` |
| dbus-daemon starts without errors | `dbus-monitor` |
### 8.3 Verification Scripts
Create bounded proof scripts:
```bash
local/scripts/test-credential-syscalls-qemu.sh # QEMU launcher
local/scripts/test-credential-syscalls-guest.sh # In-guest checker
```
## 9. References
- `local/docs/COMPREHENSIVE-OS-ASSESSMENT.md` — Parent assessment, §2 kernel gaps
- `docs/01-REDOX-ARCHITECTURE.md` — Architecture reference
- `local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md` — IRQ/PCI plan (sibling)
- `local/docs/RELIBC-IPC-ASSESSMENT-AND-IMPROVEMENT-PLAN.md` — IPC surface plan (companion)
- `local/docs/ACPI-IMPROVEMENT-PLAN.md` — ACPI/shutdown plan (sibling)
- `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` — Desktop path plan (consumer)
- `recipes/core/kernel/source/src/syscall/mod.rs` — Syscall dispatch (primary implementation target)
- `recipes/core/kernel/source/src/context/context.rs` — Context struct (credential fields)
- `recipes/core/kernel/source/src/scheme/proc.rs` — Proc scheme (credential setting)
- `recipes/core/relibc/source/src/platform/redox/mod.rs` — relibc Redox platform (credential stubs)
- `recipes/core/relibc/source/redox-rt/src/sys.rs` — redox-rt credential primitives