From ecf1f19d55da5d51003840ca2d8810903b41fbf7 Mon Sep 17 00:00:00 2001 From: vasilito Date: Thu, 9 Jul 2026 11:19:53 +0300 Subject: [PATCH] docs: remove 13 more superseded archived audit/assessment snapshots Removed archived audit snapshots and superseded plans: - BOOT-PROCESS-* (3 audit files from 2026-05) - COMPREHENSIVE-FIX-AND-IMPROVEMENT + FINAL (superseded by IMPROVEMENT-PLAN) - DEVICE-INIT, GRAPHICAL-BOOT, GREETER-LOGIN (old assessments) - IOMMU-SPEC, SCHEDULER-REVIEW, BUILD-TOOLS, VFAT, ZSH (superseded) Active plans remain in local/docs/. Archived dir now has 10 files. --- .../BOOT-PROCESS-FIX-SUMMARY-2026-05-03.md | 70 - .../archived/BOOT-PROCESS-IMPROVEMENT-PLAN.md | 274 --- .../BOOT-PROCESS-SECOND-AUDIT-2026-05-03.md | 266 --- .../docs/archived/BUILD-TOOLS-PORTING-PLAN.md | 368 ---- .../COMPREHENSIVE-FIX-AND-IMPROVEMENT-PLAN.md | 255 --- .../archived/COMPREHENSIVE-FIX-PLAN-FINAL.md | 197 -- ...ICE-INIT-COMPREHENSIVE-IMPROVEMENT-PLAN.md | 735 ------- .../GRAPHICAL-BOOT-ASSESSMENT-2026-05-03.md | 36 - local/docs/archived/GREETER-LOGIN-ANALYSIS.md | 308 --- local/docs/archived/IOMMU-SPEC-REFERENCE.md | 1946 ----------------- local/docs/archived/SCHEDULER-REVIEW-FINAL.md | 50 - .../docs/archived/VFAT-IMPLEMENTATION-PLAN.md | 916 -------- local/docs/archived/ZSH-PORTING-PLAN.md | 320 --- 13 files changed, 5741 deletions(-) delete mode 100644 local/docs/archived/BOOT-PROCESS-FIX-SUMMARY-2026-05-03.md delete mode 100644 local/docs/archived/BOOT-PROCESS-IMPROVEMENT-PLAN.md delete mode 100644 local/docs/archived/BOOT-PROCESS-SECOND-AUDIT-2026-05-03.md delete mode 100644 local/docs/archived/BUILD-TOOLS-PORTING-PLAN.md delete mode 100644 local/docs/archived/COMPREHENSIVE-FIX-AND-IMPROVEMENT-PLAN.md delete mode 100644 local/docs/archived/COMPREHENSIVE-FIX-PLAN-FINAL.md delete mode 100644 local/docs/archived/DEVICE-INIT-COMPREHENSIVE-IMPROVEMENT-PLAN.md delete mode 100644 local/docs/archived/GRAPHICAL-BOOT-ASSESSMENT-2026-05-03.md delete mode 100644 local/docs/archived/GREETER-LOGIN-ANALYSIS.md delete mode 100644 local/docs/archived/IOMMU-SPEC-REFERENCE.md delete mode 100644 local/docs/archived/SCHEDULER-REVIEW-FINAL.md delete mode 100644 local/docs/archived/VFAT-IMPLEMENTATION-PLAN.md delete mode 100644 local/docs/archived/ZSH-PORTING-PLAN.md diff --git a/local/docs/archived/BOOT-PROCESS-FIX-SUMMARY-2026-05-03.md b/local/docs/archived/BOOT-PROCESS-FIX-SUMMARY-2026-05-03.md deleted file mode 100644 index b1cb9b136b..0000000000 --- a/local/docs/archived/BOOT-PROCESS-FIX-SUMMARY-2026-05-03.md +++ /dev/null @@ -1,70 +0,0 @@ -# Red Bear OS — Build & Boot Fix Summary - -**Date**: 2026-05-03 -**Oracle-reviewed**: Yes (3 rounds) - -## Applied Fixes - -### 1. Cookbook Stage Cleanup (`src/cook/cook_build.rs`) -- Line 506, 715: `remove_all(&stage_dir)` before `rename(stage.tmp, stage)` -- Prevents "Directory not empty" during incremental builds - -### 2. Cargo Install --Force (`src/cook/script.rs`) -- Line 155: `--force` flag on `cargo install --root` -- Prevents "binary already exists" errors - -### 3. KF6 Config (`config/redbear-full.toml`) -- `kf6-kwayland`, `kf6-kidletime` → `"ignore"` (TEMPORARY — blocked on libwayland) -- `31_debug_console.service`: `/scheme/debug/no-preserve -J` with `respawn = true` - -### 4. POSIX Named Semaphores (`recipes/core/relibc/`) -- `sem_open`: shm-backed via `shm_open` + `mmap` + `sem_init` -- `sem_close`: `munmap` wrapper -- `sem_unlink`: `shm_unlink` wrapper -- `sem_trywait`: Returns -1 with EAGAIN when acquire fails -- `sem_wait`: Returns -1 with EINVAL on error -- `sem_timedwait`/`sem_clockwait`: Return -1 with ETIMEDOUT on timeout -- Fixed `Semaphore::wait()`: Was returning success when count was 0 (inverted condition) -- **Durable patch**: `local/patches/relibc/P5-named-semaphores.patch` (249 lines) -- **Recipe symlink**: `recipes/core/relibc/P5-named-semaphores.patch` → `local/` - -### 5. Documentation -- `GRAPHICAL-BOOT-ASSESSMENT-2026-05-03.md`: Updated with current state -- This file: Comprehensive fix summary -- 20 stale docs archived in `local/docs/archived/` - -## Known Limitations (Honest Assessment) - -### Semaphore Completeness -- `sem_wait` errno: Sets EINVAL for any error from underlying `wait()`, which can only return `Err(())` for invalid clock_id. Correct in practice for the current code paths. -- `sem_timedwait`/`sem_clockwait`: Set ETIMEDOUT for all errors; cannot distinguish timeout from invalid clock_id with current `wait()` return type. Conservative: ETIMEDOUT covers the common case. -- Named semaphore size: Uses `size_of::()` (4 bytes) for `ftruncate`/`mmap`, but `RlctSemaphore` may be larger. Works currently because internal representation fits. - -### Relibc Patch Chain -- `recipes/core/relibc/recipe.toml` currently lists only `P5-named-semaphores.patch` -- Pre-existing relibc modifications (waitid, eventfd, signalfd, etc.) exist in the live source tree but are NOT captured in patches -- A clean `repo fetch relibc` would lose those changes — this is a pre-existing condition, not introduced by this work -- Full relibc patch audit needed as separate task - -### Console/Login Surface -- Console login: Available on **framebuffer VT2** (`getty 2`), not serial -- Serial port: Shows daemon logs and stderr output; does not show login prompt in QEMU `-display none` mode -- To access VT2 login: Use `-display gtk` or similar with QEMU - -## Build Verification -``` -✅ redbear-full: 0 failed recipes, 4GB image -✅ redbear-mini: 0 failed recipes -✅ nm -D libc.so: 11 sem_* symbols exported -✅ Serial console: All daemon output visible (D-Bus, sessiond, greeter, keymapd) -✅ Init chain: Serial probes confirm all services start -✅ Semaphore wait: Fixed inverted condition in sync/semaphore.rs -✅ cbindgen.toml: SEM_FAILED macro exported -``` - -## Remaining Work (Not In Scope) -1. **libwayland**: Implement MSG_NOSIGNAL and open_memstream in relibc -2. **KF6 re-enable**: When libwayland builds, un-ignore kf6-kwayland/kf6-kidletime -3. **Relibc patch audit**: Capture all pre-existing relibc changes as durable patches -4. **Runtime POSIX tests**: Run test-posix-runtime.sh for behavioral verification -5. **QML gate**: Long-term blocker for KWin/Plasma desktop diff --git a/local/docs/archived/BOOT-PROCESS-IMPROVEMENT-PLAN.md b/local/docs/archived/BOOT-PROCESS-IMPROVEMENT-PLAN.md deleted file mode 100644 index d1f2ec1419..0000000000 --- a/local/docs/archived/BOOT-PROCESS-IMPROVEMENT-PLAN.md +++ /dev/null @@ -1,274 +0,0 @@ -# Red Bear OS — Boot Process Improvement Plan -**Implementation status (2026-04-29):** All BOOT plan code artifacts are build-verified. Remaining items in this document are runtime validation gates requiring QEMU or hardware. - -**Version:** 1.1 — 2026-04-29 -**Status:** Active — supersedes ad-hoc boot fixes and replaces historical P0–P6 boot notes -**Canonical plans:** `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` (v4.0), `local/docs/GREETER-LOGIN-IMPLEMENTATION-PLAN.md` -**Diagnosis:** `local/docs/BOOT-PROCESS-ASSESSMENT.md` (Phase 7 kernel RAM hang + ISO organization) - ---- - -## 1. Target Contract - -| Profile | Required boot outcome | Current state | Gap | -|---------|----------------------|---------------|-----| -| `redbear-full` | **Graphical Wayland greeter → KDE desktop session** | Graphical Wayland greeter path (bounded compositor proof); real KWin gated on Qt6Quick | Three blockers | -| `redbear-mini` | **Text login** | ✅ Working | None | -| `redbear-grub` | **Text login** | ✅ Working | None | - ---- - -## 2. Current Boot Reality (2026-04-27 Diagnosis) - -### What works - -- UEFI bootloader → kernel → init phase 1/2/3 → services → text login prompt -- D-Bus system bus, redbear-sessiond (login1), seatd, redbear-authd, redbear-polkit -- redbear-upower, redbear-udisks (read-only) -- Framebuffer via vesad (1280×720), fbcond handoff -- udev-shim, evdevd input stack -- All 37 rootfs units schedule and start - -### What does NOT work - -1. **No graphical login yet** — boot ordering now explicitly schedules `pcid-spawner` before the greeter, and `redbear-greeter-compositor` waits for the configured DRM path before selecting `--drm`. The remaining blocker is still runtime DRM availability: if `redox-drm` never exposes `/scheme/drm/card0`, the greeter honestly falls back to `redbear-compositor --virtual` and the Qt6/QML greeter UI still does not render on a real KMS path. -2. **Kernel hangs with ≥4 GiB RAM** — On x86_64, kernel enters spin-loop before `serial::init()` completes when guest RAM ≥4 GiB. `make qemu` default 2048 MiB is unaffected. -3. **Live ISO preload broken** — Bootloader cannot allocate 4 GiB contiguous RAM block. - ---- - -## 3. Blocker Resolution Plan - -### 3.1 Blocker A: Fix kernel 4 GiB RAM hang - -**Priority:** P0 — blocks real hardware and any QEMU config with >2 GiB RAM. - -**Symptom:** With `-m 4096` (4 GiB guest RAM), the kernel loads but produces zero serial output. CPU trace shows spin-loop (`pause` + `jmp`). With 2 GiB, boots normally. - -**Root cause:** Memory map processing or SMP initialization bug in `startup::memory::init()` or `arch/x86_shared/start.rs` when physical memory exceeds ~2 GiB. - -**Evidence:** Kernel binary identical between mini and full (MD5 confirmed). Mini boots at 4 GiB, full does not. Bootloader, kernel, and initfs are byte-identical across profiles. - -**Files to modify:** - -| File | Change | Why | -|------|--------|-----| -| `recipes/core/kernel/source/src/arch/x86_shared/start.rs` | Add raw COM1 `outb` before `serial::init()` as canary | Proves serial hardware works; isolates hang point | -| `recipes/core/kernel/source/src/startup/memory.rs` | Add debug logging around memory region processing | Identify overflow / bad mapping at large memory sizes | -| `recipes/core/kernel/source/src/arch/x86_shared/device/serial.rs` | Ensure COM1 init path is robust for all memory configs | If serial init itself hangs, diagnose why | - -**Acceptance criteria:** -- [x] `make qemu` with `QEMU_MEM=4096` — structurally implemented (kernel patch exists, 4GB config present); runtime QEMU validation supplementary (requires QEMU environment) -- [x] Full init sequence — service ordering verified in config; runtime proof requires QEMU -- [x] Kernel patch — generated, wired into `local/patches/kernel/`, `recipe.toml` updated per durability policy - -**Estimated effort:** 2–4 days (requires kernel debugging with QEMU GDB) - ---- - -### 3.2 Blocker B: Enable DRM/KMS for Wayland compositor - -**Priority:** P0 — KWin needs a real DRM device to render the greeter. - -**Symptom:** `redbear-greeter-compositor: using virtual KWin backend (set KWIN_DRM_DEVICES to enable DRM)` - -**Root cause chain:** - -1. `redox-drm` daemon is not being spawned by `pcid-spawner` for the active GPU -2. No `/scheme/drm/card0` device exists -3. `KWIN_DRM_DEVICES` must still point at the real device node (`/scheme/drm/card0` in the bounded QEMU path) -4. The compositor wrapper must wait for that node even when the environment is already populated, because `pcid-spawner` is intentionally asynchronous in Red Bear OS - -**Files to modify:** - -| File | Change | Why | -|------|--------|-----| -| `config/redbear-full.toml` — `20_greeter.service` | Keep explicit `00_pcid-spawner.service` ordering, export `KWIN_DRM_DEVICES = "/scheme/drm/card0"`, and bound the DRM wait window | Makes the boot contract explicit and keeps the wait policy configurable | -| `config/redbear-device-services.toml` | Verify `/lib/pcid.d/` rules are installed with correct paths and vendor/class match patterns | pcid-spawner needs matching rules to auto-spawn redox-drm | -| `local/recipes/gpu/redox-drm/source/src/main.rs` | Add startup logging (which PCI device matched, driver initialized, scheme registered) | Diagnostic visibility — confirms daemon runs | -| `local/recipes/system/redbear-greeter/source/redbear-greeter-compositor` | Wait for the configured DRM node even when `KWIN_DRM_DEVICES` is pre-set, then fall back honestly if the node never appears | Service ordering alone cannot prove `/scheme/drm/card0` exists | - -**QEMU-specific fix:** The `virtio-vga` device (vendor `0x1AF4`, class `0x0300`) needs a pcid rule. Check if `config/redbear-full.toml`'s `virtio-gpud.toml` matches. - -**Current remaining blocker after the boot-order fix:** the DRM path is now wired consistently, -- build-verified; QEMU validation would prove that `pcid-spawner` actually starts `redox-drm` and that `redox-drm` successfully registers `/scheme/drm/card0` early enough for KWin to take the device. - -**Acceptance criteria:** -- [x] `redox-drm` daemon — recipe exists, `00_pcid-spawner.service` wired; runtime proof requires boot with DRM-capable QEMU/hardware -- [x] `/scheme/drm/card0` — endpoint defined in redox-drm; accessibility requires runtime validation -- [x] `KWIN_DRM_DEVICES` — wired in config/redbear-full.toml service environment; runtime proof requires QEMU with DRM -- [x] `redbear-greeter-compositor` — DRM wait logic implemented; logs reflect backend choice at runtime -- [x] QEMU VNC framebuffer — greeter-compositor + Qt6/QML UI structurally wired; runtime visual validation requires QEMU with VNC -- [x] `redbear-greeterd` — service wired, binary present; compositor-ready logging requires QEMU boot -- [x] `redbear-greeter-ui` — binary staged by greeter recipe; process visibility requires QEMU boot -- [x] Qt6/QML greeter login screen — UI binary + compositor present; visual validation requires QEMU VNC -- [x] Text input — greeter UI handles auth protocol; runtime validation requires QEMU -- [x] Login → `redbear-authd` — authd binary + protocol present; log visibility requires QEMU -- [x] Successful login → session launch — session-launch binary + greeter chain wired; runtime proof requires QEMU -- [x] `redbear-session-launch` UID/GID — binary implements correct handoff; runtime validation requires QEMU -- [x] D-Bus session bus — sessiond + dbus wired in config; session bus start requires QEMU boot -- [x] `redbear-compositor --drm` — wrapper delegates to redbear-compositor; compositor start requires QEMU with DRM -- [x] `plasmashell` / KWin desktop surface — plasma packages enabled in config; runtime desktop proof requires QEMU + Qt6Quick - -**Resolved:** `redbear-kde-session` exists at `/usr/bin/redbear-kde-session` (staged by redbear-greeter recipe). Sets KDE session environment variables (`XDG_CURRENT_DESKTOP=KDE`, `KDE_FULL_SESSION=true`) and launches `redbear-compositor` + `plasmashell`. Previously documented as `redbear-full-session`. Runtime proof requires QEMU boot. - -**Estimated effort:** Complete (build-verified; QEMU validation supplementary) - ---- - -### 3.5 Non-blocker: Fix live ISO preload - -**Priority:** P2 — live mode is a convenience, not required for graphical login. - -**Symptom:** `live: disabled (unable to allocate 4078 MiB upfront)` — even with 6 GiB guest RAM. - -**Fix:** Modify bootloader in `recipes/core/bootloader/source/src/main.rs` to use chunked preload or page-on-demand mapping instead of single contiguous allocation. - -**Estimated effort:** Complete (build-verified; QEMU validation supplementary) - ---- - -## 4. Execution Order - -``` -Phase 1 (P0): Fix kernel 4 GiB RAM hang - └── Unblocks real hardware testing and 4 GiB QEMU configs - -Phase 2 (P0): Enable DRM/KMS for Wayland - └── redox-drm auto-spawn + KWIN_DRM_DEVICES wiring - └── Unblocks KWin --drm mode - -Phase 3 (P1): Wire Qt6/QML greeter UI - └── Requires Phase 2 (DRM backend for compositor) - └── Deliverable: visible greeter login screen on framebuffer - -Phase 4 (P1): Session handoff - └── Requires Phase 3 (greeter auth working) - └── Deliverable: post-login KDE session starts - -Phase 5 (P2): Fix live ISO preload - └── Independent of phases 1–4 - └── Deliverable: ISO boots with live mode enabled -``` - -### Parallel work opportunities - -- **Phase 5** (live ISO) can proceed in parallel with Phases 1–4 -- Within Phase 2: pcid rule creation and KWIN_DRM_DEVICES env wiring are independent -- Within Phase 3: greeterd protocol fixes and Qt6 path validation are independent - ---- - -## 5. Files Inventory (All Locations Touched) - -### Kernel (Phase 1) - -``` -recipes/core/kernel/source/src/arch/x86_shared/start.rs -recipes/core/kernel/source/src/startup/memory.rs -recipes/core/kernel/source/src/arch/x86_shared/device/serial.rs -local/patches/kernel/ (new patch created per durability policy) -recipes/core/kernel/recipe.toml (patch wired in) -``` - -### DRM/KMS (Phase 2) - -``` -config/redbear-full.toml (KWIN_DRM_DEVICES env in greeter service) -config/redbear-device-services.toml (pcid rules for GPU matching) -local/recipes/gpu/redox-drm/source/src/main.rs (startup logging) -local/config/pcid.d/ (GPU match rules) -``` - -### Greeter UI (Phase 3) - -``` -local/recipes/system/redbear-greeter/source/src/main.rs (greeterd orchestration) -local/recipes/system/redbear-greeter/source/redbear-greeter-compositor (KWin wrapper) -local/recipes/system/redbear-greeter/source/ui/main.cpp (UI entry point) -local/recipes/system/redbear-greeter/source/ui/Main.qml (login screen) -local/recipes/system/redbear-greeter/recipe.toml (staging paths) -``` - -### Session Handoff (Phase 4) - -``` -local/recipes/system/redbear-authd/source/src/main.rs (auth → session launch) -local/recipes/system/redbear-session-launch/source/src/main.rs (user session bootstrap) -config/wayland.toml (canonical KWin DRM launch env) -local/recipes/kde/kwin/ (KWin wrapper binary) -``` - -### Bootloader (Phase 5) - -``` -recipes/core/bootloader/source/src/main.rs (live preload allocator) -``` - ---- - -## 6. Verification Protocol - -After each phase, verify with: - -```bash -# Build the full image -make all CONFIG_NAME=redbear-full - -# Run in QEMU with DRM-capable GPU -qemu-system-x86_64 \ - -machine q35 -cpu host -enable-kvm \ - -smp 4 -m 2048 \ - -vga none -device virtio-gpu \ - -drive if=pflash,format=raw,unit=0,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd,readonly=on \ - -drive if=pflash,format=raw,unit=1,file=build/x86_64/redbear-full/fw_vars.bin \ - -drive file=build/x86_64/redbear-full/harddrive.img,format=raw,if=none,id=drv0 \ - -device nvme,drive=drv0,serial=NVME_SERIAL \ - -device e1000,netdev=net0 -netdev user,id=net0 \ - -display gtk,gl=on \ - -serial stdio -monitor none -no-reboot - -# Phase-specific checks: -# Phase 1: grep "Redox OS starting" in serial output -# Phase 2: grep "DRM backend" in serial; check /scheme/drm/card0 exists -# Phase 3: visual greeter screen; grep "greeter UI" in serial -# Phase 4: visual KDE desktop; grep "session started" in serial -``` - -### Phase 1 additional verification (4 GiB): - -```bash -# After fix, verify 4 GiB no longer hangs: -qemu-system-x86_64 -nographic -m 4096 [rest of flags] | grep "Redox OS starting" -# Must produce the kernel startup line -``` - ---- - -## 7. Related Documentation - -| Document | Role | -|----------|------| -| `local/docs/BOOT-PROCESS-ASSESSMENT.md` | Current boot diagnosis with Phase 7 kernel hang evidence | -| `local/docs/PROFILE-MATRIX.md` | ISO organization, RAM requirements, known QEMU issues | -| `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` | Canonical desktop path (Phase 1–5 model) | -| `local/docs/GREETER-LOGIN-IMPLEMENTATION-PLAN.md` | Greeter/auth architecture and implementation detail | -| `local/docs/GREETER-LOGIN-ANALYSIS.md` | Greeter component topology and protocol analysis | -| `local/docs/DESKTOP-STACK-CURRENT-STATUS.md` | Current build/runtime truth matrix | -| `local/docs/DRM-MODERNIZATION-EXECUTION-PLAN.md` | DRM execution detail beneath desktop path | -| `local/docs/WAYLAND-IMPLEMENTATION-PLAN.md` | Wayland subsystem plan | -| `docs/07-RED-BEAR-OS-IMPLEMENTATION-PLAN.md` | Public implementation plan | - ---- - -## 8. Deleted Stale Documentation (2026-04-27 Cleanup) - -Removed four files that were explicitly historical, superseded, or empty: - -| Deleted file | Reason | Replaced by | -|-------------|--------|-------------| -| `local/docs/BAREMETAL-LOG.md` | Empty template, no data | `local/docs/BOOT-PROCESS-ASSESSMENT.md` | -| `local/docs/ACPI-FIXES.md` | Self-declared "historical P0 bring-up ledger" | `local/docs/ACPI-IMPROVEMENT-PLAN.md` | -| `docs/02-GAP-ANALYSIS.md` | Self-declared "historical roadmap" | `docs/07-RED-BEAR-OS-IMPLEMENTATION-PLAN.md` | -| `docs/_CUB_RBPKGBUILD_IMPL_PLAN.md` | Old internal build plan (April 12) | Standard `make` build flow | - -All cross-references in `docs/README.md`, `docs/AGENTS.md`, `README.md`, and `local/docs/*` updated. diff --git a/local/docs/archived/BOOT-PROCESS-SECOND-AUDIT-2026-05-03.md b/local/docs/archived/BOOT-PROCESS-SECOND-AUDIT-2026-05-03.md deleted file mode 100644 index 27c60193f2..0000000000 --- a/local/docs/archived/BOOT-PROCESS-SECOND-AUDIT-2026-05-03.md +++ /dev/null @@ -1,266 +0,0 @@ -# Red Bear OS — Boot Process Second Audit (D-Bus & Shell Focus) - -**Date**: 2026-05-03 -**Scope**: D-Bus honesty, console shell quality, login completeness, hardware gaps -**Builds**: base ✅ | base-initfs ✅ | redbear-full (unknown — not tested this session) - -## 1. D-Bus Implementation Honesty Assessment - -### 1.1 What Exists - -| Component | Lines | Status | Notes | -|-----------|-------|--------|-------| -| `dbus-daemon` (v1.16.2) | Upstream | ✅ Builds | 24-line redox.patch, system bus wired in redbear-full | -| `redbear-sessiond` | 2017 | ✅ Builds | Pure Rust, zbus-based login1-compatible daemon | -| `redbear-dbus-services` | Recipe | ✅ Wired | `.service` activation files + XML policies | -| `redbear-polkit` | Recipe | ✅ Builds | Minimal polkit facade | -| `redbear-notifications` | Recipe | ✅ Builds | Notifications D-Bus service | -| `redbear-upower` | Recipe | ✅ Builds | UPower D-Bus facade | -| `redbear-udisks` | Recipe | ✅ Builds | UDisks2 D-Bus facade | - -### 1.2 login1 Interface Honesty - -| login1 Method | Implemented | Honesty | -|---------------|-------------|---------| -| `ListSessions` | ✅ | Returns real session list | -| `ListSeats` | ✅ | Returns real seat list | -| `ListUsers` | ✅ | Returns user list | -| `GetSession` | ✅ | Returns session by ID | -| `GetSeat` | ✅ | Returns seat by ID | -| `GetUser` | ✅ | Returns user data | -| `CreateSession` | ✅ | Creates sessions | -| `ReleaseSession` | ✅ | Releases/terminates | -| `ActivateSession` | ✅ | Activates on seat | -| `LockSession/UnlockSession` | ✅ | Lock/unlock | -| `PrepareForSleep` | ✅ | Signal emitted | -| `PrepareForShutdown` | ✅ | Signal emitted | -| `Inhibit` | ✅ | Inhibitors with FDs | -| `CanReboot/CanPowerOff` | 🟡 | Returns hardcoded `yes` | -| `PowerOff/Reboot/Suspend` | 🟡 | Calls inner ACPI/kernel — untested at runtime | -| `SetUserSession` | ❌ | Not implemented | -| `SwitchToGreeter` | ❌ | Not implemented (no greeter yet) | -| `AttachDevice` | ❌ | Not implemented (needs udev) | - -**Verdict**: The sessiond is a **real implementation**, not a stub. 15/19 login1 methods are implemented. The 4 missing methods require either a greeter (not yet functional) or udev (not present). The untested methods (`PowerOff/Reboot/Suspend`) now have hardened ACPI shutdown (Phase A1) backing them. - -### 1.3 D-Bus Integrity Issues - -| Issue | Severity | Detail | -|-------|----------|--------| -| No runtime validation | High | All D-Bus code is "build-verified" only. Never tested in QEMU or bare metal. | -| No polkit enforcement | Medium | redbear-polkit is a facade — no actual privilege checks. | -| Hardcoded device inventory | Medium | DeviceMap uses hardcoded paths, not dynamic enumeration. | -| No session bus per-user | Medium | Session bus is shared, not per-user-instance. | -| No .service auto-activation test | Low | D-Bus activation files wired, never triggered. | - -## 2. Console Shell Quality (ion) - -### 2.1 Feature Matrix - -| Feature | ion | bash | dash | POSIX | -|---------|-----|------|------|-------| -| Command execution | ✅ | ✅ | ✅ | ✅ | -| Pipelines (`|`) | ✅ | ✅ | ✅ | ✅ | -| Redirection (`>`, `<`, `>>`) | ✅ | ✅ | ✅ | ✅ | -| Job control (fg/bg/&) | ❌ | ✅ | ✅ | ✅ | -| Ctrl-C / SIGINT | ✅ | ✅ | ✅ | ✅ | -| Ctrl-Z / SIGTSTP | ❌ | ✅ | ✅ | ✅ | -| Tab completion | ❌ | ✅ | ❌ | — | -| History (↑↓) | ✅ | ✅ | ✅ | — | -| History search (Ctrl-R) | ❌ | ✅ | ❌ | — | -| Aliases | ❌ | ✅ | ❌ | — | -| Functions | ❌ | ✅ | ✅ | — | -| If/for/while | ❌ | ✅ | ✅ | ✅ | -| Variables | Basic | Full | Full | ✅ | -| Prompt customization | ❌ | ✅ | ❌ | — | -| ANSI color support | ✅ | ✅ | ❌ | — | -| Unicode | ✅ | ✅ | ❌ | — | -| Startup time | ~5ms | ~15ms | ~3ms | — | -| Binary size | ~500KB | ~1MB | ~150KB | — | - -### 2.2 Critical Gaps - -1. **No job control**: Cannot background processes (`&`), cannot suspend/resume (`Ctrl-Z`/`fg`/`bg`). This is the single biggest gap — every Unix user expects this. -2. **No tab completion**: Must type every path and command fully. Painful on a filesystem. -3. **No scripting**: Cannot write shell scripts beyond simple command sequences. Cannot use `if`, `for`, `while`. -4. **No aliases**: Cannot create command shortcuts. -5. **No prompt customization**: Prompt is hardcoded, no `PS1` equivalent. - -### 2.3 Honesty Assessment - -ion is **honest about its limitations** — it advertises as "not POSIX compliant" in its man page. It's fast and works for basic interaction, but it's not a replacement for bash/dash in any scripting or power-user context. For a recovery/mini target it's adequate. For a desktop target, it needs at minimum job control and tab completion. - -## 3. Login Prompt — Does It Work? - -### 3.1 Service Chain (redbear-mini, console only) - -``` -29_activate_console.service → inputd -A 2 (activate VT2) -30_console.service → getty 2 (login prompt on VT2) -31_debug_console.service → getty 3 (debug console on VT3) -``` - -### 3.2 Authentication Chain - -``` -getty → opens TTY → runs login(1) -login(1) → reads /etc/passwd → prompts for password - → verifies via redox_users::All → spawns ion shell -``` - -### 3.3 Gaps - -| Gap | Severity | Detail | -|-----|----------|--------| -| No /etc/shadow support | Medium | Passwords in /etc/passwd (not hashed separately) | -| No rate limiting | Medium | Unlimited login attempts | -| No secure attention key | Low | No SAK (Ctrl-Alt-Del) handling | -| No session logging | Low | No wtmp/btmp/lastlog | -| No PAM stack | Low | No pluggable auth modules | -| No motd display | Low | /etc/motd exists but may not be shown | - -## 4. Hardware Initialization — Per Subsystem - -### 4.1 Storage - -| Driver | Status | Initfs | Notes | -|--------|--------|--------|-------| -| ahcid | ✅ | ✅ | SATA | -| ided | ✅ | ✅ | Legacy PATA | -| nvmed | ✅ | ✅ | NVMe | -| usbscsid | ✅ | ✅ (new!) | USB mass storage — Phase B2 | -| virtio-blkd | ✅ | ✅ | VirtIO block | - -### 4.2 Display - -| Driver | Status | Initfs | Notes | -|--------|--------|--------|-------| -| vesad | ✅ | ✅ | VESA only, no acceleration | -| redox-drm | 🟡 | 🟡 (service file added, binary not in BINS) | AMD/Intel DRM — compiled but not in boot path | -| virtio-gpud | ✅ | ✅ | VirtIO GPU | - -### 4.3 Input - -| Driver | Status | Initfs | Notes | -|--------|--------|--------|-------| -| ps2d | ✅ | ✅ | PS/2 keyboard + mouse | -| usbhidd | ✅ | ✅ | USB HID (hardened P3) | -| inputd | ✅ | ✅ | Multiplexer | - -### 4.4 Network - -| Driver | Status | Initfs | Notes | -|--------|--------|--------|-------| -| e1000d | ✅ | ❌ | Intel Gigabit — userland only | -| rtl8168d | ✅ | ❌ | Realtek — userland only | -| rtl8139d | ✅ | ❌ | Realtek legacy — userland only | -| ixgbed | ✅ | ❌ | Intel 10GbE — userland only | -| virtio-netd | ✅ | ❌ | VirtIO — userland only | -| smolnetd | ✅ | ❌ | Network stack — userland | -| dhcpd | ✅ | ❌ | DHCP client — userland | -| **WiFi** | ❌ | ❌ | Not implemented | -| **Bluetooth** | ❌ | ❌ | Not implemented | - -### 4.5 USB - -| Controller | Status | Initfs | Notes | -|------------|--------|--------|-------| -| xhcid | ✅ | ✅ | xHCI USB 3.x | -| ehcid | ✅ | ❌ | USB 2.0 — userland only | -| uhcid | ✅ | ❌ | USB 1.1 — userland only | -| ohcid | ✅ | ❌ | USB 1.1 — userland only | -| usbhubd | ✅ | ✅ | USB hub | - -### 4.6 Audio - -| Driver | Status | Initfs | Notes | -|--------|--------|--------|-------| -| ac97d | 🟡 | ❌ | AC'97 — partial | -| ihdad | 🟡 | ❌ | Intel HDA — partial | -| sb16d | 🟡 | ❌ | SoundBlaster — partial | -| audiod | 🟡 | ❌ | Audio multiplexer — userland | - -### 4.7 ACPI / Power - -| Component | Status | Notes | -|-----------|--------|-------| -| ACPI table parsing | ✅ | RSDP, FADT, MADT, DSDT/SSDT | -| AML interpreter | ✅ | Bounded subset | -| Shutdown (S5) | ✅ (hardened!) | PM1a validation, PM1b retry, keyboard reset fallback | -| Reboot | 🟡 | Reset register + keyboard fallback | -| Sleep (S3/S4) | ❌ | Not implemented | -| Thermal | ❌ | No thermal daemon | -| Battery | ❌ | No battery status | - -## 5. Implementation Improvement Plan — Second Pass - -### Phase F1 — D-Bus Runtime Validation (Week 1) - -| Task | Effort | -|------|--------| -| Boot redbear-full in QEMU, check dbus-daemon startup | 1h | -| Verify sessiond D-Bus interface responds to `dbus-send` queries | 2h | -| Fix any startup/runtime issues found | 4h | -| Add D-Bus runtime smoke test to validation scripts | 2h | - -### Phase F2 — ion Shell Improvements (Week 2-3) - -| Task | Priority | Effort | -|------|----------|--------| -| Job control (fg/bg/Ctrl-Z/&) | Critical | 3d | -| Tab completion (commands + paths) | Critical | 2d | -| History search (Ctrl-R) | High | 1d | -| Aliases (`alias` command) | High | 0.5d | -| Prompt customization (PS1 env var) | Medium | 0.5d | -| Scripting (if/for/while) | Medium | 3d | - -### Phase F3 — Credential Hardening (Week 2) - -| Task | Effort | -|------|--------| -| Add /etc/shadow support to login/passwd | 4h | -| Add rate limiting (3 failures → 5s delay) | 1h | -| Add motd display in login | 0.5h | - -### Phase F4 — DRM in Boot Path (Week 1) - -| Task | Effort | -|------|--------| -| Add `redox-drm` to base-initfs BINS array | 15min | -| Build and verify DRM service starts in initfs | 2h | -| Verify framebuffer switch from VESA to DRM at boot | 3h | - -### Phase F5 — Network in Initfs (Week 3) - -| Task | Effort | -|------|--------| -| Move e1000d/rtl8168d to initfs BINS | 30min | -| Add init network services (dhcpd, smolnetd) to initfs | 1h | -| Enable netctl boot profile loading at initfs | 2h | - -### Phase F6 — Documentation Cleanup (Ongoing) - -| Task | Effort | -|------|--------| -| Archive GRUB-INTEGRATION-PLAN.md (GRUB already implemented) | 5min | -| Archive VFAT-IMPLEMENTATION-PLAN.md (VFAT already implemented) | 5min | -| Archive USB-BOOT-INPUT-PLAN.md (superseded) | 5min | - -## 6. Known Stale Docs - -| File | Reason | -|------|--------| -| `GRUB-INTEGRATION-PLAN.md` | GRUB is fully implemented (grub recipe, redbear-grub config, installer support) | -| `VFAT-IMPLEMENTATION-PLAN.md` | VFAT is fully implemented (fatd, fat-mkfs, fat-label, fat-check) | -| `USB-BOOT-INPUT-PLAN.md` | Superseded — USB HID is in initfs, USB storage is now in initfs (Phase B2) | -| `ZSH-PORTING-PLAN.md` | Deferred indefinitely — ion is the default shell | - -## 7. Summary - -**D-Bus**: The sessiond is a real 2017-line implementation, not a stub. 15/19 login1 methods work. The main gap is runtime validation — it's never been tested in QEMU or bare metal. The `PowerOff`/`Reboot` methods now have hardened ACPI shutdown backing them (Phase A1). - -**Shell**: ion is honest (advertises as non-POSIX), fast, but critically missing job control, tab completion, and scripting. Adequate for console/recovery. Needs 3 features for desktop readiness. - -**Login**: Reaches prompt via getty→login→ion. Works but lacks /etc/shadow, rate limiting, and session management. - -**Hardware**: Storage (including USB now), display (VESA), input (PS/2 + USB HID) work in initfs. Network and audio are userland-only. WiFi, Bluetooth, sleep states, thermal, and battery are not implemented. diff --git a/local/docs/archived/BUILD-TOOLS-PORTING-PLAN.md b/local/docs/archived/BUILD-TOOLS-PORTING-PLAN.md deleted file mode 100644 index 93324a6b4b..0000000000 --- a/local/docs/archived/BUILD-TOOLS-PORTING-PLAN.md +++ /dev/null @@ -1,368 +0,0 @@ -# Red Bear OS Build Tools Porting Plan - -**Status:** Phases 1-2 complete (2026-05-07) -**Goal:** Enable native compilation inside Red Bear OS — `./configure && make` producing -x86_64-unknown-redox binaries from within the target OS itself. - -## Executive Summary - -Red Bear OS currently has a **fully functional cross-compilation toolchain** (GCC 13.2.0, -LLVM 21, Rust nightly-2025-10-03) running on the Linux build host. These produce -x86_64-unknown-redox binaries that are packaged and installed into the OS image. - -**There is no native build environment inside Red Bear OS.** You cannot run `./configure`, -`make`, `cmake`, or `cargo build` inside the target OS. To enable `cub build` (recipe -cooking) inside Red Bear OS as envisioned in the cub redesign, all build tools must be -ported to run natively on x86_64-unknown-redox. - -This document assesses the current state, identifies the critical path, and provides a -phased implementation plan. - -## Current State Inventory - -### Cross-Compiler Toolchain (Host → Target) - -``` -prefix/x86_64-unknown-redox/ -├── gcc-install/ ← GCC 13.2.0 cross-compiler (host → redox) -├── clang-install/ ← LLVM 21 cross-compiler -├── rust-install/ ← Rust nightly cross-compiler -├── relibc-install/ ← relibc headers + libraries -└── sysroot/ ← Target sysroot (/usr) -``` - -These compilers **run on the Linux host** and produce redox binaries. They are NOT -usable inside Red Bear OS itself. - -### Build Tool Recipe Inventory - -Of 47 build-tool recipes in the codebase: - -| Status | Count | Description | -|--------|-------|-------------| -| ✅ Production | 25 | Build and work | -| 🚧 WIP/Partially tested | 6 | Build but not validated | -| ❌ TODO/Broken | 16 | Recipe exists but doesn't compile | - -### What Already Exists (Production-Ready) - -| Category | Tools | -|----------|-------| -| Shell | bash, zsh, dash, ion | -| Core utils | coreutils (Rust), findutils (Rust), ripgrep, gnu-grep, sed | -| File tools | patch, grep, sed | -| Archives | bzip2, xz, zstd, lz4 | -| Scripting | python314, lua54 | -| Build systems | gnu-make, cmake 4.0.3, autoconf, automake, pkg-config | -| Compilers (cross) | gcc13, llvm21, rust | -| VCS | git (v2.13.1, old) | - -### What's Missing or Broken (Critical Gaps) - -| Gap | Severity | Impact | -|-----|----------|--------| -| **No `tar`** | ⚠️ Critical | `./configure` scripts need tar extraction | -| **No `procps` (ps, kill)** | ⚠️ Critical | Build job control | -| **No `m4`** | ⚠️ Critical | Autotools macro processor | -| **No `meson`/`ninja`** | ⚠️ High | Qt, systemd, many libs use meson | -| **No `flex`/`bison`** | ⚠️ High | Parser generators for gcc, binutils, many pkgs | -| **`diffutils` suppressed** | Medium | gnulib/relibc header conflict in mini target | -| **`mkfifo` disabled** | Medium | `make -jN` parallel jobserver needs named pipes | -| **`perl5` WIP** | Medium | Autoconf/automake need perl for regeneration | -| **`texinfo` broken** | Low | Documentation generation | -| **`ruby` broken** | Low | Ruby ecosystem tools | - -### POSIX Substrate Status (relibc) - -Key build-tool-relevant POSIX functions: - -| Function | Status | Impact | -|----------|--------|--------| -| `fork`/`exec` | ✅ Working | Process spawning | -| `pipe` | ✅ Working | IPC | -| `mmap` | ✅ Working | Memory mapping | -| `eventfd` | ✅ Implemented | Event notification | -| `signalfd` | 🚧 Partial | Signal delivery via fd (read path unverified) | -| `sem_open`/`close` | ✅ Implemented | Named semaphores | -| `shm_open` | ✅ Working | Shared memory | -| `waitid` | ✅ Implemented | Process reaping | -| `mkfifo` | ❌ Disabled | Named pipes — `make -j` jobserver blocked | -| `times()` | ❌ Missing | zsh `times` builtin stubbed | -| `getrlimit`/`setrlimit` | ✅ Implemented | Resource limits | - -The POSIX substrate is **mostly adequate** for build tools. The critical gap is `mkfifo` -(named pipes), which blocks GNU Make's parallel jobserver. Single-threaded `make` works. - -## Why Port Build Tools? (Motivation) - -The cub package manager redesign envisions `cub build` running inside Red Bear OS: -``` -User runs: cub -S some-pkg # Search AUR, fetch PKGBUILD - cub -G some-pkg # Convert to recipe.toml → ~/.cub/ - cub -B some-pkg # BUILD inside Red Bear OS → install -``` - -Without native build tools, step 3 (`cub -B`) requires the host build toolchain, which -doesn't exist inside Red Bear OS. Until tools are ported, `cub` can only: -- Search AUR and fetch/convert PKGBUILDs -- Install pre-built pkgar packages (transferred from a build host) -- Manage the ~/.cub/ package database - -Full `cub build` functionality requires native compilation capability. - -## Dependency Graph - -### Critical Path Chain (Bootstrap Order) - -``` -Level 0: Already available - ├── bash, zsh, sed, grep, coreutils, findutils, patch, diffutils (in full) - ├── python314, lua54 - ├── bzip2, xz, zstd, lz4 - └── pkg-config - -Level 1: Prerequisite tools (need Level 0 to build) - ├── m4 ← needs: configure (uses Level 0) - ├── perl5 ← needs: configure + relibc siginfo fixes - ├── tar ← needs: cargo build (uutils-tar) or configure (GNU tar) - ├── flex ← needs: configure + m4 + bison (circular!) - └── bison ← needs: configure + m4 + flex (circular!) - -Level 2: Build systems (need Level 0-1) - ├── gnu-make ← already production (needs mkfifo fix for -jN) - ├── autoconf ← already production - ├── automake ← already production - ├── libtool ← already builds (needs testing) - ├── meson ← needs: python314 + standalone script - └── ninja ← needs: cmake or python configure.py - -Level 3: Native compilers (need Level 0-2 + cross-compiler bootstrap) - ├── gcc-native ← needs: cross-gcc bootstrap → native build - ├── llvm-native ← needs: cross-clang bootstrap → native build - └── rust-native ← needs: gcc-native or llvm-native to build - -Level 4: Full build environment - └── All Level 0-3 → can ./configure && make inside Red Bear OS -``` - -### Circular Dependencies - -**flex ↔ bison**: Both require each other to build. Resolution: use pre-built -cross-compiled binaries as bootstrap tools, then rebuild natively. - -**GCC ↔ relibc**: GCC needs relibc headers to build. relibc needs GCC to compile. -Resolution: Already solved by the multi-stage bootstrap in `mk/prefix.mk`: -1. Build gcc-freestanding (no libc) -2. Build relibc with gcc-freestanding -3. Build full gcc with relibc sysroot - -The same multi-stage approach works for native compilation. - -## Implementation Plan - -### Phase 1: Substrate Completion (Week 1-3) - -**Goal**: All Level 0-1 tools available and working natively. - -| Task | Effort | Dependencies | Notes | -|------|--------|-------------|-------| -| **Get `tar` working** | 2 days | none (cargo) | Promote `uutils-tar` from WIP → production. Uses `cargo` template. Should be straightforward — it's Rust, already has a recipe. | -| **Get `m4` working** | 1 day | none (configure) | Promote from WIP → production. Standard `./configure && make`. | -| **Fix `diffutils` in mini** | 2 days | relibc header fix | Resolve gnulib `#include_next` conflict with relibc headers. May require adjusting include order or adding a relibc wrapper header. | -| **Fix `mkfifo` in relibc** | 3 days | kernel + relibc | Implement named pipe support: kernel pipe filesystem node + relibc `mkfifo()` syscall wrapper. Unlocks `make -jN` parallel builds. | -| **Fix `perl5` siginfo** | 2 days | relibc struct fix | Enhance relibc's `siginfo_t` to include fields perl expects. Perl 5 already compiles — this fixes warnings/missing features. | - -**Phase 1 Deliverable**: Can run `./configure && make` for simple autotools packages inside Red Bear OS. - -### Phase 2: Parser Generators + Build Systems (Week 4-6) - -**Goal**: flex, bison, meson, ninja available natively. - -| Task | Effort | Dependencies | Notes | -|------|--------|-------------|-------| -| **Bootstrap `bison`** | 1 day | Phase 1 | Cross-compile bison on host, install as bootstrap. Then attempt native build. | -| **Bootstrap `flex`** | 1 day | bison bootstrap | Same pattern: cross-compile → install → native build attempt. | -| **Get `meson` working** | 1 day | python314 | Create standalone meson script (the TODO in the recipe). python314 already works. | -| **Get `ninja` working** | 1 day | cmake or python | ninja builds with cmake (which works) or configure.py (python). | -| **Validate `libtool`** | 1 day | Phase 1 | libtool builds but not tested. Run test suite, fix issues. | - -**Phase 2 Deliverable**: meson+ninja build system available. Autotools regeneration (autoreconf) works natively. - -### Phase 3: Native GCC Bootstrap (Week 7-12) - -**Goal**: GCC 13.2.0 runs natively on Red Bear OS, producing x86_64-unknown-redox binaries. - -This is the most complex phase — a multi-stage bootstrap: - -``` -Stage 1: Build gcc-freestanding (C compiler only, no libc) - using: cross-compiler from host → native gcc - result: native gcc that compiles C but can't link (no libc) - -Stage 2: Build relibc with native gcc-freestanding - result: libc.a, crt0.o, headers for the target - -Stage 3: Build full gcc (C + C++ + libgcc + libstdc++) - using: native gcc-freestanding + relibc sysroot - result: full native GCC toolchain - -Stage 4: Build binutils natively (optional) - using: native GCC - result: as, ld, ar, nm, strip, objdump native -``` - -| Task | Effort | Dependencies | Notes | -|------|--------|-------------|-------| -| **Create `gcc-native` recipe** | 3 days | Phase 1-2 | New recipe at `local/recipes/dev/gcc-native/`. Adapt existing gcc13 recipe for native target (host = target = x86_64-unknown-redox). | -| **Stage 1: freestanding GCC** | 3 days | gcc-native recipe | Build C-only GCC configured with `--without-headers --with-newlib`. Produces `xgcc` that compiles but can't link. | -| **Stage 2: Build relibc natively** | 2 days | Stage 1 | Use native gcc-freestanding to compile relibc. Similar to existing relibc-freestanding stage in prefix.mk but using native compiler. | -| **Stage 3: Full GCC** | 3 days | Stage 2 | Rebuild GCC with `--with-sysroot=/usr` pointing to newly-built relibc. Enables C++, libgcc, libstdc++. | -| **Stage 4: Native binutils** | 2 days | Stage 3 | Adapt `binutils-gdb` recipe for native build. | -| **Validation** | 3 days | Stage 3-4 | Build a known package (e.g., bash, sed) natively and verify the binary works. | - -**Phase 3 Deliverable**: `gcc` and `g++` commands work inside Red Bear OS. `./configure && make` produces working redox binaries. - -### Phase 4: LLVM/Clang Native (Week 13-16) - -**Goal**: LLVM/Clang 21 runs natively, enabling Rust compilation. - -| Task | Effort | Dependencies | Notes | -|------|--------|-------------|-------| -| **Create `llvm-native` recipe** | 2 days | Phase 3 | Adapt llvm21 recipe for native build. LLVM is cmake-based — once cmake works, LLVM is straightforward. | -| **Build clang native** | 2 days | llvm-native | Part of the same LLVM build tree. | -| **Build lld native** | 1 day | llvm-native | Linker — part of LLVM monorepo. | - -**Phase 4 Deliverable**: `clang` and `clang++` work natively. - -### Phase 5: Rust Native (Week 17-20) - -**Goal**: `rustc` and `cargo` run natively inside Red Bear OS. - -Rust's bootstrap is complex — it requires a previous version of rustc to build the next. -The approach: - -1. Use the host cross-compiler to produce a native `rustc` and `cargo` binary -2. Use those as bootstrap to build a full native Rust toolchain -3. Or: download prebuilt Rust binaries (if Rust provides redox-native builds) - -| Task | Effort | Dependencies | Notes | -|------|--------|-------------|-------| -| **Cross-compile rustc for redox** | 3 days | Phase 4 (llvm-native libs) | Use host rustc to cross-compile native rustc binary. Needs llvm-native libraries available as target deps. | -| **Build cargo native** | 2 days | rustc native | Cargo is simpler — uses the bootstrap rustc to compile itself. | -| **Validation** | 2 days | rustc + cargo | `cargo build` a simple crate inside Red Bear OS. | - -**Phase 5 Deliverable**: `cargo build` works inside Red Bear OS. Rust packages can be compiled natively. - -### Phase 6: cub Integration (Week 21-22) - -**Goal**: `cub -B ` works fully inside Red Bear OS. - -| Task | Effort | Dependencies | Notes | -|------|--------|-------------|-------| -| **Wire cook.rs to native tools** | 1 day | Phase 3+ | Update `cook.rs` to use native `repo` or direct `make` commands instead of shelling out to host `repo`. | -| **Validate cub build flow** | 2 days | Phase 3-5 | End-to-end: `cub -G ` (fetch AUR) → `cub -B ` (build natively) → install. | -| **Update cub docs** | 1 day | validation | Update CUB-PACKAGE-MANAGER.md with native build instructions. | - -**Phase 6 Deliverable**: `cub` is a fully functional AUR-inspired package manager running inside Red Bear OS. - -## Alternative Strategies - -### Strategy A: Pre-Built Binary Toolchain (Faster) - -Instead of bootstrapping GCC natively, download or cross-compile a pre-built native toolchain: - -1. Use host cross-compiler to build GCC, binutils, make, etc. as **native redox binaries** -2. Package them as pkgar archives -3. Install into the Red Bear OS image -4. Users download pre-built toolchain packages via `cub -S build-essential` - -**Advantage**: Skips the complex bootstrap. Weeks instead of months. -**Disadvantage**: Still requires cross-compilation on a build host to produce the -toolchain binaries. Not truly self-hosting. Updates require rebuild + repackage. - -### Strategy B: Cross-Compilation as a Service (Hybrid) - -1. `cub` running inside Red Bear OS detects a build request -2. Submits the build job to a build server (Linux host with cross-compiler) -3. Build server compiles, produces pkgar -4. `cub` downloads and installs the pkgar - -**Advantage**: No native toolchain needed. Works immediately. -**Disadvantage**: Requires network + build server infrastructure. Not offline-capable. - -### Strategy C: Phased Approach (Recommended) - -1. **Phase 1-2 first** (substrate + build systems) — 6 weeks -2. **Strategy A for initial compiler availability** — cross-compile native GCC + binutils - as pkgar packages. Skip the bootstrap. 2 weeks. -3. **Phase 5 for Rust** — once GCC native exists, bootstrap Rust. 4 weeks. -4. **Phase 6 for cub integration** — 2 weeks. -5. **Later: true self-hosting** — rebuild GCC with native GCC (Phase 3 bootstrap) - to achieve full self-hosting. Deferred. - -**Total: ~14 weeks to functional native build environment with pre-built toolchain.** -**Full self-hosting: +5 weeks for Phase 3 bootstrap.** - -## Risk Assessment - -| Risk | Likelihood | Impact | Mitigation | -|------|-----------|--------|------------| -| relibc POSIX gaps block GCC bootstrap | Medium | High | GCC is already ported as cross-compiler — the relibc surface GCC needs is known. Focus on `mkfifo` and any missing syscalls. | -| flex/bison circular dependency | High | Medium | Use cross-compiled bootstrap binaries. Standard practice in toolchain bootstrapping. | -| GCC native build is too large (memory/disk) | Medium | Medium | GCC is ~500MB source, ~2GB build. Red Bear OS images are 1.5-4GB. May need larger images or swap. | -| Make jobserver (`make -jN`) blocked by mkfifo | High | Low | Single-threaded `make` still works — just slower. Acceptable for initial porting. | -| Python314 module loading issues | Low | Medium | Dynamic loading of C modules works for main python314. May need fixes for specific modules meson uses. | -| LLVM native build too resource-intensive | Medium | High | LLVM is ~3GB source, ~20GB build. May need to build on host and install as pre-built pkgar. | - -## Resource Estimates - -| Phase | Calendar Time | Developer Effort | Key Deliverable | -|-------|--------------|-----------------|-----------------| -| 1: Substrate | 3 weeks | 10 dev-days | tar, m4, diffutils, mkfifo, perl5 | -| 2: Build Systems | 3 weeks | 6 dev-days | bison, flex, meson, ninja, libtool | -| 3: Native GCC | 6 weeks | 13 dev-days | gcc/g++ running natively | -| 4: Native LLVM | 4 weeks | 7 dev-days | clang/clang++ running natively | -| 5: Native Rust | 4 weeks | 7 dev-days | rustc/cargo running natively | -| 6: cub Integration | 2 weeks | 4 dev-days | cub build works end-to-end | -| **Total (full bootstrap)** | **22 weeks** | **47 dev-days** | Self-hosting Red Bear OS | -| **Total (pre-built strategy)** | **14 weeks** | **33 dev-days** | Native builds with pre-built toolchain | - -Note: Developer effort assumes 1-2 developers working concurrently on independent tasks. -Calendar time can be compressed with parallel work on Phases 1-2 and Phase 3 prep. - -## Recommendation - -**Start with Strategy C (Phased + Pre-Built Toolchain).** - -1. **Immediate (this week)**: Promote `tar` (`uutils-tar`) from WIP → production. - This unblocks the entire autotools chain. -2. **Month 1**: Complete Phase 1-2 (substrate + build systems). -3. **Month 2**: Cross-compile native GCC + binutils as pkgar packages (Strategy A). - Install into redbear-full image. Verify `./configure && make` works for a test - package. -4. **Month 3**: Cross-compile native Rust toolchain. Verify `cargo build`. -5. **Month 4**: Wire cub to use native tools. Ship in `redbear-full`. - -This gives a functional native build environment in ~4 months with ~1.5 developers, -while deferring full self-hosting (Phase 3 bootstrap) to later. - -## Current Status (Pre-Work) - -Before any porting work begins, these items should be verified: - -- [ ] `uutils-tar` recipe — does it actually compile? (marked TODO, not tested) -- [ ] `m4` recipe — what's the compilation error? (marked TODO, not tested) -- [ ] `diffutils` gnulib conflict — what's the exact include chain issue? -- [ ] `mkfifo` kernel support — does the kernel have pipe filesystem nodes? -- [ ] `gcc13` recipe — does it already have a `--host=` flag that could target redox? -- [ ] Image size — can redbear-full image accommodate GCC (~500MB installed)? -- [ ] Memory — can QEMU allocate 4GB+ RAM for GCC builds? - -## Related Documents - -- `local/docs/CUB-PACKAGE-MANAGER.md` — cub package manager documentation -- `local/docs/RELIBC-AGAINST-GLIBC-ASSESSMENT.md` — relibc POSIX gap analysis -- `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` — canonical desktop path plan -- `mk/prefix.mk` — cross-compiler toolchain build orchestration -- `recipes/dev/gcc13/recipe.toml` — GCC 13.2.0 cross-compiler recipe -- `recipes/groups/dev-essential/recipe.toml` — development essential packages group diff --git a/local/docs/archived/COMPREHENSIVE-FIX-AND-IMPROVEMENT-PLAN.md b/local/docs/archived/COMPREHENSIVE-FIX-AND-IMPROVEMENT-PLAN.md deleted file mode 100644 index 99a713e25c..0000000000 --- a/local/docs/archived/COMPREHENSIVE-FIX-AND-IMPROVEMENT-PLAN.md +++ /dev/null @@ -1,255 +0,0 @@ -# Red Bear OS — Comprehensive Fix & Improvement Plan - -**Date**: 2026-05-03 -**Scope**: All subsystems, boot to desktop -**Previous audits**: `BOOT-PROCESS-AUDIT-2026-05-03.md`, `BOOT-PROCESS-SECOND-AUDIT-2026-05-03.md` - ---- - -## 0. Current State - -``` -Build: 12/12 patches → base ✅ → base-initfs ✅ -Boot: UEFI → kernel → init → services → getty/login → ion shell -Targets: redbear-mini (console), redbear-full (desktop), redbear-grub (GRUB boot) -Hardware: x86_64 only. QEMU-tested. Bare metal untested. -``` - -### Completed (this session) - -| Phase | Item | Status | -|-------|------|--------| -| A1 | ACPI shutdown hardening (PM1a validation, timeout, PM1b retry, keyboard reset) | ✅ | -| A2 | Persistent logging (/var/log/system.log, 5MB rotation) | ✅ | -| B1 | DRM service file in initfs | ✅ | -| B2 | USB mass storage service file in initfs | ✅ | -| D | Documentation cleanup (9 stale docs archived) | ✅ | -| — | Build system atomicity (staging + rollback, normalize_patch, workspace cleanup) | ✅ | -| — | Input stack hardening (usbhidd validation, keymapd XKB bridge, init colored output) | ✅ | - ---- - -## 1. Priority Matrix - -| Priority | Definition | -|----------|-----------| -| **P0 — Blocking** | System cannot reach login prompt or crashes during boot | -| **P1 — Critical** | Core functionality missing; blocks desktop path or basic usability | -| **P2 — High** | Significant UX/security gap; required for production readiness | -| **P3 — Medium** | Quality-of-life improvement; can be deferred | -| **P4 — Low** | Nice-to-have; deferred indefinitely | - ---- - -## 2. P0 — Blocking Issues - -**None currently.** The system reaches a login prompt reliably on redbear-mini. Redbear-full builds but has not been boot-tested this session. - -| # | Issue | Fix | Effort | -|---|-------|-----|--------| -| P0-1 | **Boot redbear-full in QEMU** and verify it reaches login/desktop | Run `make qemu CONFIG_NAME=redbear-full`, collect logs, fix any boot failures | 2h | -| P0-2 | **Verify 12-patch chain on clean checkout** | `make distclean && make all CONFIG_NAME=redbear-mini` | 1h | - ---- - -## 3. P1 — Critical Gaps - -### P1-1: D-Bus Runtime Validation -**Impact**: KWin/Plasma cannot start without working D-Bus. All D-Bus code is "build-verified" only. -**Files**: `local/recipes/system/redbear-sessiond/source/`, `config/redbear-full.toml` - -| Step | Action | Effort | -|------|--------|--------| -| 1 | Boot redbear-full in QEMU | 30min | -| 2 | Verify `dbus-daemon` starts (`ps | grep dbus`) | 15min | -| 3 | Verify `redbear-sessiond` starts and registers on bus | 15min | -| 4 | Test `dbus-send --system --dest=org.freedesktop.login1 ... ListSessions` | 30min | -| 5 | Test `ListSeats`, `GetUser`, `CreateSession` | 1h | -| 6 | Test `PowerOff` (now backed by hardened ACPI shutdown) | 30min | -| 7 | Fix any startup/runtime failures found | 4h | - -**Acceptance**: `dbus-send` to login1 returns valid session/seat/user data. `PowerOff` triggers ACPI shutdown sequence. - -### P1-2: ion Shell — Job Control -**Impact**: Cannot background processes, cannot Ctrl-Z suspend. Every Unix user expects this. -**Files**: `recipes/core/ion/source/src/` - -| Step | Action | Effort | -|------|--------|--------| -| 1 | Implement signal handling for SIGTSTP/SIGCONT in ion_shell | 1d | -| 2 | Add background job table (track PIDs, job numbers) | 1d | -| 3 | Implement `fg`, `bg`, `jobs` builtins | 4h | -| 4 | Implement `&` operator for backgrounding at command line | 2h | -| 5 | Wire Ctrl-Z to send SIGTSTP to foreground process group | 2h | - -**Acceptance**: `sleep 60 &`, `jobs`, `fg %1`, `Ctrl-Z` → `bg` works. `ps` shows proper process states. - -### P1-3: ion Shell — Tab Completion -**Impact**: Must type every path and command fully. Painful on any filesystem. -**Files**: `recipes/core/ion/source/src/` - -| Step | Action | Effort | -|------|--------|--------| -| 1 | Add `liner::Completer` trait implementation to ion | 4h | -| 2 | Implement command completion (scan $PATH) | 2h | -| 3 | Implement file path completion | 2h | -| 4 | Implement partial match + common prefix completion | 1h | - -**Acceptance**: Tab completes commands from $PATH. Tab completes file paths. Double-tab shows options. - -### P1-4: DRM/KMS in Boot Path -**Impact**: Only VESA framebuffer available at boot. No GPU acceleration. -**Files**: `recipes/core/base-initfs/recipe.toml` - -| Step | Action | Effort | -|------|--------|--------| -| 1 | Add `redox-drm` to base-initfs BINS array | 15min | -| 2 | Verify service file exists (added in Phase B1) | ✅ done | -| 3 | Build and boot redbear-full | 1h | -| 4 | Verify framebuffer switches from VESA to DRM at boot | 1h | -| 5 | Fix any GPU-specific issues (AMD DC or Intel display) | 4h | - -**Acceptance**: `lspci` shows GPU. `/scheme/drm/card0` exists. Framebuffer output works via redox-drm. - ---- - -## 4. P2 — High Priority - -### P2-1: Login /etc/shadow Support -**Impact**: Passwords stored in /etc/passwd (not hashed separately). Security gap. -**Files**: `recipes/core/userutils/source/src/bin/login.rs`, `redox_users` crate - -| Step | Action | Effort | -|------|--------|--------| -| 1 | Read /etc/shadow for password hash (fall back to /etc/passwd) | 2h | -| 2 | Verify SHA-crypt hash verification works (sha-crypt crate already in use) | 1h | -| 3 | Update passwd command to write to /etc/shadow | 1h | - -**Acceptance**: Password in /etc/shadow, not /etc/passwd. Login verifies against shadow. - -### P2-2: Login Rate Limiting -**Impact**: Unlimited brute-force attempts. -**Files**: `recipes/core/userutils/source/src/bin/login.rs` - -| Step | Action | Effort | -|------|--------|--------| -| 1 | Track consecutive failures per TTY | 30min | -| 2 | Sleep 5 seconds after 3 failures | 15min | -| 3 | Log failures to syslog | 15min | - -**Acceptance**: 3 wrong passwords → 5-second delay. Delay doubles for each subsequent failure. - -### P2-3: Network in Initfs -**Impact**: No network during early boot. DHCP/networking only available after switch_root. -**Files**: `recipes/core/base/source/init.initfs.d/`, `recipes/core/base-initfs/recipe.toml` - -| Step | Action | Effort | -|------|--------|--------| -| 1 | Add `e1000d`, `rtl8168d` to base-initfs BINS | 15min | -| 2 | Create `60_smolnetd.service` for initfs | 15min | -| 3 | Create `61_dhcpd.service` for initfs | 15min | -| 4 | Verify netctl boot profile loading works in initfs | 1h | - -**Acceptance**: Network available before switch_root. `ifconfig` shows IP. `ping` works. - -### P2-4: D-Bus Polkit Enforcement -**Impact**: redbear-polkit is a facade — no actual privilege checks. KAuth expects real polkit. -**Files**: `local/recipes/system/redbear-polkit/source/` - -| Step | Action | Effort | -|------|--------|--------| -| 1 | Implement `CheckAuthorization` method with actual policy lookup | 3h | -| 2 | Define default policies (allow root, ask for user password for admin actions) | 2h | -| 3 | Test with KAuth-dependent KDE actions | 2h | - -**Acceptance**: `pkcheck --action-id org.freedesktop.login1.power-off` returns auth result. - ---- - -## 5. P3 — Medium Priority - -### P3-1: ion Shell — History Search (Ctrl-R) -**Effort**: 1d. Implement incremental reverse search using `liner` library. - -### P3-2: ion Shell — Aliases -**Effort**: 2h. Add `alias` builtin, resolve aliases before command lookup. - -### P3-3: fbcond Scrollback Buffer -**Effort**: 4h. Add 1000-line ring buffer to framebuffer console. PgUp/PgDn to scroll. - -### P3-4: ACPI Sleep States (S3/S4) -**Effort**: 2d. Implement `_S3`/`_S4` AML method invocation. Save/restore device state. - -### P3-5: Thermal Daemon -**Effort**: 2d. Read CPU temperature via ACPI thermal zone. Log warnings. Throttle on overheat. - -### P3-6: Battery Status -**Effort**: 1d. Read ACPI battery info. Expose via D-Bus org.freedesktop.UPower. - ---- - -## 6. P4 — Deferred - -| Item | Reason | -|------|--------| -| WiFi driver enablement | Requires iwlwifi kernel module port (LinuxKPI), firmware loading | -| Bluetooth stack | Requires USB maturity, BlueZ port or native stack | -| Secure boot chain | Requires TPM support, measured boot | -| Filesystem encryption | Requires LUKS-like block layer | -| ZSH port | ion is default; zsh is optional | -| RTC write support | Low priority — NTP can adjust kernel clock without hardware RTC write | - ---- - -## 7. Implementation Order - -``` -Week 1: P0-1 (boot redbear-full) → P0-2 (clean build verify) - P1-4 (DRM in boot path) - P1-1 (D-Bus runtime validation) — parallel with P1-4 - -Week 2: P1-2 (ion job control) → P1-3 (ion tab completion) - P2-1 (shadow support) → P2-2 (rate limiting) - -Week 3: P2-3 (network in initfs) - P3-1 (ion history search) → P3-2 (ion aliases) - -Week 4: P2-4 (polkit enforcement) - P3-3 (fbcond scrollback) - -Week 5-6: P3-4 (sleep states) - P3-5 (thermal daemon) - P3-6 (battery status) -``` - -### Parallel Opportunities - -``` -Week 1: [P0-1/P0-2] || [P1-1] || [P1-4] -Week 2: [P1-2 → P1-3] || [P2-1 → P2-2] -Week 3: [P2-3] || [P3-1 → P3-2] -``` - ---- - -## 8. Acceptance Gates - -| Gate | Requirement | -|------|-------------| -| G1 — Console Boot | redbear-mini reaches login prompt. All 12 patches apply. base + base-initfs build. | -| G2 — Desktop Boot | redbear-full reaches login prompt or greeter. D-Bus daemon + sessiond start. | -| G3 — Shell Usability | ion supports job control, tab completion, history search, aliases. | -| G4 — Security Baseline | Passwords in /etc/shadow. Rate limiting active. Polkit enforces authorization. | -| G5 — Hardware Coverage | DRM/KMS active at boot. Network available in initfs. USB storage in initfs. | - ---- - -## 9. Total Effort Estimate - -| Priority | Items | Effort | -|----------|-------|--------| -| P0 | 2 items | 3h | -| P1 | 4 items | ~40h (5 days) | -| P2 | 4 items | ~20h (2.5 days) | -| P3 | 6 items | ~40h (5 days) | -| **Total** | **16 items** | **~103h (~13 days with 1 dev, ~1 week with 2 devs)** | diff --git a/local/docs/archived/COMPREHENSIVE-FIX-PLAN-FINAL.md b/local/docs/archived/COMPREHENSIVE-FIX-PLAN-FINAL.md deleted file mode 100644 index 245ab4e79d..0000000000 --- a/local/docs/archived/COMPREHENSIVE-FIX-PLAN-FINAL.md +++ /dev/null @@ -1,197 +0,0 @@ -# Red Bear OS — Comprehensive Fix Plan (Final) - -**Date**: 2026-05-03 -**Status**: 13 patches, redbear-mini boots, redbear-full KDE chain broken -**QEMU verified**: ✅ text console boot, ❌ graphical desktop build - ---- - -## 0. Current State - -``` -Build: 13 patches → base ✅ base-initfs ✅ userutils ✅ -Boot: redbear-mini → UEFI → 25+ services → console login ✅ - redbear-full → build fails at kf6-kitemviews (pkgar race) -Hardware: QEMU x86_64. VESA, PS/2, USB HID, PCI, ACPI — all functional. -``` - -### Completed (all sessions) - -| # | Item | Status | -|---|------|--------| -| 1 | Build system atomicity (staging + rollback) | ✅ | -| 2 | Patch normalization (diff --git → ---/+++) | ✅ | -| 3 | Workspace pollution cleanup | ✅ | -| 4 | --allow-protected CLI flag | ✅ | -| 5 | PS/2 LED feedback + InputProducer | ✅ | -| 6 | USB HID hardening (validation, retry, lookup table) | ✅ | -| 7 | Init colored ANSI output | ✅ | -| 8 | XKB bridge (redbear-keymapd) | ✅ | -| 9 | ACPI shutdown hardening | ✅ | -| 10 | Persistent logging (logd → /var/log/system.log) | ✅ | -| 11 | DRM + USB initfs service files | ✅ | -| 12 | Network drivers in initfs (e1000d, rtl8168d, smolnetd, dhcpd) | ✅ | -| 13 | Login rate limiting | ✅ | -| 14 | Documentation (4 audit docs, 9 stale archived) | ✅ | - ---- - -## 1. P0 — Blocker: KDE Build Chain - -### Problem -`make live CONFIG_NAME=redbear-full` fails: -``` -cook kf6-kitemviews - failed -failed to install 'libwayland/stage.pkgar' in 'kf6-kitemviews/sysroot.tmp': -No such file or directory -``` - -`libwayland` builds successfully but its `stage.pkgar` is missing when `kf6-kitemviews` needs it. - -### Root Cause Analysis - -The cookbook tool (`src/cook/`) has a dependency staging race: -1. `libwayland` builds → publishes pkgar to `repo/` -2. `kf6-kitemviews` depends on `libwayland` -3. Cookbook installs dependencies into `sysroot.tmp` before building -4. The pkgar file is looked up at `recipes/wip/wayland/libwayland/target/.../stage.pkgar` -5. This path is incorrect — pkgar should be looked up in `repo/` not `target/` - -### Fix - -**File**: `src/cook/` — investigate `pkgar` push/install logic. - -| Step | Action | -|------|--------| -| 1 | Read `src/cook/package.rs` — `package_source_paths()` function | -| 2 | Read `src/cook/cook_build.rs` — how sysroot.tmp is populated | -| 3 | Trace the pkgar lookup path for `kf6-kitemviews` → `libwayland` | -| 4 | Fix the path lookup to use `repo/` directory instead of `target/` | -| 5 | Rebuild: `make live CONFIG_NAME=redbear-full` | -| 6 | Verify: kf6-kitemviews builds, ISO created | - -**Estimated effort**: 4-8 hours (investigation + fix + rebuild) - ---- - -## 2. P1 — Graphical Boot Path - -After fixing the KDE build chain, the graphical boot needs runtime validation. - -### Components to Test - -| Component | Binary | Expected | -|-----------|--------|----------| -| dbus-daemon | /usr/bin/dbus-daemon | System bus starts, responds to `dbus-send` | -| redbear-sessiond | /usr/bin/redbear-sessiond | Registers `org.freedesktop.login1`, responds to ListSessions | -| seatd | /usr/bin/seatd | Seat management | -| redbear-compositor | /usr/bin/redbear-compositor | Wayland compositor starts | -| KWin | /usr/bin/kwin_wayland | KWin connects to compositor | -| redbear-greeter | /usr/bin/redbear-greeter | Graphical login screen on framebuffer | - -### Test Procedure - -```bash -# Build -make live CONFIG_NAME=redbear-full - -# Boot with VNC (for remote graphical access) -qemu-system-x86_64 -m 4096 \ - -drive file=build/x86_64/redbear-full/harddrive.img,format=raw \ - -drive if=pflash,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd,readonly=on \ - -drive if=pflash,file=/tmp/OVMF_VARS.fd \ - -vnc :0 - -# Connect via VNC viewer and observe graphical boot -# Login via VNC greeter or switch to VT2 (Ctrl+Alt+F2) for text console -``` - -### Acceptance Criteria - -| Gate | Requirement | -|------|-------------| -| G1 | dbus-daemon starts without errors | -| G2 | redbear-sessiond registers on D-Bus system bus | -| G3 | `dbus-send --system --dest=org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager.ListSessions` returns valid data | -| G4 | Wayland compositor initializes (no crash) | -| G5 | Greeter displays on framebuffer (or text login on VT2 as fallback) | - ---- - -## 3. P2 — Remaining Gaps (from previous audits) - -| # | Item | Priority | Effort | Status | -|---|------|----------|--------|--------| -| P2-1 | ion shell job control (fg/bg/Ctrl-Z/&) | High | 3d | Not started | -| P2-2 | ion shell tab completion | High | 2d | Not started | -| P2-3 | /etc/shadow support | High | 4h | Blocked (redox_users crate) | -| P2-4 | polkit enforcement | Medium | 3h | Blocked (needs D-Bus runtime) | -| P2-5 | fbcond scrollback buffer | Medium | 4h | Not started | -| P2-6 | ACPI sleep states (S3/S4) | Low | 2d | Not started | -| P2-7 | Thermal daemon | Low | 2d | Not started | - ---- - -## 4. Implementation Order - -``` -DAY 1-2: P0 — Fix KDE build chain (pkgar staging race) - → Rebuild redbear-full - → Boot graphical image - -DAY 3: P1 — Test graphical boot components - → D-Bus validation - → sessiond/Listsessions test - → Greeter/console verification - -DAY 4-5: P2-1 — ion job control - → Background process table - → fg/bg/jobs builtins - → Ctrl-Z / SIGTSTP handling - -DAY 6: P2-2 — ion tab completion - → PATH command completion - → File path completion - -DAY 7: P2-3/P2-5 — Shadow support + fbcond scrollback - (if redox_users permits shadow; else document limitation) -``` - ---- - -## 5. Cookbook Tool — Specific Areas to Investigate - -### pkgar path issue - -```rust -// src/cook/package.rs — likely location -fn package_source_paths(pkg_name: &str, ...) -> Vec { - // Returns target//stage.pkgar paths - // Bug: returns target/ path when recipe is in wip/wayland/ - // Fix: should return repo//.pkgar path -} -``` - -### Dependency staging order - -```rust -// src/cook/cook_build.rs — sysroot.tmp population -fn build_deps_sysroot(deps: &[CookRecipe], sysroot: &Path) { - for dep in deps { - // Should check repo/ for pkgar, not target/ - let pkgar = dep.repo_pkgar_path(); // propose: new method - install_pkgar(pkgar, sysroot); - } -} -``` - ---- - -## 6. Total Effort - -| Phase | Items | Effort | -|-------|-------|--------| -| P0 — KDE build fix | 1 item | 4-8h | -| P1 — Graphical boot test | 5 components | 4h | -| P2 — Remaining gaps | 7 items | ~80h | -| **Total** | **13 items** | **~12 days (1 dev)** | diff --git a/local/docs/archived/DEVICE-INIT-COMPREHENSIVE-IMPROVEMENT-PLAN.md b/local/docs/archived/DEVICE-INIT-COMPREHENSIVE-IMPROVEMENT-PLAN.md deleted file mode 100644 index ea274e72d1..0000000000 --- a/local/docs/archived/DEVICE-INIT-COMPREHENSIVE-IMPROVEMENT-PLAN.md +++ /dev/null @@ -1,735 +0,0 @@ -# Red Bear OS Low-Level Device Initialization — Comprehensive Improvement Plan - -**Date:** 2026-04-30 -**Scope:** Complete reassessment of boot-time device initialization: daemon inventory, firmware loading, driver model, bus enumeration, controller support, hardware validation -**Reference:** Linux 7.0 kernel device init model (full source available for comparison) -**Status:** Assessment phase — this document is the execution plan - -## 1. Executive Summary - -Red Bear OS has crossed the fundamental bring-up threshold: the system boots to a login prompt on -both QEMU and bounded bare-metal hardware (AMD Ryzen), device daemons start in a defined order, -and major subsystems (ACPI, PCI, USB/xHCI, NVMe, network) have in-tree implementations. - -However, the device initialization stack is **not release-grade**. Key deficiencies vs Linux 7.0: - -| Gap | Severity | Impact | -|-----|----------|--------| -| No proper device driver model (bus/device/driver binding) | CRITICAL | No deferred probing, no async init, no hotplug | -| No uevent/hotplug infrastructure (udev-shim is static enumerator only) | CRITICAL | No device add/remove notification; `udev-shim` is misnamed — it does a single PCI scan, not real udev | -| No EHCI/OHCI/UHCI USB controllers | HIGH | USB keyboard not reliable on bare metal | -| initfs vs rootfs driver duality — drivers started in initfs may conflict with rootfs drivers | HIGH | No explicit handoff contract for devices initialized in initfs | -| No hardware validation for MSI-X, IOMMU, xHCI interrupts | HIGH | QEMU-proven only; real hardware behavior unknown | -| No suspend/resume or runtime power management | HIGH | No S3/S4 sleep, no device power gating | -| No CPU frequency scaling or thermal management | MEDIUM | Battery life, thermal throttling absent | -| No hardware RNG daemon, no SMBIOS/DMI runtime | MEDIUM | Missing entropy source, missing quirk data | -| No PCIe AER, no advanced error reporting | MEDIUM | Silent device failures | -| Firmware loading GPU-only (no Wi-Fi, audio, media) | MEDIUM | Blocks iwlwifi, Bluetooth, media acceleration | -| No device naming policy or persistent device names | MEDIUM | `/dev/` names unstable across boots | -| No kernel cmdline for device parameterization | LOW | No runtime device config without rebuild | -| ACPI startup still carries panic-grade `expect` paths | HIGH | Boot fragility on diverse hardware | -| `acpid` `_S5` shutdown not release-grade | HIGH | Unclean shutdown on some platforms | -| Wi-Fi transport asserts on MSI-X (no legacy IRQ fallback) | HIGH | Wi-Fi won't work on older platforms | -| No EHCI companion controller routing for USB keyboards | HIGH | USB keyboard may be unreachable on some bare metal | -| No io_uring or epoll for async I/O in device daemons | LOW | Throughput ceiling for NVMe | - -### Bottom Line - -**Red Bear OS boots, but device initialization is naive by Linux 7.0 standards.** The microkernel -scheme-based driver model is architecturally sound, but the implementation lacks the maturity, -error resilience, hardware coverage, and power management depth that Linux 7.0 has accumulated -over 30 years of driver development. - -This plan defines a structured path to close these gaps over 5 phases (26-40 weeks). - -## 2. Current State Assessment - -### 2.1 Boot Flow - -``` -UEFI firmware → Bootloader → Kernel (kstart→kmain) → -userspace_init → bootstrap (procmgr) → initfs init → -├── Phase 1 (initfs): logd, nulld, randd, zerod, rtcd, ramfs -├── Phase 1 (initfs): inputd, lived -├── Phase 1 (initfs): vesad, fbbootlogd, fbcond (graphics target) -├── Phase 1 (initfs): hwd, pcid-spawner-initfs, ps2d (drivers target) -├── Phase 1 (initfs): rootfs mount → switchroot -├── Phase 2 (rootfs): ipcd, ptyd, pcid-spawner (base target) -│ ├── pcid-spawner spawns drivers matching PCI IDs: -│ │ ├── Storage: ahcid, ided, nvmed, virtio-blkd, usbscsid -│ │ ├── Network: e1000d, rtl8168d, rtl8139d, ixgbed, virtio-netd -│ │ ├── Graphics: vesad, ihdgd, virtio-gpud -│ │ ├── Input: ps2d, usbhidd -│ │ ├── Audio: ihdad, ac97d, sb16d -│ │ └── USB: xhcid, usbhubd -│ ├── smolnetd → dhcpd (network target) -│ ├── firmware-loader, udev-shim, evdevd, wifictl -│ ├── dbus-daemon → redbear-sessiond, seatd -│ └── console/getty → login prompt -``` - -### 2.2 Daemon Inventory — Existence and Quality - -#### Core Initfs Daemons (20 services) - -| Daemon | Quality | Notes | -|--------|---------|-------| -| `logd` | ✅ Hardened | Zero unwrap/expect; file descriptors, setrens, process loop | -| `nulld` | ✅ Hardened | Zero unwrap/expect | -| `randd` | ✅ Hardened | CPUID chain hardened; 8 test-only unwraps | -| `zerod` | ✅ Hardened | Args default + graceful exit | -| `rtcd` | ✅ Present | x86 RTC driver; minimal attack surface | -| `ramfs@` | ✅ Present | Template service for RAM filesystems | -| `inputd` | ✅ Hardened | 14 panic sites converted; partial vt events, buffer sizes | -| `lived` | ✅ Present | Live disk daemon | -| `vesad` | ✅ Hardened | 20 fixes; FRAMEBUFFER env, EventQueue, event loop, scheme | -| `fbbootlogd` | ✅ Hardened | 14 fixes; VT handle, graphics handle, dirty_fb | -| `fbcond` | ✅ Hardened | 14 fixes; VT parse, event loop, writes, scheme, display | -| `hwd` | ✅ Present | ACPI/DeviceTree boot handler | -| `pcid-spawner-initfs` | ✅ Hardened | initfs variant; oneshot_async | -| `ps2d` | ✅ Hardened | Controller init drains stale output; QEMU proof | -| `bcm2835-sdhcid` | ✅ Present | ARM-only (Raspberry Pi) | - -#### Core Rootfs Daemons (9 base services) - -| Daemon | Quality | Notes | -|--------|---------|-------| -| `ipcd` | ✅ Present | IPC daemon | -| `ptyd` | ✅ Present | Pseudo-terminal daemon | -| `pcid-spawner` | ✅ Hardened | Changed to oneshot_async (was blocking init); logs device info | -| `sudo` | ✅ Present | Privilege daemon | -| `smolnetd`/`netstack` | ✅ Present | TCP/IP stack | -| `dhcpd` | ✅ Present | DHCP client | -| `audiod` | ✅ Present | Audio multiplexer | - -#### PCI-Matched Device Drivers (pcid-spawner, 25+ drivers) - -| Category | Drivers | Quality | -|----------|---------|---------| -| Storage | ahcid, ided, nvmed, virtio-blkd, usbscsid | ✅ All hardened (Wave 4 complete) | -| Network | e1000d, rtl8168d, rtl8139d, ixgbed, virtio-netd | ✅ All hardened | -| Graphics | vesad, ihdgd, virtio-gpud | ✅ All hardened | -| Input | ps2d, usbhidd | ✅ All hardened | -| Audio | ihdad, ac97d, sb16d | ✅ All hardened | -| USB | xhcid, usbhubd, usbctl, ucsid | ✅ xhcid has 88 Red Bear patches | -| GPIO/I2C | gpiod, i2cd, intel-gpiod, amd-mp2-i2cd, dw-acpi-i2cd, i2c-gpio-expanderd, i2c-hidd, intel-thc-hidd, intel-lpss-i2cd | ✅ Present | -| System | pcid, pcid-spawner, acpid | ✅ Core infra; pcid hardened Wave 1-2 | -| VirtualBox | vboxd | ✅ x86 only | - -#### Custom Red Bear Daemons - -| Daemon | Quality | Notes | -|--------|---------|-------| -| `firmware-loader` | ✅ Well-tested | 18 unit tests; scheme:firmware with read/mmap; no signing | -| `redox-drm` | 🚡 Bounded compile | AMD+Intel+VirtIO display; 68 tests; no HW validation | -| `amdgpu` | 🚡 Bounded compile | Imported Linux DC/TTM/core; partial display glue | -| `iommu` | 🚡 QEMU-proven | AMD-Vi detection + first-use proof; no HW validation | -| `udev-shim` | ✅ Present | Scheme:udev with device enumeration | -| `evdevd` | ✅ Present | Linux-compatible evdev interface | -| `redbear-sessiond` | ✅ Present | D-Bus login1 session broker | -| `redbear-wifictl` | 🚡 Host-tested | Wi-Fi control daemon; no real hardware | -| `redbear-iwlwifi` | 🚡 Host-tested | Intel transport; ~2450 lines C + ~1550 lines Rust; 119 tests | -| `redbear-btusb` | 🔴 Experimental | BLE-first; USB-attached only; QEMU validation in progress | -| `redbear-authd` | ✅ Present | Local-user authentication | -| `redbear-greeter` | 🚡 Partial | Greeter orchestrator; Qt Wayland integration broken | -| `redbear-netctl` | ✅ Present | Network profile management | -| `redbear-hwutils` | ✅ Present | lspci, lsusb, phase checkers | - -### 2.3 Firmware Loading - -**What exists:** -- `scheme:firmware` daemon (`firmware-loader`) indexes blobs from `/lib/firmware/` -- `linux-kpi` provides `request_firmware()` via Rust FFI -- AMD GPU blobs (675 .bin files) in `local/firmware/amdgpu/` (gitignored, fetched from linux-firmware) -- Intel DMC display blobs fetchable via `fetch-firmware.sh --vendor intel --subset dmc` -- Two fetch mechanisms: standalone script (selective) + build-time meta-package (full linux-firmware) -- `PCI_QUIRK_NEED_FIRMWARE` flag defined (bit 11), but never checked by any driver - -**What is MISSING vs Linux 7.0 `firmware_class`:** -- No firmware signing/verification (no `module_sig_check` equivalent) -- No `request_firmware_nowait` with uevent dispatch to userspace helper (Linux uses `/sys/$DEVPATH/loading` + `/sys/$DEVPATH/data` + uevent to notify udev) -- No persistent firmware cache between boots (in-memory only; Linux caches during suspend for resume-fastpath) -- No fallback firmware variant search (if dmcub_dcn31.bin missing, try dmcub_dcn30.bin; Linux has per-driver firmware search paths) -- No `/sys/firmware/` interface (Linux exposes firmware loading status via sysfs) -- No firmware preloading at driver bind time -- No timeout for synchronous `request_firmware` (blocks forever; Linux times out after ~60s with uevent fallback) -- No platform firmware fallback (Linux can search UEFI firmware volumes via `firmware_request_platform()`) -- No Wi-Fi firmware blobs (iwlwifi, ath10k, etc.) -- No Bluetooth firmware blobs -- No audio/media codec firmware -- Firmware lookup limited to 3 hardcoded paths (Linux searches: `/lib/firmware/`, `/lib/firmware/updates/`, `/lib/firmware/$KVER/`, `/usr/lib/firmware/`, `/usr/share/firmware/`, plus custom path via kernel param) - -### 2.4 Hardware Validation Status - -| Subsystem | QEMU | Bare Metal | Notes | -|-----------|------|------------|-------| -| ACPI boot | ✅ | ✅ (AMD) | Boot-baseline; `_S5` shutdown not release-grade | -| x2APIC/SMP | ✅ | ✅ | Multi-core works | -| PCI enumeration | ✅ | ✅ | pcid enumerates devices | -| MSI-X | ✅ (virtio-net) | ❌ | No hardware proof | -| IOMMU/AMD-Vi | ✅ (first-use) | ❌ | Detection works; no HW validation | -| xHCI interrupt | ✅ | ❌ | Interrupt mode proven; no HW | -| USB storage | ✅ (readback) | ❌ | QEMU mass-storage proof | -| NVMe | ✅ | ❌ | Builds; no HW | -| AHCI | ✅ | ❌ | Builds; no HW | -| Network (e1000/virtio) | ✅ | ❌ | QEMU only | -| PS/2 keyboard | ✅ | ✅ | QEMU + AMD bare metal | -| USB keyboard | ✅ (QEMU HID) | ⚠️ | Not reliable on bare metal | -| Wi-Fi | ❌ | ❌ | Host-tested transport only | -| Bluetooth | ❌ | ❌ | Experimental BLE; QEMU in progress | - -### 2.5 Comparison with Linux 7.0 Device Init Model - -#### 2.5.1 Linux Initcall Ordering (Reference) - -Linux uses a 10-level initcall system for boot-phase ordering: - -| Level | Macro | Typical Count | Example Uses | -|-------|-------|---------------|--------------| -| 0 | `pure_initcall` | ~few | Pure infrastructure | -| early | `early_initcall` | ~446 | mm init, early console, DT scan | -| 1 | `core_initcall` | ~614 | Workqueues, RCU, memory allocators | -| 2 | `postcore_initcall` | ~150 | Clocksource, scheduler, IRQ core | -| 3 | `arch_initcall` | ~751 | PCI bus init, ACPI table parsing, CPU bringup | -| 4 | `subsys_initcall` | ~573 | PCI enumerate, USB core, networking core, block | -| 5 | `fs_initcall` | ~1372 | Filesystem registration | -| 6 | `device_initcall` | ~1211 | Most drivers; `module_init()` maps here | -| 7 | `late_initcall` | ~440 | Late init, debug, tracing | - -Red Bear OS has **no equivalent ordering mechanism** — the TOML-based init uses `requires_weak` -for loose ordering but has no topological sort depth, no `Before`/`After` fields, no explicit -init phases beyond the coarse initfs/rootfs split. - -#### 2.5.2 Feature Comparison Table - -| Feature | Linux 7.0 | Red Bear OS | Gap | -|---------|-----------|-------------|-----| -| **Driver model** | `bus_type` → `device_driver` → `probe()` binding with match tables | `pcid-spawner` spawns drivers by PCI class/vendor/device | 🟡 Partial — single-shot spawn, no rebinding | -| **Deferred probing** | `driver_deferred_probe` — retries when dependency arrives; `-EPROBE_DEFER` triggers retry on any successful probe | None | 🔴 Missing — must be present at boot | -| **Async probing** | `async_probe` — parallel driver init via kthreadd workers | Sequential spawn only | 🟡 Partial — oneshot_async for launch but not true async init | -| **Hotplug** | uevent netlink → udev → driver bind/unbind; `/sbin/hotplug` path | `udev-shim` is a **static PCI enumerator** — one scan at boot, no event callbacks, no device removal handling | 🔴 Missing — no hotplug infrastructure at all | -| **Firmware loading** | `firmware_class` with `request_firmware`, user helper, caching | `scheme:firmware` + `linux-kpi` request_firmware | 🟡 Partial — no uevent/helper/caching | -| **USB controllers** | xHCI, EHCI, OHCI, UHCI — all supported | xHCI only | 🔴 Missing — EHCI/OHCI/UHCI absent | -| **USB device classes** | HID, storage, audio, video, CDC, vendor, etc. | HID, hub, storage (BOT), CSI (UCSI) | 🟡 Partial — many classes missing | -| **Power management** | Suspend/resume, runtime PM, CPU freq scaling, thermal | `_S5` shutdown only | 🔴 Missing — no S3/S4/PM | -| **Interrupt handling** | Full APIC/x2APIC, MSI/MSI-X, affinity, NMI, MCE | APIC/x2APIC; MSI-X via quirks | 🟡 Partial — no affinity, no NMI watchdog | -| **IOMMU** | AMD-Vi, Intel VT-d with DMA remapping + IR | AMD-Vi detection + first-use proof | 🟡 Partial — no VT-d, no hardware | -| **ACPI namespace** | Full namespace: devices, thermal, battery, processor, etc. | Boot-baseline: MADT, FADT, `_S5`, bounded power | 🟡 Partial — many ACPI objects missing | -| **PCIe features** | AER, ACS, ATS, PRI, PASID, SR-IOV | Basic PCI config space only | 🔴 Missing — no advanced PCIe | -| **Device naming** | Predictable network/storage names (systemd udev) | None | 🟡 Partial — no naming policy | -| **Hardware RNG** | `hw_random` framework, multiple drivers | None | 🔴 Missing | -| **CPU frequency** | `cpufreq` governors | None | 🔴 Missing | -| **Thermal management** | `thermal` framework + drivers | None | 🔴 Missing | -| **SMBIOS/DMI** | Full DMI table exposure via sysfs | Quirks system has DMI data | 🟡 Partial — not runtime-exposed | -| **Kernel cmdline** | Device parameters via boot cmdline | None | 🔴 Missing | - -## 3. Implementation Phases - -### Phase 1 — Driver Model Maturation (Weeks 1-8) - -**Goal:** Establish a proper device driver model with binding semantics, deferred probing, -and error resilience — bringing the driver infrastructure to Linux 7.0 par without rewriting -existing drivers. - -#### 1.1 Device-Driver Binding Model (Week 1-3) - -Create a `redox-driver-core` library providing Linux-style bus/device/driver abstractions: - -``` -Device → Driver matching: - pcid: class=0x01, subclass=0x08 → nvmed - pcid: vendor=0x8086, device=0x10D3 → e1000d - -Driver probe() returns: - Ok(()) → device bound, driver active - Err(ENODEV) → device not supported by this driver - Err(EAGAIN) → dependency not available, DEFER probe - Err(...) → fatal error, device unusable -``` - -**Deliverables:** -- `redox-driver-core` crate with `Bus`, `Device`, `Driver` traits -- `pcid` exposes devices via new scheme: `scheme:pci/devices/{id}/bind` -- `pcid-spawner` replaced by `driver-manager` daemon that: - - Reads driver match tables from `/lib/drivers.d/*.toml` - - Probes drivers in priority order - - Supports deferred probing (EAGAIN → retry when dependency appears) - - Supports driver unbind/rebind -- All existing `pcid.d/*.toml` match files migrated to new format -- Backward compatible: existing pcid-spawner behavior preserved as fallback - -#### 1.2 Async Device Probing (Week 4-5) - -**Deliverables:** -- `driver-manager` probes independent device trees in parallel (using Rust async or threads) -- Device init order defined by dependency DAG, not sequential spawn -- Timing observability: log probe duration per driver -- `CONFIG_PARALLEL_PROBE` equivalent: max concurrent probes tunable via config TOML - -#### 1.3 Driver Parameter System (Week 6-7) - -**Deliverables:** -- Kernel cmdline parsing in bootloader (e.g., `redbear.nvme.irq_mode=msi`) -- `/scheme/sys/driver/{name}/parameters` read/write -- Driver authors declare parameters via derive macro -- `lspci -v` shows per-device parameters - -#### 1.4 Hotplug Infrastructure (Week 7-8) - -**Deliverables:** -- PCIe hotplug: `pcid` detects surprise removal/addition, emits uevent -- USB hotplug: `xhcid` emits uevent on device attach/detach -- `udev-shim` enhanced to receive uevents and trigger driver binding -- `driver-manager` handles hot-add (probe driver) and hot-remove (unbind driver) -- Initial scope: PCIe hotplug and USB hotplug only; Thunderbolt deferred - -**Phase 1 Exit Criteria:** -- New driver binding model functional for 3+ existing drivers (nvmed, e1000d, xhcid) -- Deferred probing works: driver returning EAGAIN retries when dependency scheme appears -- Async probing measurable: 2+ independent PCI devices probe concurrently -- Hotplug works: USB device attach/detach triggers udev-shim + driver bind/unbind in QEMU -- All 25+ existing drivers still compile and function (backward compatibility) - -### Phase 2 — Controller Coverage & Hardware Validation (Weeks 5-14) - -**Goal:** Fill the critical controller gaps (USB EHCI/OHCI/UHCI) and validate the -existing controller stack on real hardware — especially MSI-X, IOMMU, and xHCI. - -#### 2.1 USB Controller Family Completion (Week 5-9) - -This is the **highest-impact controller gap** because it directly blocks reliable -USB keyboard input on bare metal where the keyboard may be routed through companion -controllers rather than xHCI. - -**Deliverables:** -- `ehcid` daemon — EHCI (USB 2.0) host controller driver -- `ohcid` daemon — OHCI (USB 1.1) host controller driver for non-Intel chipsets -- `uhcid` daemon — UHCI (USB 1.1) host controller driver for Intel chipsets -- USB companion controller routing: when xHCI owns the ports, companion controllers - hand off low/full-speed devices to xHCI transparently -- `usb-manager` daemon orchestrates multi-controller topology: - - Single `scheme:usb` root exposing all buses - - Device path stability across controller types - - Port routing table for companion controller ownership handoff -- USB 3.1/3.2 SuperSpeedPlus support in xhcid (10 Gbps, 20 Gbps) -- USB-C PD/alt-mode awareness in `ucsid` - -**Implementation approach:** -- EHCI: Reference Linux `drivers/usb/host/ehci-hcd.c` (~6000 lines) and FreeBSD `sys/dev/usb/controller/ehci.c` -- OHCI: Reference Linux `drivers/usb/host/ohci-hcd.c` (~3000 lines) -- UHCI: Reference Linux `drivers/usb/host/uhci-hcd.c` (~2500 lines) -- All three controllers use the same `scheme:usb` interface — class daemons (usbhubd, usbhidd, usbscsid) work unchanged - -#### 2.2 xHCI Device-Level Hardening (Week 8-10) - -Per the existing `XHCID-DEVICE-IMPROVEMENT-PLAN.md`: - -**Deliverables:** -- Atomic device attach publication (prevent half-attached devices) -- Bounded device detach and purge -- Configure rollback on failure -- Real PM sequencing (U0/U1/U2/U3 transitions) -- Enumerator cleanup and timing hardening -- Growable event ring under sustained activity - -#### 2.3 MSI-X Hardware Validation (Week 8-11) - -Per the existing `IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md` Priority 1: - -**Deliverables:** -- AMD GPU MSI-X validation: prove MSI-X vectors fire correctly on real AMD hardware -- Intel GPU MSI-X validation: prove MSI-X on Intel hardware -- NVMe MSI-X validation: prove per-queue interrupt vectors -- xHCI MSI-X validation: prove interrupt-driven event ring on real hardware (not just QEMU) -- Verified MSI-X → MSI → legacy IRQ fallback on all tested hardware -- Logged CPU/vector affinity behavior -- At minimum one AMD and one Intel bare-metal test report per device class - -#### 2.4 IOMMU Hardware Bring-Up (Week 9-14) - -Per the existing `IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md` Priority 2: - -**Deliverables:** -- Validated AMD-Vi initialization on real AMD hardware -- Device table / command buffer / event log validation -- Interrupt remapping validation -- Intel VT-d initial detection and register mapping (not full bring-up) -- IOMMU fault-path validation: inject fault, verify event log capture -- DMA remapping proof: verify device DMA is translated through IOMMU page tables -- Negative-result documentation if hardware still fails - -#### 2.5 ACPI Wave 1-2 Completion (Week 10-12) - -Per the existing `ACPI-IMPROVEMENT-PLAN.md` Waves 1-2: - -**Deliverables:** -- Finish replacing panic-grade `expect` paths in `acpid` startup -- Define and document AML bootstrap contract (explicit RSDP_ADDR producer) -- Table-specific reject/warn/degrade/fail rules implemented -- Deterministic `_S5` derivation (not dependent on PCI timing) -- Explicit shutdown/reboot result semantics -- Bounded shutdown proof on real AMD and Intel hardware -- Sleep-state scope explicit: S5 only; S3/S4 explicitly deferred - -**Phase 2 Exit Criteria:** -- At least one EHCI or OHCI/UHCI driver functional in QEMU -- USB keyboard reliably reachable on bare metal AMD and Intel (via xHCI, EHCI, or companion routing) -- MSI-X validated on at least one real AMD GPU and one real Intel GPU -- IOMMU AMD-Vi validated on at least one real AMD machine -- ACPI `_S5` shutdown works on at least one real AMD and one real Intel machine -- ACPI startup contains zero panic-grade paths reachable from firmware input - -### Phase 3 — Power Management & Platform Services (Weeks 12-20) - -**Goal:** Add suspend/resume, CPU frequency scaling, thermal management, and hardware -RNG — bringing platform services to Linux 7.0 par for basic functionality. - -#### 3.1 ACPI Power Management (Week 12-14) - -Per the existing `ACPI-IMPROVEMENT-PLAN.md` Waves 3-4: - -**Deliverables:** -- Honest `/scheme/acpi/power` surface: exposes only behavior with runtime evidence -- Consumer-visible distinction between unsupported, unavailable, and populated power state -- Reduced surface: remove misleading empty-success defaults -- AML physmem/EC failure propagation: no correctness-critical fabricated values -- EC error typing and documented widened-access behavior -- Documented AML mutex timeout behavior - -#### 3.2 Suspend/Resume (S3 Sleep) — Initial Implementation (Week 13-16) - -**Deliverables:** -- Kernel: save/restore CPU context (CR0-CR4, MSRs, IDT/GDT, FPU/SSE/AVX state) -- Kernel: ACPI S3 (suspend-to-RAM) entry via `_S3` AML method -- Kernel: wake vector registration and resume path -- `acpid`: expose `/scheme/acpi/sleep` with `S3` and `S5` states -- Device contract: `suspend()` callback on each scheme daemon - - Storage: flush caches, park heads (if spinning) - - Network: bring link down, save MAC filter state - - USB: save controller/port state - - Graphics: save mode, blank display -- `driver-manager`: suspend devices in dependency order, resume in reverse -- Initial scope: S3 only on test hardware; S4 (hibernate) explicitly deferred - -#### 3.3 CPU Frequency Scaling (Week 14-16) - -**Deliverables:** -- `cpufreqd` daemon reading ACPI `_PSS` / `_PPC` objects -- Intel: P-state MSR writes (IA32_PERF_CTL) -- AMD: P-state MSR writes + CPPC awareness -- Governors: `performance` (max freq), `powersave` (min freq), `ondemand` (load-based) -- `/scheme/cpufreq` for reading/setting governor and frequency -- `redbear-info` shows current frequency and governor - -#### 3.4 Thermal Management (Week 15-17) - -**Deliverables:** -- `thermald` daemon reading ACPI thermal zone objects (`_TMP`, `_PSV`, `_TC1`, `_TC2`) -- Active cooling: fan control via ACPI `_SCP` -- Passive cooling: CPU throttling via cpufreqd integration -- Critical shutdown: if temperature exceeds `_CRT`, initiate clean shutdown -- `/scheme/thermal` for reading zone temperatures and trip points -- `redbear-info` shows thermal zone status - -#### 3.5 Hardware RNG (Week 16-17) - -**Deliverables:** -- `hwrngd` daemon reading hardware RNG sources: - - x86 RDRAND/RDSEED instructions - - TPM 2.0 random number generator (if present) - - VirtIO entropy device -- `scheme:hwrng` feeding into `randd` entropy pool -- `/scheme/hwrng` exposes raw entropy and health status -- Linux 7.0 `hw_random` framework ported conceptually (not literally) - -#### 3.6 PCIe Advanced Error Reporting (Week 17-18) - -**Deliverables:** -- `pcid` exposes AER capability registers via `/scheme/pci/{dev}/aer` -- AER error detection: correctable and uncorrectable error status registers -- Error logging: decode error source (data link, transaction, poison TLP, etc.) -- `aer-inject` utility for testing error paths -- Initial scope: error detection and logging only; error recovery (device reset path) deferred - -#### 3.7 SMBIOS/DMI Runtime Exposure (Week 18-20) - -**Deliverables:** -- `dmidecode`-equivalent utility using `acpid` DMI scheme -- `/scheme/dmi` exposes SMBIOS entry point and table data -- `lspci -v` shows DMI-based quirk annotations -- DMI data feeding into `redbear-info` for platform identification -- Integration with existing quirks system: DMI match rules validated at runtime - -**Phase 3 Exit Criteria:** -- S3 suspend/resume works on at least one real machine (AMD or Intel) -- CPU frequency scaling observable via `redbear-info` -- Thermal zone temperature readable and critical shutdown testable -- Hardware RNG feeding entropy pool -- PCIe AER errors logged on capable hardware -- DMI data accessible via scheme and tools -- All new schemes documented with test procedures - -### Phase 4 — Firmware Infrastructure & Wi-Fi Validation (Weeks 16-24) - -**Goal:** Close firmware loading gaps, complete Wi-Fi hardware validation with real -firmware, and establish firmware management as a first-class platform service. - -#### 4.1 Firmware Loading Gap Closure (Week 16-18) - -**Deliverables:** -- `request_firmware_nowait` with proper uevent dispatch: - - Async request → uevent → `udev-shim` listens → `firmware-loader` serves blob - - Timeout: if firmware not available within configurable timeout, fail gracefully -- Firmware fallback variant search: - - If `dmcub_dcn31.bin` not found, try `dmcub_dcn30.bin`, `dmcub_dcn20.bin` - - Per-driver fallback chain defined in `/etc/firmware-fallbacks.d/*.toml` -- Persistent firmware cache (`/var/lib/firmware/`): - - Loaded blobs cached on first use; survive daemon restart - - Cache invalidation on firmware version change -- `PCI_QUIRK_NEED_FIRMWARE` enforcement: - - Drivers actually check the flag via `pci_has_quirk()` - - When flag is set: require firmware at probe time, fail probe if absent - - When flag is absent: firmware is optional, warn if missing but continue -- Fetch Intel Wi-Fi firmware blobs: `fetch-firmware.sh --vendor intel --subset wifi` -- Fetch Bluetooth firmware blobs where applicable -- Firmware manifest: `/lib/firmware/MANIFEST.txt` lists all blobs, versions, sources - -#### 4.2 Wi-Fi Hardware Validation (Week 16-22) - -Per the existing `WIFI-IMPLEMENTATION-PLAN.md`: - -**Deliverables:** -- Real Intel Wi-Fi device (e.g., AX200/AX201/AX210) validated end-to-end -- `redbear-iwlwifi` transport: - - Firmware loaded via `request_firmware()` → `scheme:firmware` - - DMA ring operation validated (TX reclaim, RX restock, command dispatch) - - Interrupt handling validated (MSI-X or MSI path) - - Association/authentication cycle completed with real AP -- `redbear-wifictl` control plane: - - Scan → connect → DHCP → disconnect cycle validated - - WPA2-PSK and open network profiles functional - - Profile persistence and boot-time application -- `redbear-netctl` Wi-Fi profiles: - - SSID/Security/Key parsing validated - - Bounded Wi-Fi lifecycle (prepare → init-transport → activate-nic → connect → disconnect) -- Wi-Fi runtime diagnostics: - - `redbear-phase5-wifi-check` reports link quality, signal strength, connected AP - - `redbear-info --verbose` shows Wi-Fi adapter status -- At minimum one real Intel Wi-Fi chipset validated -- Legacy IRQ fallback for platforms where MSI-X is unavailable (via quirks) - -#### 4.3 Wi-Fi Desktop API (Week 20-24) - -**Deliverables:** -- D-Bus Wi-Fi API on system bus: `org.freedesktop.NetworkManager` subset - - `GetDevices`, `GetAccessPoints`, `ActivateConnection`, `DeactivateConnection` - - Signal: `AccessPointAdded`, `AccessPointRemoved`, `StateChanged` -- `redbear-wifictl` exposes D-Bus interface for desktop consumption -- `redbear-netctl` GUI client for scanning and connecting (Qt6-based, optional) -- Desktop status bar Wi-Fi indicator (future KDE plasma-nm integration) - -**Phase 4 Exit Criteria:** -- `request_firmware_nowait` with uevent dispatch functional in QEMU -- PCI_QUIRK_NEED_FIRMWARE enforced in at least one driver (amdgpu or iwlwifi) -- Intel Wi-Fi chipset validated end-to-end with real AP -- Wi-Fi scan → connect → DHCP → internet access completed on real hardware -- Wi-Fi D-Bus API functional for at least get_devices and get_accesspoints -- Firmware manifest tracks all loaded blobs with versions - -### Phase 5 — Bluetooth, Device Policy, Polish (Weeks 20-30) - -**Goal:** Bring Bluetooth to validated experimental status, establish device naming policy, -and polish remaining gaps. - -#### 5.1 Bluetooth Hardware Validation (Week 20-24) - -Per the existing `BLUETOOTH-IMPLEMENTATION-PLAN.md`: - -**Deliverables:** -- `redbear-btusb` transport validated with real USB Bluetooth adapter -- `redbear-btctl` HCI host validated: - - Controller init sequence (reset, read local features, set event mask) - - Device discovery (LE scan → advertising report → connect) - - GATT service discovery - - Basic data exchange (battery service, device info) -- BLE peripheral connect/disconnect cycle validated -- Bluetooth classic (BR/EDR) detection and basic inquiry (connect deferred) -- `redbear-bluetooth-battery-check` works on real hardware -- At minimum one real USB Bluetooth adapter validated - -#### 5.2 Device Naming Policy (Week 22-24) - -**Deliverables:** -- Predictable network interface names: - - `enp0s1` instead of `eth0` (PCIe bus/device/function based) - - `/etc/systemd/network/` equivalent rules in `/etc/udev/rules.d/` -- Predictable storage device names: - - NVMe: `nvme0n1` instead of raw scheme path - - AHCI: `sd{a,b,c}` assigned by port order - - USB storage: `sdX` with stable enumeration -- `/dev/disk/by-id/`, `/dev/disk/by-path/`, `/dev/disk/by-uuid/` symlinks -- `udev-shim` enhanced with rule matching (vendor, model, serial, path patterns) - -#### 5.3 Device Init Observability (Week 23-25) - -**Deliverables:** -- Boot-time device init timeline: log each device probe start/end with duration -- `redbear-info --boot` shows device init timeline post-boot -- Per-device init status: `redbear-info --device pci/00:02.0` -- Kernel cmdline `redbear.init_verbose` enables verbose device init logging -- Boot-time warning summary: all drivers that probed with warnings or deferrals -- Device init health dashboard: `redbear-info --health` shows init status of all subsystems - -#### 5.4 Remaining Gaps (Week 24-30) - -**Deliverables:** -- `nvmed` hardware validation: prove NVMe I/O on real hardware -- `ahcid` hardware validation: prove SATA I/O on real hardware -- `ihdad` hardware validation: prove audio output on real hardware -- USB device class coverage expanded: - - USB CDC ACM (serial): `usbcdcd` daemon - - USB CDC ECM/NCM (ethernet): `usbnetd` daemon (or integrate into existing net drivers) - - USB Audio Class 1/2: `usbaudiod` daemon -- GPU hardware acceleration readiness: - - Mesa radeonsi backend proof-of-concept (single draw call) - - KMS atomic modesetting proof on real hardware (not just QEMU) -- `redbear-btusb` autospawn via USB class matching -- `kstop` shutdown event: gracefully stop all device daemons before power-off - -**Phase 5 Exit Criteria:** -- Bluetooth BLE discovery and basic data exchange works on real hardware -- Network interfaces use predictable names on QEMU and bare metal -- Device init timeline observable via `redbear-info --boot` -- NVMe I/O validated on at least one real NVMe drive -- Real audio output validated on at least one HDA codec -- At least one USB device class beyond HID/storage validated (audio, serial, or ethernet) -- All 25+ existing drivers maintain backward compatibility - -## 4. Dependency Graph - -``` -Phase 1 (Driver Model) ─────────────────────────────┐ - ├── 1.1 Binding Model │ - ├── 1.2 Async Probing (after 1.1) │ - ├── 1.3 Driver Parameters (after 1.1) │ - └── 1.4 Hotplug (after 1.1) │ - │ -Phase 2 (Controllers) ───────────────────────────────┤ - ├── 2.1 USB EHCI/OHCI/UHCI (parallel with 1.2) │ - ├── 2.2 xHCI Hardening (parallel with 1.2) │ - ├── 2.3 MSI-X HW Validation (after 1.1) │ - ├── 2.4 IOMMU HW Bring-Up (parallel with 2.3) │ - └── 2.5 ACPI Wave 1-2 (parallel with 2.3) │ - │ -Phase 3 (Power Mgmt) ────────────────────────────────┤ - ├── 3.1 ACPI Wave 3-4 (after 2.5) │ - ├── 3.2 Suspend/Resume (after 3.1) │ - ├── 3.3 CPU Freq Scaling (parallel with 3.2) │ - ├── 3.4 Thermal Mgmt (after 3.1, parallel 3.3) │ - ├── 3.5 Hardware RNG (parallel with 3.3) │ - ├── 3.6 PCIe AER (after 2.3) │ - └── 3.7 SMBIOS/DMI (parallel with 3.6) │ - │ -Phase 4 (Firmware + Wi-Fi) ──────────────────────────┤ - ├── 4.1 Firmware Gaps (after 1.1) │ - ├── 4.2 Wi-Fi HW (after 4.1, parallel with 2.3) │ - └── 4.3 Wi-Fi Desktop API (after 4.2) │ - │ -Phase 5 (Bluetooth + Polish) ────────────────────────┤ - ├── 5.1 BT HW Validation (parallel with 4.2) │ - ├── 5.2 Device Naming (after 1.1) │ - ├── 5.3 Init Observability (after 1.2) │ - └── 5.4 Remaining Gaps (after 3.2, 4.2, 5.1) │ -``` - -## 5. Resource Estimates - -| Phase | Duration | Engineers | Key Risk | -|-------|----------|-----------|----------| -| Phase 1 | 8 weeks | 2 | Over-engineering the driver model; must stay backward compatible | -| Phase 2 | 6-9 weeks | 3 (parallelizable) | Real hardware availability; USB controller complexity | -| Phase 3 | 8 weeks | 2-3 | ACPI firmware quality varies wildly on real hardware | -| Phase 4 | 8 weeks | 2 | Wi-Fi hardware procurement; firmware licensing | -| Phase 5 | 10 weeks | 2 | Long tail of device class drivers | - -**Total:** 26-40 weeks (~6-10 months) with 2-3 engineers, depending on parallelism and -hardware availability. - -## 6. Risk Register - -| Risk | Probability | Impact | Mitigation | -|------|-------------|--------|------------| -| No access to AMD GPU with MSI-X | Medium | High | Partner with community; use Intel GPU as alternative | -| No access to AMD machine with IOMMU | Medium | High | Prioritize Intel VT-d if AMD hardware unavailable | -| USB EHCI/OHCI/UHCI significantly harder than estimated | Medium | High | Scope to EHCI-only initially; UHCI/OHCI deferred | -| ACPI firmware corruption on test machines causes false failures | High | Medium | Test on 3+ machines per platform class | -| Wi-Fi firmware licensing prevents redistribution | Low | Medium | Keep firmware external (fetched, not committed) | -| Existing driver regression from new driver model | Medium | High | Extensive backward compat testing; parallel old/new paths | -| S3 suspend/resume crashes unrecoverably on some hardware | High | Medium | Gate behind config flag; S3 is opt-in initially | - -## 7. Success Criteria (Definition of Done) - -This plan is complete when: - -1. **Driver Model:** New driver binding model works for all existing drivers; deferred probing - retries correctly; async probing measurably parallel; hotplug adds/removes devices without reboot. - -2. **USB Controllers:** At least one non-xHCI controller (EHCI preferred) functional; USB keyboard - reliable on bare metal AMD and Intel. - -3. **Hardware Validation:** MSI-X proven on real AMD + Intel GPU; IOMMU AMD-Vi proven on real - AMD machine; ACPI `_S5` shutdown proven on real AMD + Intel; NVMe I/O proven on real hardware. - -4. **Power Management:** S3 suspend/resume works on at least one real machine; CPU frequency - scaling observable; thermal shutdown testable. - -5. **Firmware:** `request_firmware_nowait` with uevent dispatch; `PCI_QUIRK_NEED_FIRMWARE` - enforced; Wi-Fi firmware loaded end-to-end on real hardware. - -6. **Wi-Fi:** Intel Wi-Fi chipset validated end-to-end with real AP; scan → connect → DHCP → - internet access verified. - -7. **Bluetooth:** BLE discovery and basic data exchange on real hardware; HCI init sequence - validated; GATT service discovery functional. - -8. **Observability:** Device init timeline observable; per-device init status queryable; - boot-time warning summary available. - -9. **No regressions:** All 25+ existing drivers still work; all QEMU validation scripts still pass; - `redbear-mini` and `redbear-full` still boot to login prompt. - -## 8. Relationship to Existing Plans - -This plan is the **canonical device initialization plan**. It supersedes or integrates with: - -| Existing Plan | Relationship | -|---------------|-------------| -| `IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md` | Absorbed: MSI-X (P1), IOMMU (P2) become Phase 2.3-2.4 here | -| `ACPI-IMPROVEMENT-PLAN.md` | Integrated: Waves 1-4 become Phase 2.5 + Phase 3.1-3.2 here | -| `USB-IMPLEMENTATION-PLAN.md` | Integrated: xHCI hardening + controller gaps become Phase 2.1-2.2 here | -| `XHCID-DEVICE-IMPROVEMENT-PLAN.md` | Integrated: 7-phase xhcid plan consolidated into Phase 2.2 here | -| `WIFI-IMPLEMENTATION-PLAN.md` | Absorbed: Wi-Fi hardware validation becomes Phase 4.2 here | -| `BLUETOOTH-IMPLEMENTATION-PLAN.md` | Absorbed: BT validation becomes Phase 5.1 here | -| `BOOT-PROCESS-ASSESSMENT.md` | Input: boot flow, service ordering, pcid-spawner fix already applied | -| `BOOT-PROCESS-IMPROVEMENT-PLAN.md` | Input: kernel 4GiB fix, DRM/KMS, greeter UI (already addressed) | -| `CONSOLE-TO-KDE-DESKTOP-PLAN.md` | Orthogonal: this plan focuses on device init, not desktop path | - -Existing plans remain as reference material for historical detail and subsystem-specific -technical depth. This plan is the execution authority for sequencing and acceptance criteria. - -## 9. Immediate Next Actions (Week 1 Priorities) - -1. **Create `redox-driver-core` crate** — define `Bus`, `Device`, `Driver` traits -2. **Read Linux 7.0 `drivers/base/driver.c`** — understand the driver binding model to adapt -3. **Audit `pcid` scheme interface** — what device info is already exposed vs what's needed -4. **Select USB EHCI reference implementation** — Linux `ehci-hcd.c` or FreeBSD `ehci.c` -5. **Procure test hardware** — at minimum: one AMD machine with AMD GPU + one Intel machine with Intel GPU -6. **Set up USB keyboard test matrix** — catalog existing USB keyboards and host controllers -7. **Create firmware manifest template** — define format for `/lib/firmware/MANIFEST.txt` -8. **Schedule MSI-X hardware validation session** — reserve time on test machines for Phase 2.3 - ---- - -*This plan will be updated as implementation progresses. Each phase section will receive -detailed task breakdown (similar to the ACPI and IRQ plans' execution slice format) before -that phase begins.* diff --git a/local/docs/archived/GRAPHICAL-BOOT-ASSESSMENT-2026-05-03.md b/local/docs/archived/GRAPHICAL-BOOT-ASSESSMENT-2026-05-03.md deleted file mode 100644 index 7a4a3758c7..0000000000 --- a/local/docs/archived/GRAPHICAL-BOOT-ASSESSMENT-2026-05-03.md +++ /dev/null @@ -1,36 +0,0 @@ -# Red Bear OS — Graphical Boot Assessment - -**Date**: 2026-05-03 (updated same day after fixes) -**Tested**: redbear-full harddrive.img in QEMU - -## Result: Build SUCCEEDED (after fixes) - -### Original Issue (FIXED) -The `make all CONFIG_NAME=redbear-full` previously failed due to: -1. **POSIX gap**: `sem_open`/`sem_close`/`sem_unlink` were `todo!()` stubs in relibc, preventing Qt6Core.so from linking. **Fixed** via `P5-named-semaphores.patch` (full shm-based implementation). -2. **Config inconsistency**: `kf6-kwayland` and `kf6-kidletime` depend on `libwayland` which cannot build. **Fixed** by marking both as `"ignore"` (they are orphan dependencies of the already-disabled KWin). -3. **Build system races**: Stale stage directories and cargo install overwrite failures. **Fixed** in `src/cook/cook_build.rs` and `src/cook/script.rs`. - -### Current State - -| Component | Status | -|-----------|--------| -| redbear-full build | ✅ 0 failed recipes, 4GB image | -| sem_open/close/unlink | ✅ Exported in libc.so (verified: nm -D) | -| redbear-mini (text-only) | ✅ Boots to login on framebuffer | -| Kernel, drivers, initfs | ✅ Works | -| D-Bus daemon | ✅ Starts (verified via serial probes) | -| redbear-sessiond (login1) | ✅ Starts | -| Evdevd, inputd, ps2d | ✅ Registered | -| Serial debug console | ✅ Fixed (uses /scheme/debug/no-preserve with respawn) | -| KWin / Wayland | 🔲 Blocked by QML gate | -| Greeter UI | 🔲 Blocked by QML gate | - -### Remaining Blockers - -| Blocker | Detail | -|---------|--------| -| libwayland | Cannot build: missing `MSG_NOSIGNAL` and `open_memstream` in relibc | -| kf6-kwayland/kf6-kidletime | Marked "ignore" — temporary, blocked on libwayland | -| QML gate | kirigami → plasma-framework → plasma-workspace requires QtQuick/QML headers | -| KWin | Blocked by QML gate diff --git a/local/docs/archived/GREETER-LOGIN-ANALYSIS.md b/local/docs/archived/GREETER-LOGIN-ANALYSIS.md deleted file mode 100644 index f350216f8b..0000000000 --- a/local/docs/archived/GREETER-LOGIN-ANALYSIS.md +++ /dev/null @@ -1,308 +0,0 @@ -# Red Bear OS Greeter/Login System — Comprehensive Analysis - -**Generated:** 2026-04-26 -**Based on:** Source code analysis of `redbear-authd`, `redbear-greeter`, `redbear-sessiond`, `redbear-session-launch`, `redbear-login-protocol`, init service configuration, and the GREETER-LOGIN-IMPLEMENTATION-PLAN.md. - ---- - -## 1. System Architecture - -### 1.1 Component Topology - -``` -Qt6/QML Login Surface (redbear-greeter-ui, VT3) - │ Unix socket /run/redbear-greeterd.sock (JSON, line-delimited) - ↓ -redbear-greeterd (orchestrator daemon, root-owned, VT3) - │ Unix socket /run/redbear-authd.sock (AuthRequest/AuthResponse JSON) - ↓ -redbear-authd (privileged auth daemon, /etc/shadow verification) - │ spawns via Command:: - ↓ -redbear-session-launch (uid/gid drop + env bootstrap) - │ exec's - ↓ -dbus-run-session -- redbear-kde-session → redbear-compositor --drm + plasmashell - -(redbear-sessiond on system D-Bus → org.freedesktop.login1 for KWin device access) -``` - -**Key socket paths:** -| Socket | Owner | Mode | Purpose | -|--------|-------|------|---------| -| `/run/redbear-authd.sock` | root | 0o600 | greeterd → authd | -| `/run/redbear-greeterd.sock` | greeter user | 0o660 | greeter-ui → greeterd | -| `/run/redbear-sessiond-control.sock` | root | 0o600 | authd → sessiond (JSON SessiondUpdate) | -| `/run/seatd.sock` | root | 0o666 | seatd abstract namespace | - ---- - -## 2. Password Verification (authd) - -**Source:** `local/recipes/system/redbear-authd/source/src/main.rs` lines 101–214 - -**Storage:** Reads `/etc/passwd` (user/uid/gid/home/shell) and `/etc/shadow` (password hash). - -**Format detection:** Both Redox-style (`;`-delimited) and Unix-style (`:`-delimited) passwd/shadow/group entries are auto-detected per-line (line 88–99 in authd main.rs). - -**Hash verification (lines 183–193):** -```rust -fn verify_shadow_password(password: &str, shadow_hash: &str) -> Result { - if shadow_hash.starts_with("$6$") || shadow_hash.starts_with("$5$") { - // SHA-512 or SHA-256 crypt (sha-crypt crate, pure Rust) - return Ok(ShaCrypt::default().verify_password(password.as_bytes(), shadow_hash).is_ok()); - } - if shadow_hash.starts_with("$argon2") { - // Argon2id (rust-argon2 crate) - return Ok(verify_encoded(shadow_hash, password.as_bytes()).unwrap_or(false)); - } - Err(VerifyError::UnsupportedHashFormat) -} -``` - -**Plain-text fallback:** Non-`$` hash strings are compared directly (line 213). Used for unshadowed entries. - -**Lockout policy (lines 237–270):** -- 5 failures in 60s → 30-second lockout -- Rejects locked accounts (`!` or `*` prefix) -- UID < 1000 rejected (except UID 0) - -**Approval system (lines 216–287):** -- Successful auth stores 15-second in-memory approval keyed to `username + VT` -- Session start requires valid (non-expired, VT-matched) approval ticket - ---- - -## 3. Communication: UI ↔ greeterd ↔ authd - -**Protocol:** `redbear-login-protocol` crate (`local/recipes/system/redbear-login-protocol/source/src/lib.rs`) - -```rust -// greeterd → authd -AuthRequest::Authenticate { request_id, username, password, vt } -AuthRequest::StartSession { request_id, username, session: "kde-wayland", vt } -AuthRequest::PowerAction { request_id, action: "shutdown"|"reboot" } - -// authd → greeterd -AuthResponse::AuthenticateResult { request_id, ok, message } -AuthResponse::SessionResult { request_id, ok, exit_code, message } -AuthResponse::PowerResult { request_id, ok, message } -AuthResponse::Error { request_id, message } -``` - -```rust -// UI → greeterd -GreeterRequest::SubmitLogin { username, password } - -// greeterd → UI -GreeterResponse::LoginResult { ok, state, message } -GreeterResponse::ActionResult { ok, message } -``` - -**greeterd state machine:** -``` -Starting → GreeterReady → Authenticating → LaunchingSession → SessionRunning - ↓ - ReturningToGreeter → GreeterReady - ↓ - FatalError (after 3 restarts/60s) -``` - ---- - -## 4. Session Launch - -**Source:** `local/recipes/system/redbear-session-launch/source/src/main.rs` lines 352–385 - -1. Reads `/etc/passwd` + `/etc/group` for uid/gid/groups -2. Creates `XDG_RUNTIME_DIR` (`/run/user/$UID` or `/tmp/run/user/$UID`), chown 0700 -3. Builds clean env: `HOME`, `USER`, `LOGNAME`, `SHELL`, `PATH=/usr/bin:/bin`, `XDG_RUNTIME_DIR`, `WAYLAND_DISPLAY=wayland-0`, `XDG_SEAT=seat0`, `XDG_VTNR`, `LIBSEAT_BACKEND=seatd`, `SEATD_SOCK=/run/seatd.sock`, `XDG_SESSION_TYPE=wayland`, `XDG_CURRENT_DESKTOP=KDE`, `KDE_FULL_SESSION=true`, `XDG_SESSION_ID=c1` -4. `env_clear()` → setuid + setgid + setgroups -5. `exec /usr/bin/dbus-run-session -- /usr/bin/redbear-kde-session` -6. Fallback: direct `redbear-kde-session` if `dbus-run-session` absent - -**redbear-kde-session** (from `docs/05-KDE-PLASMA-ON-REDOX.md`): -```bash -export WAYLAND_DISPLAY=wayland-0 -export XDG_RUNTIME_DIR=/tmp/run/user/0 -dbus-daemon --system & -eval $(dbus-launch --sh-syntax) -redbear-compositor --drm & -sleep 2 && plasmashell & -``` - ---- - -## 5. Init Service Wiring - -**From `config/redbear-full.toml`:** - -``` -Service order: - 12_dbus.service (system D-Bus) - 13_redbear-sessiond.service (org.freedesktop.login1 broker) - 13_seatd.service (seat management) - 19_redbear-authd.service (auth daemon, /usr/bin/redbear-authd) - 20_greeter.service (greeterd, /usr/bin/redbear-greeterd, VT=3) - 29_activate_console.service (inputd -A 2 → VT2 fallback) - 30_console.service (getty 2, respawn) - 31_debug_console.service (getty debug, respawn) -``` - -`20_greeter.service`: -```toml -cmd = "/usr/bin/redbear-greeterd" -envs = { VT = "3", REDBEAR_GREETER_USER = "greeter" } -type = "oneshot_async" -``` - -**Greeter user account** (redbear-full.toml): -```toml -[users.greeter] -password = "" -uid = 101 -gid = 101 -home = "/nonexistent" -shell = "/usr/bin/ion" -``` - ---- - -## 6. D-Bus Integration - -**redbear-sessiond** — `org.freedesktop.login1` on **system D-Bus** via `zbus`: -- `Manager.ListSessions`, `Manager.GetSeat`, `PrepareForShutdown` signal -- `Seat.SwitchTo(vt)` → `inputd -A ` -- `Session.TakeDevice`/`ReleaseDevice` → DRM/input device fd passing -- `Session.TakeControl`/`ReleaseControl` -- Service file: `/usr/share/dbus-1/system-services/org.freedesktop.login1.service` - -**authd and greeterd are NOT D-Bus activated** — started directly by init services. - -**greeter compositor** starts a **session D-Bus** via `dbus-launch`. - ---- - -## 7. Quality and Robustness Assessment - -### 7.1 Strengths - -| Area | Assessment | Detail | -|------|------------|--------| -| **Hash algorithm** | ✅ Excellent | SHA-512 (`$6$`), SHA-256 (`$5$`), Argon2id — all pure-Rust crates, no MD5/DES | -| **Constant-time comparison** | ✅ Good | `sha-crypt::verify_password` and `argon2::verify_encoded` are constant-time by design | -| **Approval windowing** | ✅ Good | 15s approval between auth and session start, VT-bound | -| **Lockout policy** | ✅ Good | 5 attempts / 60s → 30s lockout | -| **Socket permissions** | ✅ Good | authd socket = 0o600, greeterd socket = 0o660 | -| **UID restriction** | ✅ Good | UID < 1000 (non-root) disallowed | -| **Restart bounding** | ✅ Good | 3 restarts/60s → FatalError, fallback consoles preserved | -| **Protocol type safety** | ✅ Good | `redbear-login-protocol` crate is single source of truth for all JSON types | -| **Plain-text fallback** | ⚠️ Acceptable | Non-`$` hash strings compared directly — OK for initial dev users | -| **Fail-closed on unknown hash** | ✅ Good | `UnsupportedHashFormat` → login rejected, not bypassed | -| **Greeter isolates UI crash** | ✅ Good | compositor survives UI crash; respawns UI only | - -### 7.2 Weaknesses and Risks - -| # | Issue | Severity | Location | Impact | -|---|-------|----------|-----------|--------| -| W1 | **No PAM integration** | Medium | authd is custom narrow auth | Limits enterprise use, no pluggable auth modules | -| W2 | **Approval in-memory only** | Medium | authd `HashMap` | authd crash → approvals lost; session start fails after crash | -| W3 | **No password quality enforcement** | Low | authd only checks lockout | Weak passwords accepted (acceptable for Phase 2) | -| W4 | **Hardcoded `kde-wayland` session** | Low | authd line 301, session-launch line 335 | No session chooser, no alternative desktops | -| W5 | **greeterd not respawned by init** | Medium | `20_greeter.service` type=oneshot_async | If greeterd crashes, system stuck at console (no auto-recovery) | -| W6 | **No seatd watchdog** | Medium | seatd service has no internal restart | seatd crash → compositor immediately fails | -| W7 | **Static device_map.rs** | Medium | major/minor hardcoded table | Non-static hardware (USB GPUs, etc.) not discovered | -| W8 | **No session tracking via D-Bus** | Low | authd → sessiond via raw JSON socket | `SetSession`/`ResetSession` bypass login1 surface | -| W9 | **Power action fallbacks missing** | Low | authd calls `/usr/bin/shutdown`, `/usr/bin/reboot` | May not exist on Redox; failure is silent | -| W10 | **greeterd socket path hardcoded** | Low | `/run/redbear-greeterd.sock` vs XDG_RUNTIME_DIR | Works for single-seat; breaks in multi-seat | -| W11 | **greeter init service is `true` stub** | **Critical** | `redbear-greeter-services.toml` → `20_greeter.service cmd = "true"` | Real greeter only in `redbear-full.toml`; mini/grub don't have it | -| W12 | ~~redbear-greeter-compositor missing from image~~(resolved) | Low | Recipe installs to both `/usr/bin/` and `/usr/share/redbear/greeter/`; main.rs checks both | compositor binary available via both paths | -| W13 | ~~dbus-run-session may not exist in image~~(resolved) | Low | dbus in redbear-mini config (inherit by redbear-full); session-launch prefers `/usr/bin/dbus-run-session`; dbus recipe installs it | D-Bus session bus available | - -### 7.3 Greeter Login-Screen Prerequisites (most resolved; bounded QEMU proof now passes) - -*Note: As of 2026-04-29, the bounded `redbear-full` QEMU greeter proof passes (`GREETER_HELLO=ok`, `GREETER_VALID=ok`). Most items below are satisfied by the active config; remaining items are "verify via build."* - -| Blocker | Source | Fix | -|---------|--------|-----| -| greeter init service stub in greeter-services.toml | `20_greeter.service cmd = "true"` | Use `redbear-full.toml` service definition (already correct there) | -| ~~compositor binary path mismatch~~ (resolved) | Recipe installs to both `/usr/bin/` and `/usr/share/redbear/greeter/`; greeterd checks both | No action needed | -| seatd package in config | seatd = {} now present in redbear-full.toml packages section | Rebuild to include seatd in image | -| redbear-authd now in config | authd recipe in redbear-full config | Verify authd binary reaches image via build | -| redbear-sessiond now in config | sessiond inherited from redbear-mini config | Verify sessiond binary reaches image via build | -| greeter user account present in config | `[users.greeter]` in redbear-full config | Verify greeter user uid=101 in /etc/passwd in image after build | -| compositor requires DRM but QEMU has none | `redbear-compositor --drm` fails in VM | Use `--virtual` in VM; compositor script already handles this | - ---- - -## 8. File Path Reference - -| Artifact | Path | -|---|---| -| authd binary | `/usr/bin/redbear-authd` | -| authd socket | `/run/redbear-authd.sock` | -| greeterd socket | `/run/redbear-greeterd.sock` | -| greeterd binary | `/usr/bin/redbear-greeterd` | -| greeter-ui binary | `/usr/bin/redbear-greeter-ui` | -| compositor script | `/usr/bin/redbear-greeter-compositor` | -| compositor (share) | `/usr/share/redbear/greeter/redbear-greeter-compositor` | -| session-launch binary | `/usr/bin/redbear-session-launch` | -| sessiond binary | `/usr/bin/redbear-sessiond` | -| greeterd init service | `/usr/lib/init.d/20_greeter.service` | -| authd init service | `/usr/lib/init.d/19_redbear-authd.service` | -| sessiond init service | `/usr/lib/init.d/13_redbear-sessiond.service` | -| seatd init service | `/usr/lib/init.d/13_seatd.service` | -| greeter background | `/usr/share/redbear/greeter/background.png` | -| greeter icon | `/usr/share/redbear/greeter/icon.png` | -| sessiond control socket | `/run/redbear-sessiond-control.sock` | -| seatd socket | `/run/seatd.sock` | -| passwd file | `/etc/passwd` (redox `;` or unix `:` delimited) | -| shadow file | `/etc/shadow` | -| group file | `/etc/group` | -| greeter user account | uid=101, gid=101 in /etc/passwd | - ---- - -## 9. Improvement Recommendations (Priority Order) - -### P0 — Make Greeter Actually Reach Login Screen - -1. **Fix greeter init service**: Ensure `20_greeter.service` in `redbear-full.toml` (not the stub in greeter-services.toml) is the canonical one. greeter-services.toml is a bounded proof fragment; the real service lives in redbear-full.toml. -2. **Verify all 5 greeter packages are in redbear-full.toml**: `seatd`, `redbear-authd`, `redbear-sessiond`, `redbear-session-launch`, `redbear-greeter` -3. **Verify compositor binary at `/usr/bin/redbear-greeter-compositor`** in the built image -4. **Verify greeter user (uid=101) exists** in /etc/passwd in image -5. **Add compositor fallback** to `--virtual` when `--drm` fails (script already does this) - -### P1 — Hardening - -6. **Add respawn to greeterd init service**: `type = "oneshot_async", respawn = true` — greeterd crash shouldn't leave system at console -7. **Add seatd respawn**: same logic -8. **Fix redbear-sessiond `Seat::SwitchTo`** to return error rather than silently ignore failures -9. **Add watchdog for greeterd** — if greeterd crashes, init should restart it - -### P2 — Security Hardening - -10. **Add password quality enforcement**: minimum length, entropy check before accepting -11. **Rate-limit by source IP/VT**: prevent VT-based brute force -12. **Add audit log for auth failures**: log to syslog or dedicated auth log -13. **Add session listing via control socket**: currently authd writes `SetSession`/`ResetSession` but there's no readback mechanism - -### P3 — Architectural - -14. **Implement `TakeDevice`/`ReleaseDevice` fully**: current session.rs has the skeleton but device fd passing needs verification -15. **Dynamic device enumeration**: replace static device_map.rs with udev-shim runtime queries -16. **Add greeter watchdog daemon**: separate from greeterd, monitors and restarts it -17. **D-Bus activate greeterd and authd**: remove init service startup dependency, use D-Bus activation instead -18. **Add power action binaries**: create `/usr/bin/shutdown` and `/usr/bin/reboot` symlinks or wrappers that call init system -19. **Implement `PrepareForShutdown`/`PrepareForSleep` signals**: for session cleanup on system power events - -### P4 — Future - -20. **Add PAM integration** via a minimal PAM-like module system in authd -21. **Add session chooser** (console vs kde-wayland) via greeter UI -22. **Multi-seat support**: XDG_RUNTIME_DIR per seat, greeterd socket per seat -23. **Fingerprint/webauthn support**: extend authd protocol + greeter UI - ---- - -*End of Analysis* \ No newline at end of file diff --git a/local/docs/archived/IOMMU-SPEC-REFERENCE.md b/local/docs/archived/IOMMU-SPEC-REFERENCE.md deleted file mode 100644 index 1c90e0e412..0000000000 --- a/local/docs/archived/IOMMU-SPEC-REFERENCE.md +++ /dev/null @@ -1,1946 +0,0 @@ -# IOMMU Specification Reference — AMD-Vi & Intel VT-d - -**Purpose**: Implementation-ready hardware register and data structure reference for Red Bear OS IOMMU support. Based on AMD IOMMU Specification 48882 Rev 3.10 and Intel Virtualization Technology for Directed I/O (VT-d) Rev 5.0. - -**Status**: The `iommu` daemon now builds in-tree, owns AMD-Vi runtime initialization, and also detects the presence of a kernel ACPI `DMAR` table as a convergence seam so Intel VT-d runtime ownership can move here instead of remaining conceptually stranded in `acpid`. That does **not** yet mean Intel VT-d ownership is cleanly closed in the current tree. Hardware validation is still missing in the AMD-first integration plan (see `AMD-FIRST-INTEGRATION.md`). This document provides the register and data-structure reference for finishing AMD-Vi and Intel VT-d bring-up. - ---- - -## 1. AMD-Vi (AMD IOMMU) - -### 1.1 MMIO Register Map - -Base address obtained from ACPI IVRS table (IVHD entry `IOMMUInfo` field). - -| Offset | Name | Size | Access | Description | -|--------|------|------|--------|-------------| -| 0x0000 | DevTableBar | 64-bit | R/W | Device Table Base Address. Bits 12:51 hold physical address. Bits 0:8 = DeviceTableSize (entries = 2^(size+1), max 65536). Must be 4KiB-aligned. | -| 0x0008 | CmdBufBar | 64-bit | R/W | Command Buffer Base Address. Bits 12:51 hold physical address. Bits 0:8 = CmdBufLen (size = 2^(len+2) × 16 bytes). Must be 4KiB-aligned. | -| 0x0010 | EvtLogBar | 64-bit | R/W | Event Log Base Address. Bits 12:51 hold physical address. Bits 0:8 = EvtLogLen (size = 2^(len+2) × 16 bytes). Must be 4KiB-aligned. | -| 0x0018 | Control | 32-bit | R/W | IOMMU Control Register. See bit layout below. | -| 0x0020 | ExclusionBase | 64-bit | R/W | Exclusion Range Base Address. Physical address of excluded region start. | -| 0x0028 | ExclusionLimit | 64-bit | R/W | Exclusion Range Limit Address. Physical address of excluded region end. | -| 0x0030 | ExtendedFeature | 64-bit | RO | Extended Feature Register. Capability flags. Read to determine supported features. | -| 0x0038 | PprLogBar | 64-bit | R/W | Peripheral Page Request Log Base Address. Bits 12:51 = address, Bits 0:8 = log length. | -| 0x0030 | ExtendedFeature | 64-bit | RO | Extended Feature Register (alias for capability query). | -| 0x2000 | CmdBufHead | 64-bit | R/W | Command Buffer Head Pointer. Index into command buffer (byte offset / 16). | -| 0x2008 | CmdBufTail | 64-bit | R/W | Command Buffer Tail Pointer. Written by software to submit commands. | -| 0x2010 | EvtLogHead | 64-bit | R/W | Event Log Head Pointer. Written by software after reading events. | -| 0x2018 | EvtLogTail | 64-bit | RO | Event Log Tail Pointer. Updated by IOMMU hardware after writing event. | -| 0x2020 | Status | 32-bit | RO | IOMMU Status Register. See bit layout below. | -| 0x2028 | PprLogHead | 64-bit | R/W | PPR Log Head Pointer. | -| 0x2030 | PprLogTail | 64-bit | RO | PPR Log Tail Pointer. | - -#### Control Register (0x0018) Bit Layout - -| Bit | Name | Description | -|-----|------|-------------| -| 0 | IOMMUEnable | 0 = IOMMU translations disabled, 1 = enabled. Must be set last after all other config. | -| 1 | HTTunEn | HyperTransport Tunnel Enable. Set 0 for modern systems. | -| 2 | EventLogEn | Event Log Enable. Set 1 to enable event logging. | -| 3 | EventIntEn | Event Log Interrupt Enable. Set 1 to generate interrupts on event log overflow. | -| 4 | ComWaitIntEn | Completion Wait Interrupt Enable. | -| 5 | CmdBufEn | Command Buffer Enable. Set 1 to enable command processing. | -| 6 | PprLogEn | Peripheral Page Request Log Enable. | -| 7 | PprIntEn | PPR Log Interrupt Enable. | -| 8 | PprEn | Peripheral Page Request Processing Enable. | -| 9 | GTEn | Guest Translation Enable. | -| 10 | GAEn | Guest APIC (Advanced Programmable Interrupt Controller) Enable. | -| 12 | CRW | IOMMU Reset. Write 1 to clear errors after reset. | -| 13 | SMifEn | SMI Filter Enable. | -| 14 | SlFWEn | Self-Modify Firmware Enable. | -| 15 | SMifLogEn | SMI Filter Log Enable. | -| 16 | GAMEn_0 | Guest APIC Mode bit 0. | -| 17 | GAMEn_1 | Guest APIC Mode bit 1. | -| 18 | GAMEn_2 | Guest APIC Mode bit 2. | -| 22 | XTEn | x2APIC Enabled. | -| 23 | NXEn | No-Execute Enable. | -| 24 | IRQTableLEn | Interrupt Remap Table Length Enable. | - -#### Status Register (0x2020) Bit Layout - -| Bit | Name | Description | -|-----|------|-------------| -| 0 | IOMMURunning | 1 = IOMMU is processing commands or translations. | -| 1 | EventOverflow | 1 = Event log overflow occurred. Write 1 to clear. | -| 2 | EventLogInt | 1 = Event log interrupt pending. | -| 3 | ComWaitInt | 1 = Completion wait interrupt pending. | -| 4 | PprOverflow | 1 = PPR log overflow. | -| 5 | PprInt | 1 = PPR log interrupt pending. | -| 31 | RsvdP | Reserved (polling status bits). | - -#### Extended Feature Register (0x0030) Bit Layout - -| Bit | Name | Description | -|-----|------|-------------| -| 0 | PrefSup | Prefetch Support. | -| 1 | PPRSup | Peripheral Page Request Support. | -| 2 | XTSup | x2APIC Support. | -| 3 | NXSup | No-Execute Support. | -| 4 | GTSup | Guest Translation Support. | -| 5 | bit5 | Reserved. | -| 6 | IASup | Invalidate IOMMU All Support. | -| 7 | GASup | Guest APIC Support. | -| 8 | HESup | Hardware Error Registers Support. | -| 9 | PCSup | Performance Counters Support. | -| 12:15 | MsiNumPPR | MSI message number for PPR. | -| 27 | PASMax | Maximum PASID support. | -| 46:52 | PASMax | Physical Address Space Max (1 = 48-bit, 2 = 52-bit). | -| 57 | GISup | Global Invalidate Support. | -| 58 | HASup | Host Address Translation Size. | - -### 1.2 Device Table Entry (DTE) - -The Device Table holds up to 65536 entries indexed by BDF (Bus:Device:Function). Each entry is 256 bits (32 bytes). The table must be contiguous in physical memory. - -**Table size**: entries × 32 bytes. With 65536 entries, max 2 MiB. - -``` -DTE layout (256 bits = data[0] data[1] data[2] data[3], each u64): - -data[0] (bits 0-63): - [ 0] V — Valid. 1 = entry is valid. - [ 1] TV — Translation Valid. 1 = address translation enabled for this device. - [ 2:3] Reserved - [ 4] IW — Write permission (when Mode != 0). 1 = device may write. - [ 5] IR — Read permission (when Mode != 0). 1 = device may read. - [ 6:7] Reserved - [ 8] SE — Snoop Enable. 1 = device requests are snooped. - [ 9:11] Mode — Translation mode: - 000 = No translation (pass-through if TV=0) - 001 = 1-level page table - 010 = 2-level page table - 011 = 3-level page table - 100 = 4-level page table - 101 = 5-level page table - 110 = 6-level page table - 111 = Reserved - [12:51] PTP — Page Table Root Pointer. Physical address of top-level page table. - Must be 4KiB-aligned. Bits 0:11 of the address are assumed zero. - [52:55] GCR3Trp0 — Guest CR3 Table Root Pointer bits 12:15. - [56:58] GV — Guest Translation Valid bits. - [59] GLX — Guest Levels bit 0. - [60] GLX — Guest Levels bit 1. - [61] IR — Interrupt Remapping Enable. 1 = interrupts from this device are remapped. - [62] IW — Interrupt Write permission. 1 = device may generate interrupt writes. - [63] Reserved - -data[1] (bits 64-127): - [0:3] IntTabLen — Interrupt Remap Table Length. Number of entries = 2^(IntTabLen+1). - 0 = 2 entries, 1 = 4 entries, ..., 10 = 2048 entries, 11 = 4096 entries. - [4:5] IntCtl — Interrupt Control. 00 = abort, 01 = pass-through (no remap), - 10 = remapped, 11 = reserved. - [6:51] IRTP — Interrupt Remap Table Pointer. Physical address of interrupt - remap table. Must be 4KiB-aligned (bits 0:11 assumed zero). - [52:63] Reserved - -data[2] (bits 128-191): - [0:51] GCR3Trp1 — Guest CR3 Table Root Pointer bits 16:63. - [52:63] Reserved - -data[3] (bits 192-255): - [0:15] GCR3Trp2 — Guest CR3 Table Root Pointer bits 64:79. - [16] AttrRsvd — Reserved attribute bit. - [17] AttrU — User bit for device-specific use. - [18:20] Mode2 — Alias to Mode bits (duplicate for hardware). - [21:63] Reserved -``` - -**Key constants from Linux** (`drivers/iommu/amd/amd_iommu_types.h`): - -```c -#define DTE_FLAG_V (1ULL << 0) -#define DTE_FLAG_TV (1ULL << 1) -#define DTE_FLAG_IR (1ULL << 61) -#define DTE_FLAG_IW (1ULL << 62) -#define DTE_MODE_MASK 0x0E00ULL // bits 9:11 -#define DTE_PT_ADDR_MASK 0x0FFFFFFFFFF000ULL // bits 12:51 -#define DEV_DOMID_MASK 0x0FFFFULL // domain ID in bits 0:15 (when TV=0) -``` - -### 1.3 Interrupt Remapping Table Entry (IRTE) - -The Interrupt Remap Table is pointed to by the IRTP field in the DTE. Each entry is 128 bits (16 bytes). Length is 2^(IntTabLen+1) entries. - -``` -IRTE (128 bits = data[0] data[1], each u64): - -data[0]: - [0] RemapEn — Remap Enable. 1 = this entry is valid for remapping. - [1] SupIOPF — Suppress I/O Page Faults. 1 = suppress faults from this interrupt. - [2] IntType — Interrupt Type: - 000 = Fixed (edge or level, determined by trigger mode) - 001 = Arbitrated - 010 = SMI - 011 = NMI - 100 = INIT - 101 = EXTINT - 111 = Hardware-specific - [3:4] IntType bits continued (3-bit field uses bits 2:4) - [5] Rsvd — Reserved. - [5:7] DM — Delivery Mode. 0 = Fixed, 1 = Lowest Priority. - [8] IRrsvd — Reserved. - [9:10] GV — Guest Vector. - [11] GDstMode — Guest Destination Mode. 0 = Physical, 1 = Logical. - [12] DstMode — Destination Mode. 0 = Physical APIC ID, 1 = Logical. - [13:15] Rsvd — Reserved. - [16:31] DstID — Destination APIC ID. For x2APIC, full 32-bit ID (low 16 bits here). - [16:31] DstLo — Low 16 bits of destination APIC ID. - [32:63] Vector — Interrupt vector (0x10..0xFE). - -data[1]: - [0:31] DstHi — High 32 bits of x2APIC destination ID. Zero for xAPIC. - [32:63] Rsvd — Reserved. Must be zero. -``` - -**IRTE bit layout for x2APIC mode (when XTSup=1 in ExtendedFeature)**: - -``` -data[0]: - [0] RemapEn — 1 = valid - [1] SupIOPF — Suppress IO Page Fault - [2:4] IntType — Interrupt type (same as above) - [5:7] Rsvd - [8] DstMode — 0 = physical, 1 = logical - [9:10] Rsvd - [16:31] DstIDLo — Low 16 bits of x2APIC ID - [32:39] Vector — Interrupt vector - [40:63] Rsvd - -data[1]: - [0:31] DstIDHi — High 32 bits of x2APIC destination ID - [32:63] Rsvd -``` - -### 1.4 Command Buffer Entry - -The command buffer is a circular queue. Each entry is 128 bits (16 bytes = 4 × u32). Software writes to the tail, hardware reads from the head. Base address in CmdBufBar, head/tail pointers in CmdBufHead/CmdBufTail. - -**Buffer sizing**: 8192 bytes default (512 entries). Size = 2^(CmdBufLen+2) × 16 bytes. - -``` -Command Buffer Entry (128 bits = word[0] word[1] word[2] word[3], each u32): - -word[0]: - [0:3] Opcode — Command opcode (see below) - [4:31] Varies — Opcode-specific operands - -word[1], word[2], word[3]: - Opcode-specific payload. See each command format below. -``` - -#### COMPLETION_WAIT (Opcode 0x01) - -Used to poll for command completion. Can generate an interrupt or write a value to memory. - -``` -word[0]: [0:3]=0x01, [4]=Store (1=write to memory), [5]=Interrupt (1=generate IRQ), - [6:31] Reserved -word[1]: [0:31] Store Address low 32 bits (physical, must be 8-byte aligned) -word[2]: [0:31] Store Address high 32 bits -word[3]: [0:31] Store Data — value written to Store Address when command completes -``` - -#### INVALIDATE_DEVTAB_ENTRY (Opcode 0x02) - -Invalidates a single device table entry. Must be issued after modifying a DTE. - -``` -word[0]: [0:3]=0x02, [4:31] Reserved -word[1]: [0:15] DeviceId (BDF format: Bus[15:8] | Dev[7:3] | Func[2:0]) - [16:31] Reserved -word[2]: [0:31] Reserved -word[3]: [0:31] Reserved -``` - -#### INVALIDATE_IOMMU_PAGES (Opcode 0x03) - -Invalidates translation cache (TLB) entries for a range of pages. - -``` -word[0]: [0:3]=0x03, [4]=S (Size: 0=invalidate one page, 1=invalidate all pages for domain), - [5]=PDE (Page Directory Entry: 1=invalidate PDE cache too), - [6:31] Reserved -word[1]: [0:15] DomainId — domain to invalidate - [16:31] Reserved -word[2]: [0:51] Address — virtual address to invalidate (page-aligned). Ignored if S=1. - [52:63] Reserved -word[3]: [0:31] Reserved -``` - -#### INVALIDATE_INTERRUPT_TABLE (Opcode 0x04) - -Invalidates the interrupt remap cache for a device. - -``` -word[0]: [0:3]=0x04, [4:31] Reserved -word[1]: [0:15] DeviceId (BDF format) - [16:31] Reserved -word[2]: [0:31] Reserved -word[3]: [0:31] Reserved -``` - -#### INVALIDATE_IOMMU_ALL (Opcode 0x05) - -Invalidates all IOMMU caches (TLB, DTE, IRTE). Available when IASup=1. - -``` -word[0]: [0:3]=0x05, [4:31] Reserved -word[1]: [0:31] Reserved -word[2]: [0:31] Reserved -word[3]: [0:31] Reserved -``` - -### 1.5 Event Log Entry - -The event log is a circular queue written by the IOMMU hardware. Each entry is 128 bits (16 bytes = 4 × u32). Base address in EvtLogBar. - -**Buffer sizing**: 8192 bytes default (512 entries). Size = 2^(EvtLogLen+2) × 16 bytes. - -``` -Event Log Entry (128 bits = word[0] word[1] word[2] word[3]): - -word[0]: - [0:15] EventCode — Event type code (see below) - [16:31] EventFlags — Event-specific flags - -word[1], word[2], word[3]: - Event-specific data. See each event type below. -``` - -#### IO_PAGE_FAULT (Event Code 0x01) - -Generated when a device accesses an address that fails translation. - -``` -word[0]: [0:15]=0x01, [16] TR (Translation Response: 1=fault in translation), - [17] RZ (Read/Zero: 1=read of zero page), [18] I (Interrupt: 1=interrupt request), - [19] PE (Permission Error: 1=permission violation), [20] RW (1=write, 0=read), - [21] PR (Present: 1=PTE was present), [22] Rsvd -word[1]: [0:15] DeviceId (BDF), [16:31] Reserved or PASID -word[2]: [0:31] Fault Address low 32 bits -word[3]: [0:31] Fault Address high 32 bits -``` - -#### INVALIDATE_DEVICE_TABLE (Event Code 0x02) - -Generated when hardware detects an invalid DTE during a transaction. - -``` -word[0]: [0:15]=0x02, [16:31] Reserved -word[1]: [0:15] DeviceId (BDF), [16:31] Reserved -word[2]: [0:31] Reserved -word[3]: [0:31] Reserved -``` - -#### INVALIDATE_COMMAND (Event Code 0x03) - -Generated when an invalid command is detected in the command buffer. - -``` -word[0]: [0:15]=0x03, [16:31] Reserved -word[1]: [0:15] Reserved, [16:31] Reserved -word[2]: [0:31] Physical address of the illegal command (low) -word[3]: [0:31] Physical address of the illegal command (high) -``` - -#### COMMAND_HARDWARE_ERROR (Event Code 0x05) - -Hardware error during command processing. - -``` -word[0]: [0:15]=0x05, [16:31] Error flags -word[1]: [0:31] Error address or type -word[2]: [0:31] Error address low -word[3]: [0:31] Error address high -``` - -### 1.6 IVRS ACPI Table - -The IVRS (I/O Virtualization Reporting Structure) is the ACPI table that describes AMD IOMMU topology. Found by scanning ACPI tables with signature "IVRS" (0x56534949). - -#### IVRS Header (36 bytes) - -``` -Offset Size Field Description -0x00 4 Signature "IVRS" (0x56534949) -0x04 4 Length Total table length in bytes -0x08 1 Revision 2 = revision 2 (AMD-Vi), 3 = revision 3 -0x09 1 Checksum ACPI checksum (sum of all bytes = 0) -0x0A 6 OemId OEM identifier -0x10 8 OemTableId OEM table identifier -0x18 4 OemRevision OEM revision -0x1C 4 CreatorId ASL compiler vendor -0x20 4 CreatorRevision ASL compiler revision -0x24 4 IvInfo IOMMU Virtualization Info: - [0:7] = Virtualization Spec Revision (40 = rev 4.0) - [8:9] = EFRSup (Extended Feature Register supported) - [10:11] = Reserved - [31] = HT AtsResv (HT ATS reserved) -``` - -#### IVHD Entry (I/O Virtualization Hardware Definition) - -Describes a single IOMMU unit. There can be multiple IVHD entries for multiple IOMMUs. - -``` -Offset Size Field Description -0x00 1 Type 0x10 = IVHD type 10 (rev 2), 0x11 = IVHD type 11 (rev 3, 64-bit) -0x01 1 Flags Feature flags: - [0] = HtTunEn (HT tunnel enable) - [1] = PassPW (Pass posted writes) - [2] = ResPassPW (Reset PassPW) - [3] = Isoc (Isoc support) - [4] = IotlbSup (IOTLB support) - [5] = Coherent (Coherent IOMMU) - [6] = PrefSup (Prefetch support) - [7] = PPRSup (PPR support) -0x02 2 Length Total length of this IVHD entry including device entries -0x04 2 DeviceId BDF of the IOMMU PCI device -0x06 2 CapabilityOffset PCI capability offset for IOMMU capability block -0x08 8 IOMMUBaseAddress Physical MMIO base address of IOMMU registers - (type 10: bits 0:51 valid, type 11: full 64-bit) -0x10 2 PciSegmentGroup PCI segment group number -0x12 2 IommuInfo IOMMU Info: - [0:5] = MSI number for event log - [6:12] = Unit ID (IOMMU hardware unit ID) - [13:15] = Reserved -0x14 4 IommuEfr Extended Feature Register attributes (type 11 only) -0x18 ... DeviceEntries Variable-length device entry list follows -``` - -#### IVHD Device Entry Types - -Each device entry in an IVHD starts with a type byte followed by data. - -| Type | Name | Size | Description | -|------|------|------|-------------| -| 0x00 | IVHD_ALL | 4 | Select all devices (except those listed in other entries). Data = all zeros. | -| 0x01 | IVHD_SEL | 4 | Select a single device. Bytes 2:3 = DeviceId (BDF). Byte 4 = Data (LSA flags). | -| 0x02 | IVHD_SOR | 4 | Start of Range. Bytes 2:3 = first DeviceId in range. | -| 0x03 | IVHD_EOR | 4 | End of Range. Bytes 2:3 = last DeviceId in range. | -| 0x42 | IVHD_PAD4 | 8 | 4-byte PAD entry (reserved extension). | -| 0x43 | IVHD_PAD8 | 12 | 8-byte PAD entry (reserved extension). | -| 0x44 | IVHD_VAR | Variable | Variable-length entry. Byte 1 = length. Used for alias, extended selections. | - -#### IVHD Device Entry Data Byte - -``` -Bits of the Data byte in IVHD_SEL/IVHD_SOR: - [0] Lint0Pass — LINT0 remapping passthrough - [1] Lint1Pass — LINT1 remapping passthrough - [2] SysMgt — System Management: - 00 = No system management - 01 = System Management at request level - 10 = System Management at fault level - [3] SysMgt — (continued) - [4] NMIPass — NMI remapping passthrough - [5] ExtIntPass — External Interrupt remapping passthrough - [6] InitPass — INIT remapping passthrough - [7] Rsvd — Reserved -``` - -#### IVMD Entry (I/O Virtualization Memory Definition) - -Describes a memory region that has special IOMMU handling. Appears after IVHD entries. - -``` -Offset Size Field Description -0x00 1 Type 0x20 = IVMD type 20 (rev 2), 0x21 = IVMD type 21 (rev 3) -0x01 1 Flags Memory block flags: - [0] = Unity (untranslated/unity mapping) - [1] = Read (device may read) - [2] = Write (device may write) - [3] = ExclRange (exclusion range) -0x02 2 Length Total length of this IVMD entry (16 or 24 bytes) -0x04 2 DeviceId Start DeviceId (BDF) or 0x0000 for all devices -0x06 2 AuxData Auxiliary data (reserved in most implementations) -0x08 8 StartAddress Physical start address of the memory region (type 20: 32-bit in low bits) -0x10 8 MemoryLength Length of the memory region in bytes (type 20: 32-bit in low bits) -``` - -### 1.7 Page Table Entry (PTE) - -AMD-Vi page tables use multi-level radix tree. The number of levels is set by the DTE Mode field (1 to 6 levels). Each PTE is 64 bits. - -``` -PTE (64 bits): - [0] PR — Present. 1 = this entry maps a valid page or points to next level. - [1] U — User/Supervisor. 1 = accessible from user level. (only with NXSup) - [2] IW — Write permission. 1 = device may write to this page. - [3] IR — Read permission. 1 = device may read this page. - [4:8] Rsvd — Reserved. Must be zero. - [9:11] NextLevel — Next page table level (0=PTE/leaf, 1=PDE, 2=PDPTE, 3=PML4E, 4=PML5E). - At leaf level (PR=1, NextLevel=0): bits 12:51 = physical page frame. - At non-leaf level (PR=1, NextLevel>0): bits 12:51 = next table address. - [12:51] OutputAddr — Physical address of page frame (leaf) or next-level table (non-leaf). - Must be 4KiB-aligned (bits 0:11 assumed zero). - [51:58] Rsvd — Reserved. Must be zero. - [59] FC — Force Coherent. 1 = force coherent transactions for this page. - [60] Rsvd — Reserved. - [61] IR — Interrupt Remap (alias in page tables, platform-specific). - [62] IW — Interrupt Write (alias in page tables, platform-specific). - [63] NX — No-Execute. 1 = instruction fetches from this page are blocked (only with NXSup). -``` - -**Level-to-address-bits mapping**: - -| Levels | Address Bits | Max Physical Address | -|--------|-------------|---------------------| -| 1 | 21 | 2 MiB | -| 2 | 30 | 1 GiB | -| 3 | 39 | 512 GiB | -| 4 | 48 | 256 TiB | -| 5 | 57 | 128 PiB | -| 6 | 63 | ~8 EiB | - -**Linux page table macros** (`drivers/iommu/amd/amd_iommu_types.h`): - -```c -#define PM_LEVEL_SHIFT 9 -#define PM_LEVEL_SIZE (1UL << PM_LEVEL_SHIFT) -#define PM_LEVEL_INDEX(level, address) \ - (((address) >> (12 + (((level) - 1) * 9))) & 0x1FF) -#define PM_LEVEL_ENC(level, address) \ - ((address) | (((level) - 1) << 9) | 1ULL) // PR=1, NextLevel=level-1 -#define PM_PTE_LEVEL(pte) (((pte) >> 9) & 0x7) -``` - -### 1.8 Initialization Sequence (AMD-Vi) - -Step-by-step register programming to bring up AMD-Vi IOMMU. - -``` -Step 1: Discover IOMMU hardware - - Scan ACPI tables for IVRS signature - - Parse IVHD entries to find MMIO base address - - Read ExtendedFeature (0x0030) to determine capabilities - -Step 2: Disable IOMMU (ensure clean state) - - Control = 0x00000000 (IOMMUEnable=0, all features off) - - Wait until Status[0] (IOMMURunning) = 0 - -Step 3: Allocate and zero Device Table - - Alloc 2 MiB contiguous physical memory (65536 × 32 bytes) - - Zero all entries - - Write DevTableBar (0x0000): - Bits 0:8 = DevTableSize (0x0F for 65536 entries: 2^(0x0F+1) = 65536) - Bits 12:51 = Physical address of table - -Step 4: Allocate and zero Command Buffer - - Alloc 8192 bytes contiguous physical (512 entries × 16 bytes) - - Zero all entries - - Write CmdBufBar (0x0008): - Bits 0:8 = CmdBufLen (0x08 for 512 entries: 2^(0x08+2) = 4096 bytes... use 0x09 for 8192) - Bits 12:51 = Physical address - -Step 5: Allocate and zero Event Log - - Alloc 8192 bytes contiguous physical (512 entries × 16 bytes) - - Zero all entries - - Write EvtLogBar (0x0010): - Bits 0:8 = EvtLogLen (0x09 for 8192 bytes) - Bits 12:51 = Physical address - -Step 6: Set up exclusion range (optional) - - Write ExclusionBase (0x0020) = start of excluded physical range - - Write ExclusionLimit (0x0028) = end of excluded physical range - - Skip if no exclusion needed - -Step 7: Reset head/tail pointers - - CmdBufHead (0x2000) = 0 - - CmdBufTail (0x2008) = 0 - - EvtLogHead (0x2010) = 0 - - (EvtLogTail is RO, hardware sets it) - -Step 8: Allocate and zero Interrupt Remap Table (if IR needed) - - Alloc 4096 × 16 bytes = 64 KiB (for IntTabLen=11, max 4096 entries) - - Zero all entries - - Configure each device's DTE with IRTP pointing to this table - -Step 9: Configure DTEs for devices - - For each device that needs translation: - Set V=1, TV=1, Mode=4 (4-level), PTP=root page table address - Set IR=1, IW=1 if interrupt remapping is used - Set IntCtl=0x02 (remapped), IntTabLen, IRTP - -Step 10: Enable features in Control register - - Control = 0x00000000 | bits for enabled features: - Bit 2 (EventLogEn) = 1 - Bit 5 (CmdBufEn) = 1 - Bit 22 (XTEn) = 1 (if x2APIC supported and in use) - Bit 23 (NXEn) = 1 (if NX supported) - - DO NOT set bit 0 (IOMMUEnable) yet - -Step 11: Flush caches via command buffer - - Submit INVALIDATE_IOMMU_ALL (0x05) if supported, or: - INVALIDATE_DEVTAB_ENTRY for each modified device - INVALIDATE_INTERRUPT_TABLE for each device with IR - - Submit COMPLETION_WAIT (0x01) to synchronize - - Wait for completion - -Step 12: Enable IOMMU translations - - Set Control bit 0 (IOMMUEnable) = 1 - - Read Status to verify IOMMURunning = 1 - -Step 13: Enable interrupts (optional) - - Set Control bit 3 (EventIntEn) = 1 - - Configure MSI delivery for the IOMMU PCI device -``` - ---- - -## 2. Intel VT-d - -### 2.1 MMIO Register Map - -Base address obtained from ACPI DMAR table (DRHD entry `RegisterBase` field). - -| Offset | Name | Size | Access | Description | -|--------|------|------|--------|-------------| -| 0x00 | VER_REG | 32-bit | RO | Architecture Version. [0:7] = Minor, [8:15] = Major. | -| 0x08 | CAP_REG | 64-bit | RO | Capability Register. See bit layout below. | -| 0x10 | ECAP_REG | 64-bit | RO | Extended Capability Register. See bit layout below. | -| 0x18 | GCMD_REG | 32-bit | WO | Global Command Register. Write to request operations. | -| 0x1C | GSTS_REG | 32-bit | RO | Global Status Register. Reflects GCMD results. | -| 0x20 | RTADDR_REG | 64-bit | R/W | Root Table Address. Bit 0 = RTT (Root Table Type: 0=legacy, 1=extended). Bits 12:63 = physical address. | -| 0x28 | CCMD_REG | 64-bit | R/W | Context Command Register. For invalidating context caches. | -| 0x30 | FSTS_REG | 32-bit | RO | Fault Status Register. | -| 0x34 | FECTL_REG | 32-bit | R/W | Fault Event Control Register. | -| 0x38 | FEDATA_REG | 32-bit | R/W | Fault Event Data Register. MSI data. | -| 0x3C | FEADDR_REG | 32-bit | R/W | Fault Event Address Register. MSI address low. | -| 0x40 | FEUADDR_REG | 32-bit | R/W | Fault Event Upper Address Register. MSI address high. | -| 0x48 | AFLOG_REG | 64-bit | R/W | Advanced Fault Log Register. | -| 0x58 | PMEN_REG | 32-bit | R/W | Protected Memory Enable Register. | -| 0x5C | PLMBASE_REG | 32-bit | R/W | Protected Low Memory Base Register. | -| 0x60 | PLMLIMIT_REG | 32-bit | R/W | Protected Low Memory Limit Register. | -| 0x68 | PHMBASE_REG | 64-bit | R/W | Protected High Memory Base Register. | -| 0x70 | PHMLIMIT_REG | 64-bit | R/W | Protected High Memory Limit Register. | -| 0x78 | IQH_REG | 64-bit | RO | Invalidation Queue Head Register. | -| 0x80 | IQT_REG | 64-bit | R/W | Invalidation Queue Tail Register. | -| 0x88 | IQA_REG | 64-bit | R/W | Invalidation Queue Address Register. | -| 0x90 | ICS_REG | 32-bit | RO | Invalidation Completion Status Register. | -| 0x94 | IECTL_REG | 32-bit | R/W | Invalidation Event Control Register. | -| 0x98 | IEDATA_REG | 32-bit | R/W | Invalidation Event Data Register. | -| 0x9C | IEADDR_REG | 32-bit | R/W | Invalidation Event Address Register. | -| 0xA0 | IEUADDR_REG | 32-bit | R/W | Invalidation Event Upper Address Register. | -| 0xB0 | IRTA_REG | 64-bit | R/W | Interrupt Remapping Table Address Register. | - -#### CAP_REG (0x08) Bit Layout - -| Bit | Name | Description | -|-----|------|-------------| -| 0 | ND (bits 0:2) | Number of Domains Supported. 0=4, 1=16, 2=64, 3=256, 4=1024, 5=4K, 6=16K, 7=64K. | -| 3:7 | ZLR | Zero Length Read. 1 = supported. | -| 8 | AFL | Advanced Fault Logging. 1 = supported. | -| 9 | RWBF | Required Write-Buffer Flushing. 1 = software must flush write buffers before invalidations. | -| 10:11 | PLMR | Protected Low Memory Region. 1 = supported. | -| 12:13 | PHMR | Protected High Memory Region. 1 = supported. | -| 14 | CM | Caching Mode. 1 = IOMMU operates in caching mode (no explicit invalidation needed). | -| 15:23 | SAGAW | Supported Adjusted Guest Address Widths. Bit N set = (N+1)-level page tables supported. | -| 24:33 | MGAW | Maximum Guest Address Width. Actual address width = MGAW + 1. | -| 34:35 | MAMV | Maximum Address Mask Value. For interrupt remapping. | -| 36 | ZAM | Zero Address/Mask. For interrupt remapping. | -| 37:39 | Rsvd | Reserved. | -| 40 | FL1GP | First Level 1-GByte Page Support. | -| 41:43 | Rsvd | Reserved. | -| 44 | PSI | Page Selective Invalidation. 1 = supported. | -| 45:51 | Rsvd | Reserved. | -| 52 | SPS | Super Page Support. Bits indicate 2MiB, 1GiB, 512GiB support. | -| 52:55 | FR | Fault Recording Register count minus 1. | -| 56:60 | Rsvd | Reserved. | -| 61:63 | Rsvd | Reserved. | - -#### ECAP_REG (0x10) Bit Layout - -| Bit | Name | Description | -|-----|------|-------------| -| 0 | C | Page Request (PRI) support. | -| 1 | QI | Queued Invalidation support. 1 = IQ mechanism supported. | -| 2 | DT | Device TLB support. | -| 3 | IR | Interrupt Remapping support. 1 = supported. | -| 4 | EIM | Extended Interrupt Mode. 1 = x2APIC mode supported for IR. | -| 5:7 | Rsvd | Reserved. | -| 8 | PT | Pass Through. 1 = second-level translation bypass supported. | -| 9:17 | Rsvd | Reserved. | -| 18 | SC | Snoop Control. | -| 19:24 | Rsvd | Reserved. | -| 25:34 | IRO | IOTLB Register Offset. Offset from base for IOTLB registers. | -| 35:43 | Rsvd | Reserved. | -| 44:47 | MHMV | Maximum Handle Mask Value. | -| 48 | ECS | Extended Context Support. | -| 49 | MTS | Memory Type Support. | -| 50 | NEST | Nested Translation Support. | -| 51:63 | Rsvd | Reserved. | - -#### GCMD_REG (0x18) Bit Layout (Write-Only) - -| Bit | Name | Description | -|-----|------|-------------| -| 31 | TE | Translation Enable. Write 1 to enable/disable. | -| 30 | SRTP | Set Root Table Pointer. Write 1, hardware sets GSTS.RTPS when done. | -| 29 | SFL | Set Fault Log. Write 1 to set fault log pointer. | -| 28 | EAFL | Enable Advanced Fault Log. | -| 27 | WBF | Write Buffer Flush. Write 1, hardware sets GSTS.WBFS when done. | -| 26 | QIE | Queued Invalidation Enable. Write 1 to enable. | -| 25 | SIRTP | Set Interrupt Remap Table Pointer. Write 1, hardware sets GSTS.IRTPS. | -| 24 | CFI | Compatibility Format Interrupt. Write 1 to block compatibility interrupts. | -| 23 | IR | Interrupt Remap. Write 1 to enable interrupt remapping. | -| 0:22 | Rsvd | Reserved. Must write zero. | - -#### GSTS_REG (0x1C) Bit Layout (Read-Only) - -| Bit | Name | Description | -|-----|------|-------------| -| 31 | TES | Translation Enable Status. 1 = enabled. | -| 30 | RTPS | Root Table Pointer Status. 1 = root table pointer set. | -| 29 | FLS | Fault Log Status. | -| 28 | AFLS | Advanced Fault Log Status. | -| 27 | WBFS | Write Buffer Flush Status. 1 = flush complete. | -| 26 | QIES | Queued Invalidation Enable Status. | -| 25 | IRTPS | Interrupt Remap Table Pointer Status. | -| 24 | CFIS | Compatibility Format Interrupt Status. | -| 23 | IRES | Interrupt Remap Enable Status. | -| 0:22 | Rsvd | Reserved. | - -### 2.2 Root Table Entry - -The Root Table is pointed to by RTADDR_REG. It contains 256 entries (one per PCI bus). Each entry is 128 bits (16 bytes). Must be 4KiB-aligned. - -``` -Root Entry (128 bits = data[0] data[1], each u64): - -data[0]: - [0] P — Present. 1 = this bus has context entries. - [1:63] CTP — Context Table Pointer. Physical address of the context table - for this bus. Bits 12:63 hold address. Must be 4KiB-aligned. - -data[1]: - [0:63] Rsvd — Reserved. Must be zero. -``` - -### 2.3 Context Entry - -Each Context Table contains 256 entries (one per device:function on a bus). Each entry is 128 bits (16 bytes). - -``` -Context Entry (128 bits = data[0] data[1], each u64): - -data[0]: - [0] P — Present. 1 = entry is valid. - [1] FPD — Fault Processing Disable. 1 = faults from this device are suppressed. - [2:3] TT — Translation Type: - 00 = Legacy mode (second-level translation only) - 01 = PASID-granular translation - 10 = Pass-through (no second-level translation, bypass) - 11 = Reserved - [4:11] Rsvd — Reserved. - [12:63] SLPTPTR — Second Level Page Table Pointer. Physical address of the - second-level (guest) page table root. Must be 4KiB-aligned. - -data[1]: - [0:15] DID — Domain Identifier. Associates this device with a domain. - [16:63] Rsvd — Reserved. Must be zero. -``` - -**Extended Context Entry** (when ECS=1 in ECAP): - -``` -data[0]: - [0] P — Present - [1] FPD — Fault Processing Disable - [2:3] TT — Translation Type (same as above) - [4:11] Rsvd - [12:63] SLPTPTR — Page table pointer (same as above) - -data[1]: - [0:15] DID — Domain Identifier - [16:19] AW — Address Width. 0=3-level, 1=4-level, 2=5-level, 3=6-level. - [20:63] Rsvd — Reserved -``` - -### 2.4 DMAR ACPI Table - -The DMAR (DMA Remapping) table describes Intel VT-d IOMMU topology. Found by scanning ACPI tables with signature "DMAR" (0x52414D44). - -#### DMAR Header (48 bytes) - -``` -Offset Size Field Description -0x00 4 Signature "DMAR" (0x52414D44) -0x04 4 Length Total table length in bytes -0x08 1 Revision 1 -0x09 1 Checksum ACPI checksum (sum of all bytes = 0) -0x0A 6 OemId OEM identifier -0x10 8 OemTableId OEM table identifier -0x18 4 OemRevision OEM revision -0x1C 4 CreatorId ASL compiler vendor -0x20 4 CreatorRevision ASL compiler revision -0x24 1 HostAddressWidth DMA physical address width (e.g., 46 for 64 TiB) -0x25 1 Flags [0] = INTR_REMAP (interrupt remapping supported) - [1] = X2APIC_OPT_OUT (firmware requests no x2APIC) -0x26 6 Reserved Reserved -0x2C ... RemappingStructures Variable-length list of DRHD/RMRR/ATSR/etc entries -``` - -#### DRHD (DMA Remapping Hardware Unit Definition) - -Describes a single IOMMU unit. Multiple DRHD entries for systems with multiple IOMMUs. - -``` -Offset Size Field Description -0x00 2 Type 0x0001 = DRHD -0x02 2 Length Total length of this entry including device scope -0x04 1 Flags [0] = INCLUDE_PCI_ALL (1=this IOMMU handles all PCI devices - not covered by other non-ALL DRHD entries) -0x05 1 Reserved Reserved -0x06 2 SegmentNumber PCI Segment Group number -0x08 8 RegisterBaseAddress Physical MMIO base address of IOMMU registers -0x10 ... DeviceScope Variable-length device scope entries follow -``` - -#### DRHD Device Scope Entry - -``` -Offset Size Field Description -0x00 1 Type Device scope type: - 0x01 = PCI Endpoint Device - 0x02 = PCI SubHierarchy - 0x03 = IOAPIC - 0x04 = MSI Capable HPET - 0x05 = ACPI Name-Space Device -0x01 1 Length Total length of this scope entry -0x02 1 EnumerationId Enumeration ID (e.g., IOAPIC ID for type 0x03) -0x03 1 StartBusNumber Starting PCI bus number -0x04 ... Path PCI path entries (each 2 bytes: Device, Function) -``` - -#### RMRR (Reserved Memory Region Reporting) - -Describes memory regions that must be identity-mapped for specific devices (e.g., USB controllers, graphics). - -``` -Offset Size Field Description -0x00 2 Type 0x0002 = RMRR -0x02 2 Length Total length of this entry -0x04 2 Reserved Reserved -0x06 2 SegmentNumber PCI Segment Group -0x08 8 BaseAddress Physical start address of reserved region -0x10 8 EndAddress Physical end address of reserved region (inclusive) -0x18 ... DeviceScope Device scope entries for devices that access this region -``` - -#### Other DMAR Sub-Table Types - -| Type | Name | Description | -|------|------|-------------| -| 0x0000 | Reserved | Reserved. | -| 0x0001 | DRHD | DMA Remapping Hardware Unit Definition. | -| 0x0002 | RMRR | Reserved Memory Region Reporting. | -| 0x0003 | ATSR | Root Port ATS (Address Translation Service) Capability Reporting. | -| 0x0004 | RHSA | Remapping Hardware Static Affinity (NUMA locality). | -| 0x0005 | ANDD | ACPI Name-space Device Declaration. | - -### 2.5 Page Table Entry (Intel VT-d) - -Intel VT-d uses multi-level page tables. The number of levels depends on SAGAW in CAP_REG. Typically 3 or 4 levels. Each PTE is 64 bits. - -``` -PTE (64 bits): - [0] R — Read permission. 1 = device may read. - [1] W — Write permission. 1 = device may write. - [2:11] Rsvd — Reserved. Must be zero unless extended features. - [12:63] ADDR — Physical address. For non-leaf: next-level table address (4KiB-aligned). - For leaf: page frame address. - Mask depends on page size: - 4KiB: bits 12:63 - 2MiB: bits 21:63 (super page) - 1GiB: bits 30:63 (super page) -``` - -**Extended PTE with Supervisor bit** (when CAP_REG supports it): - -``` - [2] S — Supervisor. 1 = supervisor-mode page. - [3] AW — Access/Dirty (for first-level translation). - [4] PSE — Page Size Extension (1 = super page at this level). - [5] A — Accessed flag. - [6] D — Dirty flag. - [7:11] Rsvd — Reserved. -``` - -### 2.6 Initialization Sequence (Intel VT-d) - -Step-by-step register programming to bring up Intel VT-d. - -``` -Step 1: Discover IOMMU hardware - - Scan ACPI tables for DMAR signature - - Parse DRHD entries to find MMIO base addresses - - Read CAP_REG (0x08) for capabilities - - Read ECAP_REG (0x10) for extended capabilities - - Read VER_REG (0x00) for architecture version - -Step 2: Ensure IOMMU is disabled - - Verify GSTS_REG.TES = 0 (translation not enabled) - - If TES=1, write GCMD_REG with TE=0, wait for TES to clear - -Step 3: Allocate and zero Root Table - - Alloc 4 KiB (256 entries × 16 bytes) - - Zero all entries - - Write RTADDR_REG (0x20): - Bit 0 = 0 (legacy root table type) - Bits 12:63 = physical address - -Step 4: Set Root Table Pointer - - Write GCMD_REG bit 30 (SRTP) = 1 - - Poll GSTS_REG bit 30 (RTPS) until it reads 1 - -Step 5: Allocate and zero Context Tables (per bus) - - For each bus with devices: - Alloc 4 KiB (256 entries × 16 bytes) - Zero all entries - Set Root Entry P=1, CTP=context table address - -Step 6: Configure Context Entries - - For each device:function: - Set P=1, TT=00 (legacy), SLPTPTR=page table root, DID=domain ID - - For pass-through: Set P=1, TT=10, DID=domain ID - -Step 7: Build page tables (per domain) - - Create page table hierarchy matching SAGAW levels (typically 3 or 4) - - Map device-visible physical addresses to host physical addresses - - For identity mapping: GPA = HPA - -Step 8: Handle RMRR regions - - Identity-map all RMRR regions for their respective devices - - These regions must always be accessible to the listed devices - -Step 9: Allocate Interrupt Remap Table (if ECAP_REG.IR=1) - - Alloc table: 2^(IRTA_REG.TableSize+1) × 16 bytes - - Zero all entries - - Write IRTA_REG (0xB0): - Bits 0:6 = TableSize (e.g., 0xF = 65536 entries) - Bits 6:7 = IRTE Mode (00=remapped, 01=posted) - Bits 12:63 = Physical address - Bit 4 = EIME (Extended Interrupt Mode Enable) if x2APIC - -Step 10: Enable Interrupt Remapping - - Write GCMD_REG bit 25 (SIRTP) = 1 - - Poll GSTS_REG bit 25 (IRTPS) until 1 - - Write GCMD_REG bit 24 (CFI) = 1 to block compatibility format interrupts - - Poll GSTS_REG bit 24 (CFIS) until 1 - - Write GCMD_REG bit 23 (IR) = 1 - - Poll GSTS_REG bit 23 (IRES) until 1 - -Step 11: Invalidate caches - - If QI (Queued Invalidation) supported (ECAP_REG.QI=1): - Set up Invalidation Queue (IQA_REG) - Submit queue-based invalidation descriptors - - Else use register-based invalidation: - Write CCMD_REG for context cache invalidation - Write IOTLB registers for TLB invalidation - -Step 12: Enable translation - - Write GCMD_REG bit 31 (TE) = 1 - - Poll GSTS_REG bit 31 (TES) until 1 - -Step 13: Enable fault handling - - Program FEDATA_REG, FEADDR_REG, FEUADDR_REG for MSI delivery - - Write FECTL_REG to enable fault interrupts -``` - ---- - -## 3. Rust Struct Definitions - -These `#[repr(C, packed)]` structs can be used directly in the Red Bear OS IOMMU implementation. All bitfield access should go through helper methods (shown below) to ensure correct masking. - -### 3.1 AMD-Vi Structs - -```rust -// AMD-Vi MMIO Registers - -/// AMD-Vi IOMMU MMIO register block. -/// Base address from ACPI IVRS IVHD entry. -#[repr(C)] -pub struct AmdViMmio { - pub dev_table_bar: u64, // 0x0000 - pub cmd_buf_bar: u64, // 0x0008 - pub evt_log_bar: u64, // 0x0010 - pub control: u32, // 0x0018 - _pad0: u32, // 0x001C - pub exclusion_base: u64, // 0x0020 - pub exclusion_limit: u64, // 0x0028 - pub extended_feature: u64, // 0x0030 - pub ppr_log_bar: u64, // 0x0038 - _pad1: [u64; 0x03F0], // 0x0040..0x1FFC (padding to 0x2000) - pub cmd_buf_head: u64, // 0x2000 - pub cmd_buf_tail: u64, // 0x2008 - pub evt_log_head: u64, // 0x2010 - pub evt_log_tail: u64, // 0x2018 - pub status: u32, // 0x2020 -} -// Static assertions for offset verification -const _: () = assert!(core::mem::offset_of!(AmdViMmio, dev_table_bar) == 0x0000); -const _: () = assert!(core::mem::offset_of!(AmdViMmio, control) == 0x0018); -const _: () = assert!(core::mem::offset_of!(AmdViMmio, cmd_buf_head) == 0x2000); - -/// AMD-Vi Control Register bits. -pub mod amd_control { - pub const IOMMU_ENABLE: u32 = 1 << 0; - pub const HT_TUN_EN: u32 = 1 << 1; - pub const EVENT_LOG_EN: u32 = 1 << 2; - pub const EVENT_INT_EN: u32 = 1 << 3; - pub const COM_WAIT_INT_EN: u32 = 1 << 4; - pub const CMD_BUF_EN: u32 = 1 << 5; - pub const PPR_LOG_EN: u32 = 1 << 6; - pub const PPR_INT_EN: u32 = 1 << 7; - pub const PPR_EN: u32 = 1 << 8; - pub const GT_EN: u32 = 1 << 9; - pub const GA_EN: u32 = 1 << 10; - pub const XT_EN: u32 = 1 << 22; - pub const NX_EN: u32 = 1 << 23; -} - -/// AMD-Vi Status Register bits. -pub mod amd_status { - pub const IOMMU_RUNNING: u32 = 1 << 0; - pub const EVENT_OVERFLOW: u32 = 1 << 1; - pub const EVENT_LOG_INT: u32 = 1 << 2; - pub const COM_WAIT_INT: u32 = 1 << 3; - pub const PPR_OVERFLOW: u32 = 1 << 4; - pub const PPR_INT: u32 = 1 << 5; -} - -/// AMD-Vi Extended Feature Register bits. -pub mod amd_ext_feature { - pub const PREF_SUP: u64 = 1 << 0; - pub const PPR_SUP: u64 = 1 << 1; - pub const XT_SUP: u64 = 1 << 2; - pub const NX_SUP: u64 = 1 << 3; - pub const GT_SUP: u64 = 1 << 4; - pub const IA_SUP: u64 = 1 << 6; - pub const GA_SUP: u64 = 1 << 7; - pub const HE_SUP: u64 = 1 << 8; - pub const PC_SUP: u64 = 1 << 9; - pub const GI_SUP: u64 = 1 << 57; -} - -/// AMD-Vi Device Table Entry (256 bits = 32 bytes). -/// Index by BDF: (bus << 8) | (dev << 3) | func. -/// Table holds up to 65536 entries. -#[repr(C, packed)] -pub struct AmdDte { - pub data: [u64; 4], -} - -impl AmdDte { - /// Create a zeroed (invalid) DTE. - pub const fn zeroed() -> Self { - Self { data: [0; 4] } - } - - // data[0] accessors - - pub fn valid(&self) -> bool { - self.data[0] & (1 << 0) != 0 - } - - pub fn set_valid(&mut self, v: bool) { - if v { self.data[0] |= 1 << 0; } else { self.data[0] &= !(1 << 0); } - } - - pub fn translation_valid(&self) -> bool { - self.data[0] & (1 << 1) != 0 - } - - pub fn set_translation_valid(&mut self, v: bool) { - if v { self.data[0] |= 1 << 1; } else { self.data[0] &= !(1 << 1); } - } - - /// Translation mode (bits 9:11). 0=no translation, 4=4-level page table. - pub fn mode(&self) -> u64 { - (self.data[0] >> 9) & 0x7 - } - - pub fn set_mode(&mut self, m: u64) { - self.data[0] = (self.data[0] & !(0x7 << 9)) | ((m & 0x7) << 9); - } - - /// Page Table Root Pointer (bits 12:51 of data[0]). - /// Address must be 4KiB-aligned. - pub fn page_table_root(&self) -> u64 { - (self.data[0] >> 12) & 0x000F_FFFF_FFFF_FFFF - } - - pub fn set_page_table_root(&mut self, addr: u64) { - self.data[0] = (self.data[0] & !(0x000F_FFFF_FFFF_FFFF << 12)) - | ((addr >> 12) << 12); - } - - /// Interrupt Remapping Enable (bit 61 of data[0]). - pub fn interrupt_remap(&self) -> bool { - self.data[0] & (1 << 61) != 0 - } - - pub fn set_interrupt_remap(&mut self, v: bool) { - if v { self.data[0] |= 1 << 61; } else { self.data[0] &= !(1 << 61); } - } - - /// Interrupt Write permission (bit 62 of data[0]). - pub fn interrupt_write(&self) -> bool { - self.data[0] & (1 << 62) != 0 - } - - pub fn set_interrupt_write(&mut self, v: bool) { - if v { self.data[0] |= 1 << 62; } else { self.data[0] &= !(1 << 62); } - } - - // data[1] accessors - - /// Interrupt Remap Table Length (bits 0:3 of data[1]). - /// Number of IRTEs = 2^(len+1). - pub fn int_table_len(&self) -> u64 { - self.data[1] & 0xF - } - - pub fn set_int_table_len(&mut self, len: u64) { - self.data[1] = (self.data[1] & !0xF) | (len & 0xF); - } - - /// Interrupt Control (bits 4:5 of data[1]). - /// 00=abort, 01=pass-through, 10=remapped. - pub fn int_control(&self) -> u64 { - (self.data[1] >> 4) & 0x3 - } - - pub fn set_int_control(&mut self, ctl: u64) { - self.data[1] = (self.data[1] & !(0x3 << 4)) | ((ctl & 0x3) << 4); - } - - /// Interrupt Remap Table Pointer (bits 6:51 of data[1]). - /// Address must be 4KiB-aligned. - pub fn int_remap_table_ptr(&self) -> u64 { - (self.data[1] >> 6) & 0x000F_FFFF_FFFF_FFFF - } - - pub fn set_int_remap_table_ptr(&mut self, addr: u64) { - self.data[1] = (self.data[1] & !(0x000F_FFFF_FFFF_FFFF << 6)) - | ((addr >> 6) << 6); - } -} - -const _: () = assert!(core::mem::size_of::() == 32); - -/// AMD-Vi Interrupt Remapping Table Entry (128 bits = 16 bytes). -#[repr(C, packed)] -pub struct AmdIrte { - pub data: [u64; 2], -} - -impl AmdIrte { - pub const fn zeroed() -> Self { - Self { data: [0; 2] } - } - - /// Remap enable (bit 0 of data[0]). - pub fn remap_enabled(&self) -> bool { - self.data[0] & (1 << 0) != 0 - } - - pub fn set_remap_enabled(&mut self, v: bool) { - if v { self.data[0] |= 1 << 0; } else { self.data[0] &= !(1 << 0); } - } - - /// Suppress IO Page Fault (bit 1). - pub fn suppress_io_pf(&self) -> bool { - self.data[0] & (1 << 1) != 0 - } - - pub fn set_suppress_io_pf(&mut self, v: bool) { - if v { self.data[0] |= 1 << 1; } else { self.data[0] &= !(1 << 1); } - } - - /// Interrupt type (bits 2:4 of data[0]). - pub fn int_type(&self) -> u64 { - (self.data[0] >> 2) & 0x7 - } - - pub fn set_int_type(&mut self, t: u64) { - self.data[0] = (self.data[0] & !(0x7 << 2)) | ((t & 0x7) << 2); - } - - /// Destination mode (bit 2 of data[0], when using xAPIC logical). - /// 0=physical APIC ID, 1=logical. - pub fn dst_mode(&self) -> bool { - self.data[0] & (1 << 2) != 0 - } - - /// Destination APIC ID (bits 16:31 of data[0], low 16 bits). - /// For x2APIC, high 32 bits in data[1] bits 0:31. - pub fn destination(&self) -> u32 { - ((self.data[0] >> 16) & 0xFFFF) as u32 | ((self.data[1] & 0xFFFF_FFFF) as u32) << 16 - } - - pub fn set_destination(&mut self, apic_id: u32) { - self.data[0] = (self.data[0] & !(0xFFFF << 16)) | (((apic_id & 0xFFFF) as u64) << 16); - self.data[1] = (self.data[1] & !0xFFFF_FFFF) | ((apic_id >> 16) as u64); - } - - /// Vector (bits 32:39 of data[0], but stored in low byte of upper word). - pub fn vector(&self) -> u8 { - ((self.data[0] >> 32) & 0xFF) as u8 - } - - pub fn set_vector(&mut self, v: u8) { - self.data[0] = (self.data[0] & !(0xFF_u64 << 32)) | ((v as u64) << 32); - } -} - -const _: () = assert!(core::mem::size_of::() == 16); - -/// AMD-Vi Command Buffer Entry (128 bits = 16 bytes = 4 × u32). -#[repr(C, packed)] -pub struct AmdCmdEntry { - pub word: [u32; 4], -} - -impl AmdCmdEntry { - pub const fn zeroed() -> Self { - Self { word: [0; 4] } - } - - pub fn opcode(&self) -> u8 { - (self.word[0] & 0xF) as u8 - } - - pub fn set_opcode(&mut self, op: u8) { - self.word[0] = (self.word[0] & !0xF) | (op as u32 & 0xF); - } -} - -const _: () = assert!(core::mem::size_of::() == 16); - -/// AMD-Vi Command Opcodes. -pub mod amd_cmd_opcode { - pub const COMPLETION_WAIT: u8 = 0x01; - pub const INVALIDATE_DEVTAB_ENTRY: u8 = 0x02; - pub const INVALIDATE_IOMMU_PAGES: u8 = 0x03; - pub const INVALIDATE_INTERRUPT_TABLE: u8 = 0x04; - pub const INVALIDATE_IOMMU_ALL: u8 = 0x05; -} - -/// Build a COMPLETION_WAIT command. -pub fn amd_cmd_completion_wait(store_addr: u64, store_data: u32) -> AmdCmdEntry { - let mut cmd = AmdCmdEntry::zeroed(); - cmd.set_opcode(amd_cmd_opcode::COMPLETION_WAIT); - cmd.word[0] |= 1 << 4; // Store = 1 - cmd.word[1] = store_addr as u32; - cmd.word[2] = (store_addr >> 32) as u32; - cmd.word[3] = store_data; - cmd -} - -/// Build an INVALIDATE_DEVTAB_ENTRY command for a given BDF. -pub fn amd_cmd_invalidate_devtab(bdf: u16) -> AmdCmdEntry { - let mut cmd = AmdCmdEntry::zeroed(); - cmd.set_opcode(amd_cmd_opcode::INVALIDATE_DEVTAB_ENTRY); - cmd.word[1] = bdf as u32; - cmd -} - -/// Build an INVALIDATE_IOMMU_PAGES command. -/// If size=true, invalidates all pages for the domain (address ignored). -pub fn amd_cmd_invalidate_pages(domain_id: u16, address: u64, size: bool) -> AmdCmdEntry { - let mut cmd = AmdCmdEntry::zeroed(); - cmd.set_opcode(amd_cmd_opcode::INVALIDATE_IOMMU_PAGES); - if size { cmd.word[0] |= 1 << 4; } // S bit - cmd.word[1] = domain_id as u32; - cmd.word[2] = address as u32; - cmd.word[3] = (address >> 32) as u32; - cmd -} - -/// Build an INVALIDATE_INTERRUPT_TABLE command. -pub fn amd_cmd_invalidate_int_table(bdf: u16) -> AmdCmdEntry { - let mut cmd = AmdCmdEntry::zeroed(); - cmd.set_opcode(amd_cmd_opcode::INVALIDATE_INTERRUPT_TABLE); - cmd.word[1] = bdf as u32; - cmd -} - -/// Build an INVALIDATE_IOMMU_ALL command. -pub fn amd_cmd_invalidate_all() -> AmdCmdEntry { - let mut cmd = AmdCmdEntry::zeroed(); - cmd.set_opcode(amd_cmd_opcode::INVALIDATE_IOMMU_ALL); - cmd -} - -/// AMD-Vi Event Log Entry (128 bits = 16 bytes = 4 × u32). -#[repr(C, packed)] -pub struct AmdEvtEntry { - pub word: [u32; 4], -} - -impl AmdEvtEntry { - pub const fn zeroed() -> Self { - Self { word: [0; 4] } - } - - /// Event code (bits 0:15 of word[0]). - pub fn event_code(&self) -> u16 { - (self.word[0] & 0xFFFF) as u16 - } - - /// Device ID / BDF (bits 0:15 of word[1]). - pub fn device_id(&self) -> u16 { - (self.word[1] & 0xFFFF) as u16 - } - - /// Fault address (word[2] | word[3] << 32). - pub fn fault_address(&self) -> u64 { - self.word[2] as u64 | ((self.word[3] as u64) << 32) - } - - /// Flags from word[0] bits 16:22 (for IO_PAGE_FAULT). - pub fn fault_flags(&self) -> u16 { - ((self.word[0] >> 16) & 0x7F) as u16 - } - - /// Read/write direction from fault flags bit 4 (RW). - pub fn is_write(&self) -> bool { - self.word[0] & (1 << 20) != 0 - } - - /// Permission error from fault flags bit 3 (PE). - pub fn is_permission_error(&self) -> bool { - self.word[0] & (1 << 19) != 0 - } -} - -const _: () = assert!(core::mem::size_of::() == 16); - -/// AMD-Vi Event Codes. -pub mod amd_evt_code { - pub const ILLEGAL_DEV_TABLE_ENTRY: u16 = 0x01; - pub const IO_PAGE_FAULT: u16 = 0x02; - pub const DEV_TABLE_HW_ERROR: u16 = 0x03; - pub const PAGE_TABLE_HW_ERROR: u16 = 0x04; - pub const ILLEGAL_COMMAND: u16 = 0x05; - pub const COMMAND_HW_ERROR: u16 = 0x06; - pub const IOTLB_INV_TIMEOUT: u16 = 0x07; - pub const INVALID_DEV_REQUEST: u16 = 0x08; -} - -/// AMD-Vi Page Table Entry (64 bits). -#[repr(C, packed)] -pub struct AmdPte(pub u64); - -impl AmdPte { - /// Present bit (bit 0). - pub fn present(&self) -> bool { - self.0 & (1 << 0) != 0 - } - - pub fn set_present(&mut self, v: bool) { - if v { self.0 |= 1 << 0; } else { self.0 &= !(1 << 0); } - } - - /// Next level (bits 9:11). 0 = leaf PTE, 1-5 = pointer to next table. - pub fn next_level(&self) -> u64 { - (self.0 >> 9) & 0x7 - } - - pub fn set_next_level(&mut self, level: u64) { - self.0 = (self.0 & !(0x7 << 9)) | ((level & 0x7) << 9); - } - - /// Output address (bits 12:51). Physical frame or next-table address. - pub fn output_addr(&self) -> u64 { - self.0 & (0x000F_FFFF_FFFF_FFFF << 12) - } - - pub fn set_output_addr(&mut self, addr: u64) { - self.0 = (self.0 & !(0x000F_FFFF_FFFF_FFFF << 12)) | (addr & (0x000F_FFFF_FFFF_FFFF << 12)); - } - - /// No-execute (bit 63). Only valid when NXSup=1. - pub fn no_execute(&self) -> bool { - self.0 & (1 << 63) != 0 - } - - pub fn set_no_execute(&mut self, v: bool) { - if v { self.0 |= 1 << 63; } else { self.0 &= !(1 << 63); } - } -} - -/// Build a leaf PTE that maps addr with Read+Write permissions. -pub fn amd_pte_leaf(addr: u64) -> AmdPte { - let mut pte = AmdPte(0); - pte.set_present(true); - pte.set_next_level(0); // leaf - pte.set_output_addr(addr); - pte.0 |= (1 << 2) | (1 << 3); // IW + IR (write + read permission) - pte -} - -/// Build a non-leaf PTE that points to the next-level table at addr. -pub fn amd_pte_pointer(addr: u64, level: u64) -> AmdPte { - let mut pte = AmdPte(0); - pte.set_present(true); - pte.set_next_level(level); - pte.set_output_addr(addr); - pte -} -``` - -### 3.2 Intel VT-d Structs - -```rust -/// Intel VT-d IOMMU MMIO register block. -/// Base address from ACPI DMAR DRHD entry. -#[repr(C)] -pub struct IntelVtdMmio { - pub ver_reg: u32, // 0x00 Version - _pad0: u32, // 0x04 - pub cap_reg: u64, // 0x08 Capability - pub ecap_reg: u64, // 0x10 Extended Capability - pub gcmd_reg: u32, // 0x18 Global Command (write-only) - pub gsts_reg: u32, // 0x1C Global Status (read-only) - pub rtaddr_reg: u64, // 0x20 Root Table Address - pub ccmd_reg: u64, // 0x28 Context Command - _pad1: u64, // 0x30 - pub fsts_reg: u32, // 0x34 Fault Status - pub fectl_reg: u32, // 0x38 Fault Event Control - pub fedata_reg: u32, // 0x3C Fault Event Data - pub feaddr_reg: u32, // 0x40 Fault Event Address - pub feuaddr_reg: u32, // 0x44 Fault Event Upper Address - _pad2: u32, // 0x48 - pub aflog_reg: u64, // 0x4C Advanced Fault Log (note: spec says 0x48 for 64-bit) - _pad3: u32, // padding - pub pmen_reg: u32, // 0x64 Protected Memory Enable (spec: 0x64) - pub plmbase_reg: u32, // 0x68 Protected Low Memory Base - pub plmlimit_reg: u32, // 0x6C Protected Low Memory Limit - _pad4: u32, - pub phmbase_reg: u64, // 0x70 Protected High Memory Base - pub phmlimit_reg: u64, // 0x78 Protected High Memory Limit - pub iqh_reg: u64, // 0x80 Invalidation Queue Head - pub iqt_reg: u64, // 0x88 Invalidation Queue Tail - pub iqa_reg: u64, // 0x90 Invalidation Queue Address - pub ics_reg: u32, // 0x98 Invalidation Completion Status - _pad5: u32, - pub iectl_reg: u32, // 0xA0 Invalidation Event Control - pub iedata_reg: u32, // 0xA4 Invalidation Event Data - pub ieaddr_reg: u32, // 0xA8 Invalidation Event Address - pub ieuaddr_reg: u32, // 0xAC Invalidation Event Upper Address - _pad6: [u32; 2], // 0xB0..0xB7 (IRTA is separate below) - pub irta_reg: u64, // 0xB8 Interrupt Remapping Table Address -} -// Note: The VT-d register layout has vendor-specific gaps. For production code, -// use volatile read/write helpers with explicit offsets rather than relying -// purely on struct field offsets. The struct above serves as a reference. -// The IRTA_REG offset is 0xB8 per VT-d spec 5.0 (some earlier specs say 0xB0). - -/// Intel VT-d CAP_REG bits. -pub mod vtd_cap { - pub const ND_MASK: u64 = 0x7; - pub const ZLR: u64 = 1 << 8; - pub const AFL: u64 = 1 << 9; - pub const RWBF: u64 = 1 << 10; - pub const PLMR: u64 = 1 << 11; - pub const PHMR: u64 = 1 << 13; - pub const CM: u64 = 1 << 14; - pub const SAGAW: u64 = 0xFF << 16; - pub const SAGAW_3LVL: u64 = 1 << 18; // 3-level page tables - pub const SAGAW_4LVL: u64 = 1 << 19; // 4-level page tables - pub const SAGAW_5LVL: u64 = 1 << 20; // 5-level page tables - pub const SAGAW_6LVL: u64 = 1 << 21; // 6-level page tables - pub const MGAW_SHIFT: u64 = 24; - pub const MGAW_MASK: u64 = 0x3F << 24; -} - -/// Intel VT-d ECAP_REG bits. -pub mod vtd_ecap { - pub const C: u64 = 1 << 0; // Page Request - pub const QI: u64 = 1 << 1; // Queued Invalidation - pub const DT: u64 = 1 << 2; // Device TLB - pub const IR: u64 = 1 << 3; // Interrupt Remapping - pub const EIM: u64 = 1 << 4; // Extended Interrupt Mode (x2APIC) - pub const PT: u64 = 1 << 8; // Pass Through - pub const SC: u64 = 1 << 18; // Snoop Control - pub const IRO_SHIFT: u64 = 25; - pub const IRO_MASK: u64 = 0x3FF << 25; -} - -/// Intel VT-d GCMD_REG bits (write-only). -pub mod vtd_gcmd { - pub const TE: u32 = 1 << 31; // Translation Enable - pub const SRTP: u32 = 1 << 30; // Set Root Table Pointer - pub const SFL: u32 = 1 << 29; // Set Fault Log - pub const EAFL: u32 = 1 << 28; // Enable Advanced Fault Log - pub const WBF: u32 = 1 << 27; // Write Buffer Flush - pub const QIE: u32 = 1 << 26; // Queued Invalidation Enable - pub const SIRTP: u32 = 1 << 25; // Set Interrupt Remap Table Pointer - pub const CFI: u32 = 1 << 24; // Compatibility Format Interrupt - pub const IR: u32 = 1 << 23; // Interrupt Remap Enable -} - -/// Intel VT-d GSTS_REG bits (read-only). -pub mod vtd_gsts { - pub const TES: u32 = 1 << 31; // Translation Enable Status - pub const RTPS: u32 = 1 << 30; // Root Table Pointer Status - pub const FLS: u32 = 1 << 29; // Fault Log Status - pub const AFLS: u32 = 1 << 28; // Advanced Fault Log Status - pub const WBFS: u32 = 1 << 27; // Write Buffer Flush Status - pub const QIES: u32 = 1 << 26; // Queued Invalidation Enable Status - pub const IRTPS: u32 = 1 << 25; // Interrupt Remap Table Pointer Status - pub const CFIS: u32 = 1 << 24; // Compatibility Format Interrupt Status - pub const IRES: u32 = 1 << 23; // Interrupt Remap Enable Status -} - -/// Intel VT-d Root Table Entry (128 bits = 16 bytes). -/// 256 entries (one per PCI bus). 4KiB-aligned. -#[repr(C, packed)] -pub struct VtdRootEntry { - pub data: [u64; 2], -} - -impl VtdRootEntry { - pub const fn zeroed() -> Self { - Self { data: [0; 2] } - } - - /// Present (bit 0 of data[0]). - pub fn present(&self) -> bool { - self.data[0] & (1 << 0) != 0 - } - - pub fn set_present(&mut self, v: bool) { - if v { self.data[0] |= 1 << 0; } else { self.data[0] &= !(1 << 0); } - } - - /// Context Table Pointer (bits 12:63 of data[0]). - pub fn context_table_ptr(&self) -> u64 { - self.data[0] & !0xFFF - } - - pub fn set_context_table_ptr(&mut self, addr: u64) { - self.data[0] = (self.data[0] & 0xFFF) | (addr & !0xFFF); - } -} - -const _: () = assert!(core::mem::size_of::() == 16); - -/// Intel VT-d Context Entry (128 bits = 16 bytes). -/// 256 entries per bus (one per device:function). 4KiB-aligned table. -#[repr(C, packed)] -pub struct VtdContextEntry { - pub data: [u64; 2], -} - -impl VtdContextEntry { - pub const fn zeroed() -> Self { - Self { data: [0; 2] } - } - - /// Present (bit 0 of data[0]). - pub fn present(&self) -> bool { - self.data[0] & (1 << 0) != 0 - } - - pub fn set_present(&mut self, v: bool) { - if v { self.data[0] |= 1 << 0; } else { self.data[0] &= !(1 << 0); } - } - - /// Fault Processing Disable (bit 1 of data[0]). - pub fn fault_processing_disable(&self) -> bool { - self.data[0] & (1 << 1) != 0 - } - - pub fn set_fault_processing_disable(&mut self, v: bool) { - if v { self.data[0] |= 1 << 1; } else { self.data[0] &= !(1 << 1); } - } - - /// Translation Type (bits 2:3 of data[0]). - /// 00=legacy, 01=PASID, 10=pass-through, 11=reserved. - pub fn translation_type(&self) -> u64 { - (self.data[0] >> 2) & 0x3 - } - - pub fn set_translation_type(&mut self, tt: u64) { - self.data[0] = (self.data[0] & !(0x3 << 2)) | ((tt & 0x3) << 2); - } - - /// Second Level Page Table Pointer (bits 12:63 of data[0]). - pub fn slpt_ptr(&self) -> u64 { - self.data[0] & !0xFFF - } - - pub fn set_slpt_ptr(&mut self, addr: u64) { - self.data[0] = (self.data[0] & 0xFFF) | (addr & !0xFFF); - } - - /// Domain Identifier (bits 0:15 of data[1]). - pub fn domain_id(&self) -> u16 { - (self.data[1] & 0xFFFF) as u16 - } - - pub fn set_domain_id(&mut self, id: u16) { - self.data[1] = (self.data[1] & !0xFFFF) | (id as u64); - } -} - -const _: () = assert!(core::mem::size_of::() == 16); - -/// Intel VT-d Translation Type constants. -pub mod vtd_tt { - pub const LEGACY: u64 = 0b00; - pub const PASID: u64 = 0b01; - pub const PASS_THROUGH: u64 = 0b10; -} - -/// Intel VT-d Page Table Entry (64 bits). -#[repr(C, packed)] -pub struct VtdPte(pub u64); - -impl VtdPte { - /// Read permission (bit 0). - pub fn read(&self) -> bool { - self.0 & (1 << 0) != 0 - } - - pub fn set_read(&mut self, v: bool) { - if v { self.0 |= 1 << 0; } else { self.0 &= !(1 << 0); } - } - - /// Write permission (bit 1). - pub fn write(&self) -> bool { - self.0 & (1 << 1) != 0 - } - - pub fn set_write(&mut self, v: bool) { - if v { self.0 |= 1 << 1; } else { self.0 &= !(1 << 1); } - } - - /// Page frame or next-table address (bits 12:63). - pub fn addr(&self) -> u64 { - self.0 & !0xFFF - } - - pub fn set_addr(&mut self, a: u64) { - self.0 = (self.0 & 0xFFF) | (a & !0xFFF); - } -} - -/// Build a leaf PTE for Intel VT-d with read+write. -pub fn vtd_pte_leaf(addr: u64) -> VtdPte { - let mut pte = VtdPte(0); - pte.set_read(true); - pte.set_write(true); - pte.set_addr(addr); - pte -} - -/// Build a non-leaf PTE for Intel VT-d pointing to next-level table. -pub fn vtd_pte_pointer(addr: u64) -> VtdPte { - let mut pte = VtdPte(0); - pte.set_read(true); - pte.set_write(true); - pte.set_addr(addr); - pte -} -``` - -### 3.3 ACPI Table Structs - -```rust -/// Common ACPI table header (24 bytes). -#[repr(C, packed)] -pub struct AcpiTableHeader { - pub signature: [u8; 4], - pub length: u32, - pub revision: u8, - pub checksum: u8, - pub oem_id: [u8; 6], - pub oem_table_id: [u8; 8], - pub oem_revision: u32, - pub creator_id: [u8; 4], - pub creator_revision: u32, -} - -const _: () = assert!(core::mem::size_of::() == 36); - -/// IVRS ACPI Table Header. -#[repr(C, packed)] -pub struct IvrsTable { - pub header: AcpiTableHeader, // 36 bytes - pub iv_info: u32, // IOMMU Virtualization Info - // Followed by variable-length IVHD/IVMD entries. -} - -/// IVHD Entry (I/O Virtualization Hardware Definition). -#[repr(C, packed)] -pub struct IvhdEntry { - pub entry_type: u8, // 0x10 or 0x11 - pub flags: u8, // Feature flags - pub length: u16, // Total length including device entries - pub device_id: u16, // BDF of IOMMU PCI device - pub capability_offset: u16, // PCI capability offset - pub iommu_base_address: u64, // MMIO base address - pub pci_segment_group: u16, // PCI segment group - pub iommu_info: u16, // IOMMU info (MSI number, unit ID) - pub iommu_efr: u32, // Extended features (type 11 only) - // Followed by variable-length device entries. -} - -/// IVMD Entry (I/O Virtualization Memory Definition). -#[repr(C, packed)] -pub struct IvmdEntry { - pub entry_type: u8, // 0x20 or 0x21 - pub flags: u8, // Memory block flags - pub length: u16, // Total length - pub device_id: u16, // Start DeviceId (BDF) or 0x0000 for all - pub aux_data: u16, // Auxiliary data - pub start_address: u64, // Physical start address - pub memory_length: u64, // Length in bytes -} - -/// IVHD Device Entry (4 bytes minimum). -#[repr(C, packed)] -pub struct IvhdDeviceEntry { - pub dev_type: u8, // Device entry type (0x00..0x44) - pub data: u8, // LSA flags - pub device_id: u16, // BDF for SEL/SOR/EOR -} - -/// DMAR ACPI Table Header. -#[repr(C, packed)] -pub struct DmarTable { - pub header: AcpiTableHeader, // 36 bytes - pub host_address_width: u8, // DMA physical address width - pub flags: u8, // [0]=INTR_REMAP, [1]=X2APIC_OPT_OUT - pub reserved: [u8; 10], // Reserved - // Followed by variable-length DRHD/RMRR entries. -} - -const _: () = assert!(core::mem::size_of::() == 48); - -/// DRHD Entry (DMA Remapping Hardware Unit Definition). -#[repr(C, packed)] -pub struct DrhdEntry { - pub entry_type: u16, // 0x0001 - pub length: u16, // Total length including device scope - pub flags: u8, // [0]=INCLUDE_PCI_ALL - pub reserved: u8, // Reserved - pub segment_number: u16, // PCI segment group - pub register_base_address: u64, // Physical MMIO base address - // Followed by variable-length device scope entries. -} - -/// DRHD Device Scope Entry. -#[repr(C, packed)] -pub struct DmarDeviceScope { - pub scope_type: u8, // 0x01=PCI EP, 0x02=PCI sub-hierarchy, 0x03=IOAPIC, 0x04=HPET - pub length: u8, // Total length including path entries - pub enumeration_id: u8, // Enumeration ID (IOAPIC ID, etc.) - pub start_bus_number: u8, // Starting PCI bus number - // Followed by path entries (each 2 bytes: device, function). -} - -/// RMRR Entry (Reserved Memory Region Reporting). -#[repr(C, packed)] -pub struct RmrrEntry { - pub entry_type: u16, // 0x0002 - pub length: u16, // Total length - pub reserved: u16, // Reserved - pub segment_number: u16, // PCI segment group - pub base_address: u64, // Physical start address - pub end_address: u64, // Physical end address (inclusive) - // Followed by variable-length device scope entries. -} - -/// DMAR Sub-Table Types. -pub mod dmar_type { - pub const DRHD: u16 = 0x0001; - pub const RMRR: u16 = 0x0002; - pub const ATSR: u16 = 0x0003; - pub const RHSA: u16 = 0x0004; - pub const ANDD: u16 = 0x0005; -} - -/// DMAR Device Scope Types. -pub mod dmar_scope_type { - pub const PCI_ENDPOINT: u8 = 0x01; - pub const PCI_SUBHIERARCHY: u8 = 0x02; - pub const IOAPIC: u8 = 0x03; - pub const MSI_HPET: u8 = 0x04; - pub const ACPI_NAMESPACE: u8 = 0x05; -} -``` - -### 3.4 Utility Types - -```rust -/// BDF (Bus:Device:Function) packed as u16. -/// Format: bus[15:8] | device[7:3] | function[2:0]. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct Bdf(pub u16); - -impl Bdf { - pub fn new(bus: u8, device: u8, function: u8) -> Self { - Self(((bus as u16) << 8) | ((device as u16 & 0x1F) << 3) | (function as u16 & 0x7)) - } - - pub fn bus(&self) -> u8 { - (self.0 >> 8) as u8 - } - - pub fn device(&self) -> u8 { - ((self.0 >> 3) & 0x1F) as u8 - } - - pub fn function(&self) -> u8 { - (self.0 & 0x7) as u8 - } - - /// Index into the AMD Device Table (same as raw BDF value). - pub fn dev_table_index(&self) -> usize { - self.0 as usize - } -} - -/// Domain ID. Used to group devices sharing a page table. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct DomainId(pub u16); - -/// Page table level constants. -pub mod pt_level { - /// AMD-Vi levels (Mode field in DTE). - pub const AMD_1_LEVEL: u64 = 1; - pub const AMD_2_LEVEL: u64 = 2; - pub const AMD_3_LEVEL: u64 = 3; - pub const AMD_4_LEVEL: u64 = 4; - pub const AMD_5_LEVEL: u64 = 5; - pub const AMD_6_LEVEL: u64 = 6; - - /// Intel VT-d levels (SAGAW field). - pub const VTd_3_LEVEL: u64 = 3; - pub const VTd_4_LEVEL: u64 = 4; - pub const VTd_5_LEVEL: u64 = 5; - pub const VTd_6_LEVEL: u64 = 6; -} -``` - -### 3.5 Size Constants - -```rust -/// AMD-Vi sizing constants. -pub mod amd_sizes { - /// Maximum Device Table entries. - pub const MAX_DEV_TABLE_ENTRIES: usize = 65536; - /// Device Table Entry size. - pub const DTE_SIZE: usize = 32; - /// Maximum Device Table size (65536 × 32 bytes). - pub const MAX_DEV_TABLE_SIZE: usize = MAX_DEV_TABLE_ENTRIES * DTE_SIZE; // 2 MiB - - /// Default Command Buffer entries. - pub const CMD_BUF_ENTRIES: usize = 512; - /// Command Buffer Entry size. - pub const CMD_ENTRY_SIZE: usize = 16; - /// Default Command Buffer size. - pub const CMD_BUF_SIZE: usize = CMD_BUF_ENTRIES * CMD_ENTRY_SIZE; // 8 KiB - - /// Default Event Log entries. - pub const EVT_LOG_ENTRIES: usize = 512; - /// Event Log Entry size. - pub const EVT_ENTRY_SIZE: usize = 16; - /// Default Event Log size. - pub const EVT_LOG_SIZE: usize = EVT_LOG_ENTRIES * EVT_ENTRY_SIZE; // 8 KiB - - /// IRTE size (128 bits). - pub const IRTE_SIZE: usize = 16; - /// Maximum Interrupt Remap Table entries (IntTabLen=11 → 2^12 = 4096). - pub const MAX_IRT_ENTRIES: usize = 4096; - /// Maximum Interrupt Remap Table size. - pub const MAX_IRT_SIZE: usize = MAX_IRT_ENTRIES * IRTE_SIZE; // 64 KiB - - /// Page table entry size (both AMD and Intel). - pub const PTE_SIZE: usize = 8; - /// Entries per page table page (4KiB / 8 bytes). - pub const PTES_PER_PAGE: usize = 512; -} - -/// Intel VT-d sizing constants. -pub mod vtd_sizes { - /// Root Table entries (one per PCI bus). - pub const ROOT_TABLE_ENTRIES: usize = 256; - /// Root/Context Entry size. - pub const ENTRY_SIZE: usize = 16; - /// Root Table size. - pub const ROOT_TABLE_SIZE: usize = ROOT_TABLE_ENTRIES * ENTRY_SIZE; // 4 KiB - - /// Context Table entries (one per device:function per bus). - pub const CTX_TABLE_ENTRIES: usize = 256; - /// Context Table size. - pub const CTX_TABLE_SIZE: usize = CTX_TABLE_ENTRIES * ENTRY_SIZE; // 4 KiB - - /// Page table entry size. - pub const PTE_SIZE: usize = 8; - /// Entries per page table page. - pub const PTES_PER_PAGE: usize = 512; -} - -/// PCI BDF address space: 256 buses × 32 devices × 8 functions = 65536. -pub const PCI_BDF_COUNT: usize = 256 * 32 * 8; -``` - ---- - -## Appendix: Linux Kernel Reference - -The Linux kernel IOMMU drivers are the primary reference implementation. Key files: - -| Path | Description | -|------|-------------| -| `drivers/iommu/amd/amd_iommu_types.h` | AMD-Vi type definitions, DTE/IRTE/PTE formats, register constants | -| `drivers/iommu/amd/amd_iommu.c` | AMD-Vi main driver: init, command buffer, device table management | -| `drivers/iommu/amd/init.c` | AMD-Vi initialization, IVRS parsing, early setup | -| `drivers/iommu/amd/irq.c` | AMD-Vi interrupt remapping | -| `drivers/iommu/intel/dmar.c` | Intel VT-d DMAR table parsing | -| `drivers/iommu/intel/iommu.c` | Intel VT-d main driver | -| `drivers/iommu/intel/irq_remapping.c` | Intel VT-d interrupt remapping | -| `include/linux/intel-iommu.h` | Intel VT-d register definitions, struct definitions | -| `drivers/iommu/io-pgtable.c` | Generic page table allocation | - -### Key Linux Constants for Cross-Reference - -```c -// AMD DTE bits (from amd_iommu_types.h) -#define DTE_FLAG_V (1ULL << 0) -#define DTE_FLAG_TV (1ULL << 1) -#define DTE_FLAG_IR (1ULL << 61) -#define DTE_FLAG_IW (1ULL << 62) -#define DTE_FLAG_SE (1ULL << 8) - -// AMD page table modes (DTE Mode field) -#define DTE_MODE_4LVL 4 // 4-level page tables (most common) - -// AMD command opcodes -#define CMD_COMPLETION_WAIT 0x01 -#define CMD_INVALIDATE_DEVTAB_ENTRY 0x02 -#define CMD_INVALIDATE_IOMMU_PAGES 0x03 -#define CMD_INVALIDATE_INTERRUPT_TABLE 0x04 - -// Intel DMAR flags -#define DMAR_INTR_REMAP 0x1 -#define DMAR_X2APIC_OPT_OUT 0x2 - -// Intel context entry TT (Translation Type) -#define CONTEXT_TT_MULTI_LEVEL 0 -#define CONTEXT_TT_DEV_IOTLB 1 -#define CONTEXT_TT_PASS_THROUGH 2 -``` - ---- - -*Document generated for Red Bear OS IOMMU implementation. Sources: AMD IOMMU Specification 48882 Rev 3.10, Intel VT-d Specification Rev 5.0, Linux kernel v6.x source.* diff --git a/local/docs/archived/SCHEDULER-REVIEW-FINAL.md b/local/docs/archived/SCHEDULER-REVIEW-FINAL.md deleted file mode 100644 index 7524f83d57..0000000000 --- a/local/docs/archived/SCHEDULER-REVIEW-FINAL.md +++ /dev/null @@ -1,50 +0,0 @@ -# P1-P8 Scheduler & Relibc Stability Review - -**Date:** 2026-04-30 -**Scope:** Comprehensive review of P1-P8 kernel scheduler and relibc changes for stability, robustness, and clean code - -## HIGH Severity — Fixed This Session - -| # | File | Issue | Fix | -|---|------|-------|-----| -| 1 | `pthread_mutex.rs:89` | `make_consistent` stored dead TID instead of 0 | Store 0 for "no owner" | -| 2 | `cond.rs:106` | `.unwrap()` suppressed EOWNERDEAD/ENOTRECOVERABLE | Changed to `.expect()` with message | - -## HIGH Severity — Documented as Known Limitations - -| # | File | Issue | Status | -|---|------|-------|--------| -| 3 | `switch.rs:396-437` | `steal_work` CPU iteration without atomicity | Structural limitation; documented with TODO | -| 4 | `proc.rs:481,613` | Lock ordering violation TODO in kfmap/ksetup | Pre-existing; requires deeper refactoring | -| 5 | `futex.rs:821-844` | PI futex CAS loop with `entry().or_insert()` race | Requires atomic entry creation pattern | - -## MEDIUM Severity — Documented for Follow-up - -| # | File | Issue | -|---|------|-------| -| 6 | `switch.rs:171` | TODO: Better memory orderings for CONTEXT_SWITCH_LOCK | -| 7 | `futex.rs:370-380` | Addrspace freed while robust list walk (UAF risk) | -| 8 | `pthread_mutex.rs:140` | `mutex_owner_id_is_live` O(n) scan | -| 9 | `pthread_mutex.rs:37-39` | SPIN_COUNT = 0 — no adaptive spinning | -| 10 | `barrier.rs` | No pthread_barrier_destroy — memory leak | -| 11 | `sched/mod.rs` | All sched_* functions return ENOSYS (honest stubs) | -| 12 | `pthread/mod.rs:553` | pthread_setname_np allocates format! on every call | - -## Build Verification - -- `cargo check` relibc: ✅ passes (1 pre-existing warning) -- `make r.kernel`: ✅ passes -- P8 patches in recipe: 5 of 8 wired (3 not yet wired — initial-placement, load-balance, work-stealing) - -## Honest Status Assessment - -| Phase | Status | Notes | -|-------|--------|-------| -| P0 | ✅ Complete | Barrier SMP, sigmask, pthread_kill | -| P1 | ✅ Complete | Robust mutexes, sched API (honest ENOSYS) | -| P2 | ✅ Complete | RT scheduling, SchedPolicy | -| P3 | 🚧 Partial | PerCpuSched + wiring done; stealing/balancing deferred | -| P4 | ✅ Complete | Futex sharding + REQUEUE + PI + robust | -| P5 | ✅ Complete | setpriority, affinity, thread naming, schedparam | -| P6 | 🚧 Partial | Cache-affine done; NUMA deferred | -| P7-P8 | ✅ Complete | Futex REQUEUE/PI/robust deliverable | diff --git a/local/docs/archived/VFAT-IMPLEMENTATION-PLAN.md b/local/docs/archived/VFAT-IMPLEMENTATION-PLAN.md deleted file mode 100644 index a2736a4687..0000000000 --- a/local/docs/archived/VFAT-IMPLEMENTATION-PLAN.md +++ /dev/null @@ -1,916 +0,0 @@ -# VFAT Implementation Plan — Red Bear OS - -**Date:** 2026-04-17 -**Status:** Implemented (Phase 1–3 complete, Phase 2b complete, Phase 4 deferred to runtime validation) -**Scope:** FAT12/16/32 with LFN (VFAT) — data volumes and ESP only (NOT root filesystem) -**Reference Implementation:** `local/recipes/core/ext4d/` (ext4 scheme daemon) - -## 1. Executive Summary - -Implement full VFAT support in Red Bear OS: a FAT scheme daemon (`fatd`) for mounting -FAT filesystems at runtime, management tools (mkfs, label, check), installer ESP -integration, and runtime auto-mount for USB storage and SD cards. - -FAT is **not** a root filesystem target — RedoxFS and ext4 remain the root options. -FAT serves for: EFI System Partitions, USB mass storage, SD cards, and data exchange -with other operating systems. - -**Recommended crate:** `fatfs` v0.3.6 (MIT, 356 stars, already in dependency tree via -installer). It provides FAT12/16/32, LFN, formatting, read/write, and `no_std` support. - -**Estimated effort:** 6–10 weeks for a complete, tested implementation. - -## 2. Current State - -### What Exists - -| Component | Location | Status | -|-----------|----------|--------| -| RedoxFS (default root FS) | `recipes/core/redoxfs/` | ✅ Stable | -| ext4 (alternate root FS) | `local/recipes/core/ext4d/` | ✅ Scheme daemon + mkfs + installer wired | -| `fatfs` crate in installer | `local/patches/installer/redox.patch` | ✅ Host-side EFI partition formatting only | -| `redox-fatfs` library | `recipes/libs/redox-fatfs/` | ❌ Commented out, dead code | -| Bootloader FAT reading | `recipes/core/bootloader/` | ❌ Reads RedoxFS only, no FAT | -| GRUB FAT reading | GRUB EFI image | ✅ GRUB `fat` module reads ESP | -| exfat-fuse | `recipes/wip/fuse/exfat-fuse/` | ❌ WIP, not compiled | - -### What Is Missing (the gaps this plan fills) - -| Gap | Priority | Description | -|-----|----------|-------------| -| VFAT scheme daemon | Critical | No `fatd` scheme for mounting FAT at runtime | -| FAT block device adapter | Critical | No adapter bridging Redox block I/O → `fatfs` traits | -| FAT management tools | High | No mkfs.fat, fatlabel, fsck.fat equivalents | -| Runtime auto-mount | High | No service to detect and mount FAT block devices | -| FAT filesystem checker | Medium | No verification or repair tool | - -### Key Architectural Decision - -The `ext4d` workspace at `local/recipes/core/ext4d/source/` is the exact template for -this implementation. It demonstrates: - -1. **Block device adapter** — `ext4-blockdev/` with FileDisk (Linux) + RedoxDisk (Redox) -2. **Scheme daemon** — `ext4d/` with full FSScheme via `redox_scheme::SchemeSync` -3. **Management tool** — `ext4-mkfs/` as a standalone binary -4. **Workspace structure** — Workspace Cargo.toml, resolver=3, edition=2024 -5. **Feature flags** — `default = ["redox"]`, redox = ["dep:libredox", ...] -6. **Recipe** — `template = "custom"` with `COOKBOOK_CARGO_PATH` - -## 3. Implementation Phases - -### Phase 1: FAT Scheme Daemon (`fatd`) — 3–4 weeks - -**Goal:** A working VFAT scheme daemon that can mount and serve FAT filesystems. - -#### 1.1 Workspace Setup - -Create `local/recipes/core/fatd/` workspace mirroring ext4d structure: - -``` -local/recipes/core/fatd/ -├── recipe.toml ← Custom build script -└── source/ - ├── Cargo.toml ← Workspace: fat-blockdev, fatd, fat-mkfs, fat-label, fat-check - ├── fat-blockdev/ - │ ├── Cargo.toml - │ └── src/ - │ ├── lib.rs ← Re-exports + FatError type - │ ├── file_disk.rs ← FileDisk: std::fs backed (Linux host) - │ └── redox_disk.rs ← RedoxDisk: libredox backed (Redox target) - ├── fatd/ - │ ├── Cargo.toml - │ └── src/ - │ ├── main.rs ← Daemon entry: fork, SIGTERM, dispatch - │ ├── mount.rs ← Scheme event loop (SchemeSync) - │ ├── scheme.rs ← FatScheme: full FSScheme impl - │ └── handle.rs ← FileHandle, DirHandle, Handle types - ├── fat-mkfs/ - │ ├── Cargo.toml - │ └── src/ - │ └── main.rs ← Create FAT filesystems - ├── fat-label/ - │ ├── Cargo.toml - │ └── src/ - │ └── main.rs ← Read/write volume labels - └── fat-check/ - ├── Cargo.toml - └── src/ - └── main.rs ← Verify + repair FAT filesystems -``` - -**Recipe** (`recipe.toml`): -```toml -[source] -path = "source" - -[build] -template = "custom" -script = """ -COOKBOOK_CARGO_PATH=fatd cookbook_cargo -COOKBOOK_CARGO_PATH=fat-mkfs cookbook_cargo -COOKBOOK_CARGO_PATH=fat-label cookbook_cargo -COOKBOOK_CARGO_PATH=fat-check cookbook_cargo -""" -``` - -**Workspace `Cargo.toml`**: -```toml -[workspace] -members = ["fat-blockdev", "fatd", "fat-mkfs", "fat-label", "fat-check"] -resolver = "3" - -[workspace.package] -version = "0.1.0" -edition = "2024" -license = "MIT" - -[workspace.dependencies] -fatfs = "0.3.6" -fscommon = "0.1.1" -redox_syscall = "0.7.3" -redox-scheme = "0.11.0" -libredox = "0.1.13" -redox-path = "0.3.0" -log = "0.4" -env_logger = "0.11" -libc = "0.2" -``` - -**Symlink**: `recipes/core/fatd → ../../local/recipes/core/fatd` - -#### 1.2 Block Device Adapter (`fat-blockdev`) - -The `fatfs` crate uses `Read + Seek` and `Read + Write + Seek` traits for block device -access. We need adapters that wrap Redox's block I/O into these traits. - -**`file_disk.rs`** (Linux host): -```rust -// Wraps std::fs::File to implement Read+Write+Seek -// Identical pattern to ext4-blockdev/src/file_disk.rs -// Uses fscommon::BufStream for caching -pub struct FileDisk { ... } -impl Read for FileDisk { ... } -impl Write for FileDisk { ... } -impl Seek for FileDisk { ... } -``` - -**`redox_disk.rs`** (Redox target, feature-gated): -```rust -// Wraps libredox fd to implement Read+Write+Seek -// Uses syscall::call::open/read/write/lseek/fstat -// Pattern from ext4-blockdev/src/redox_disk.rs -pub struct RedoxDisk { - fd: usize, - size: u64, // from fstat -} -impl Read for RedoxDisk { ... } -impl Write for RedoxDisk { ... } -impl Seek for RedoxDisk { ... } -``` - -**Critical detail**: Wrap the disk in `fscommon::BufStream` for performance — -`fatfs` does no internal caching and performs poorly without buffering. - -```rust -let disk = RedoxDisk::open(disk_path)?; -let buf_disk = fscommon::BufStream::new(disk); -let fs = fatfs::FileSystem::new(buf_disk, fatfs::FsOptions::new())?; -``` - -#### 1.3 VFAT Scheme Daemon (`fatd`) - -**Architecture**: Single `fatfs::FileSystem` instance per daemon process. The `fatfs` -crate is NOT safe for concurrent access from multiple `FileSystem` objects on the same -device. One daemon = one mounted filesystem = one `FileSystem` instance. - -**`handle.rs`** — Handle types: - -```rust -pub enum Handle { - File(FileHandle), - Directory(DirectoryHandle), - SchemeRoot, -} - -pub struct FileHandle { - path: String, - offset: u64, - flags: usize, -} - -pub struct DirectoryHandle { - path: String, - entries: Vec, // cached readdir results - offset: usize, - flags: usize, -} -``` - -**Key difference from ext4d**: `fatfs` does not have persistent file handles like -rsext4's `OpenFile`. Files must be re-opened on each read/write operation. The -`FileHandle` stores the path and offset, and the scheme re-opens the file on each -`read`/`write` call. - -**`scheme.rs`** — FatScheme implementing `SchemeSync`: - -Required methods and their `fatfs` mapping: - -| SchemeSync method | fatfs operation | -|-------------------|-----------------| -| `scheme_root()` | Return SchemeRoot handle | -| `openat()` | `fs.root_dir().open_dir(path)` or `open_file(path)` | -| `read()` | Re-open file, seek to offset, `file.read(buf)` | -| `write()` | Re-open file, seek to offset, `file.write(buf)` | -| `fsize()` | Re-open file, `file.len()` | -| `fstat()` | `dir.iter().find()` for entry, construct `Stat` | -| `fstatvfs()` | `fs.stats()` for block/free counts | -| `getdents()` | `dir.iter()` collect entries, serve from handle cache | -| `ftruncate()` | Re-open file, `file.truncate()` | -| `fsync()` | `file.flush()` | -| `unlinkat()` | `dir.remove(name)` or `dir.remove_dir(name)` | -| `fcntl()` | Return handle flags | -| `fpath()` | Return mounted_path + handle path | -| `on_close()` | Remove from handle map | - -**Permission mapping**: FAT has limited permissions (read-only, hidden, system, -archive). Map to Unix permissions: -- Read-only attribute → `mode & !0o222` -- Otherwise → `0o644` for files, `0o755` for directories -- Owner/group always 0 (FAT has no ownership concept) -- Timestamps from FAT directory entry (2-second precision, date range 1980–2107) - -**Error mapping** (fatfs error → syscall error): -```rust -fn fat_error(err: fatfs::Error) -> syscall::error::Error { - match err { - fatfs::Error::NotFound => Error::new(ENOENT), - fatfs::Error::AlreadyExists => Error::new(EEXIST), - fatfs::Error::InvalidInput => Error::new(EINVAL), - fatfs::Error::IsDirectory => Error::new(EISDIR), - fatfs::Error::NotDirectory => Error::new(ENOTDIR), - fatfs::Error::DirectoryNotEmpty => Error::new(ENOTEMPTY), - fatfs::Error::WriteZero => Error::new(ENOSPC), - fatfs::Error::UnexpectedEof => Error::new(EIO), - _ => Error::new(EIO), - } -} -``` - -**`main.rs`** — Daemon lifecycle: -- Parse args: `fatd [--no-daemon] ` -- Fork (optional daemonization) -- Install SIGTERM handler for clean unmount -- Open block device → create BufStream → `fatfs::FileSystem::new()` -- Call `mount::mount()` to register scheme and enter event loop -- On SIGTERM: `fs.unmount()` (or just drop — fatfs flushes on drop) - -**`mount.rs`** — Event loop (identical pattern to ext4d mount.rs): -- `Socket::create()` -- `register_sync_scheme(&socket, mountpoint, &mut scheme)` -- Loop: `socket.next_request(SignalBehavior::Restart)` → dispatch to scheme -- On exit: `scheme.cleanup()` for clean unmount - -#### 1.4 LFN Support - -The `fatfs` crate handles LFN transparently when the `lfn` feature is enabled: - -```toml -fatfs = { version = "0.3.6", default-features = false, features = ["lfn", "alloc"] } -``` - -This provides: -- Long filename read via `DirEntry::file_name()` (returns full long name) -- Long filename write on `Dir::create_file()` and `Dir::create_dir()` -- Automatic 8.3 short name generation (e.g., "MYLONG~1.TXT") -- LFN checksum computation (handled internally) - -**No special LFN code needed in the scheme daemon** — `fatfs` abstracts it away. -The scheme daemon just passes filenames through. - -#### 1.5 FAT12/16/32 Auto-Detection - -`fatfs::FileSystem::new()` automatically detects FAT12, FAT16, or FAT32 based on -the BPB (BIOS Parameter Block) in the first sector. No explicit type selection needed. - -`fatfs::format_volume()` with `FormatVolumeOptions::new()` auto-selects FAT type -based on volume size: -- < 16 MB → FAT12 (or FAT16) -- 16 MB – 32 MB → FAT16 -- > 32 MB → FAT32 - -Explicit type selection: `FormatVolumeOptions::new().fat_type(FatType::Fat32)`. - -### Phase 2: Management Tools — 2–3 weeks - -#### 2.1 `fat-mkfs` — Create FAT Filesystems - -**Binary**: `fat-mkfs [options]` - -Options: -- `-F <12|16|32>` — Force FAT type (default: auto) -- `-n