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.
This commit is contained in:
2026-07-09 11:19:53 +03:00
parent 544e0f4870
commit ecf1f19d55
13 changed files with 0 additions and 5741 deletions
@@ -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::<sem_t>()` (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
@@ -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 P0P6 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:** 24 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 14
└── Deliverable: ISO boots with live mode enabled
```
### Parallel work opportunities
- **Phase 5** (live ISO) can proceed in parallel with Phases 14
- 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 15 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.
@@ -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.
@@ -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 <pkg>` 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 <pkg>` (fetch AUR) → `cub -B <pkg>` (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
@@ -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)** |
@@ -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<PathBuf> {
// Returns target/<triplet>/stage.pkgar paths
// Bug: returns target/ path when recipe is in wip/wayland/
// Fix: should return repo/<triplet>/<pkg>.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)** |
@@ -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.*
@@ -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
@@ -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 101214
**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 8899 in authd main.rs).
**Hash verification (lines 183193):**
```rust
fn verify_shadow_password(password: &str, shadow_hash: &str) -> Result<bool, VerifyError> {
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 237270):**
- 5 failures in 60s → 30-second lockout
- Rejects locked accounts (`!` or `*` prefix)
- UID < 1000 rejected (except UID 0)
**Approval system (lines 216287):**
- 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 352385
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 <vt>`
- `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*
File diff suppressed because it is too large Load Diff
@@ -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 |
@@ -1,916 +0,0 @@
# VFAT Implementation Plan — Red Bear OS
**Date:** 2026-04-17
**Status:** Implemented (Phase 13 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:** 610 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`) — 34 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<DirEntryInfo>, // 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 19802107)
**Error mapping** (fatfs error → syscall error):
```rust
fn fat_error(err: fatfs::Error<impl std::fmt::Debug>) -> 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] <disk_path> <mountpoint>`
- 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 — 23 weeks
#### 2.1 `fat-mkfs` — Create FAT Filesystems
**Binary**: `fat-mkfs <device> [options]`
Options:
- `-F <12|16|32>` — Force FAT type (default: auto)
- `-n <label>` — Volume label (max 11 chars)
- `-s <sectors_per_cluster>` — Cluster size
- `-r <reserved_sectors>` — Reserved sector count
- `-f <num_fats>` — Number of FATs (default: 2)
Implementation:
```rust
let disk = FileDisk::open(device)?;
let options = fatfs::FormatVolumeOptions::new()
.fat_type(fat_type)
.volume_label(label);
fatfs::format_volume(&mut disk, options)?;
```
Also: `fat-mkfs` should be usable on the build host for creating test images
and EFI System Partitions during development.
#### 2.2 `fat-label` — Read/Write Volume Labels
**Binary**: `fat-label <device> [new_label]`
- Without `new_label`: print current volume label
- With `-s "LABEL"`: set volume label (max 11 chars, uppercase)
- With `-s ""`: clear volume label
**Current status**: Read mode ✅ complete and tested. Write mode in progress
(direct BPB modification since fatfs v0.3 lacks `set_volume_label()`).
Implementation for write:
```rust
// Read: fs.volume_label() returns String (works)
// Write: direct BPB modification at offset 43 (FAT12/16) or 71 (FAT32)
// FAT type detection: root_entry_count == 0 && fat_size_32 != 0 → FAT32
// Label padded to 11 bytes with 0x20, uppercased
```
#### 2.3 `fat-check` — FAT Filesystem Checker
**Phase 2a: Verifier (read-only)** — ✅ Complete
Checks performed (no modifications):
1. **BPB validation** — sector size, cluster size, FAT size consistency ✅
2. **Directory structure** — valid entries, tree walking ✅
3. **Cluster stats** — total/free/used clusters via fatfs ✅
4. **Boot sector signature** — 0x55 0xAA check ✅
5. **FAT type detection** — FAT12/16/32 classification ✅
Output: report of all issues found, severity (info/warning/error).
Tested against clean and corrupt images.
**Phase 2b: Safe Repairs** — ✅ Complete
Safe repairs (non-destructive, `--repair` flag):
1. **Dirty flag handling** — clear dirty bit on FAT12/16/32 cluster 1 entries ✅
2. **FSInfo repair** — recount free clusters, update FSInfo sector ✅
3. **Lost cluster recovery** — reclaim lost clusters (mark free in FAT) ✅
4. **Orphaned LFN cleanup** — remove LFN entries without matching SFN ✅
Exit codes: 0 = clean, 1 = errors remain, 2 = repairs were made.
**Out of scope for initial version:**
- Cross-linked file repair
- Directory entry reconstruction
- Deep FAT table repair
- File data recovery
### Phase 3: Installer & Build Integration — 1 week
#### 3.1 Installer ESP Access (already works)
The installer already uses `fatfs` to format and write the EFI partition. This is
host-side and already functional. No changes needed for basic ESP creation.
#### 3.2 Recipe Configuration
Add `fatd` and tools to relevant config files:
```toml
# config/desktop.toml or redbear-desktop.toml
fatd = {}
fat-mkfs = {}
fat-label = {}
fat-check = {}
```
#### 3.3 Init Service
Create a Redox init service for auto-mounting FAT volumes. Follow the pattern in
`config/redbear-device-services.toml` and `config/redbear-netctl.toml`: services are
defined as `[[files]]` TOML blocks with paths under `/usr/lib/init.d/`, using the
`[unit]` + `[service]` format with `cmd`, `args`, and `type` fields.
**File**: `config/redbear-device-services.toml` (append to existing file)
```toml
[[files]]
path = "/usr/lib/init.d/15_fatd.service"
data = """
[unit]
description = "FAT filesystem auto-mount daemon"
requires_weak = [
"00_pcid-spawner.service",
]
[service]
cmd = "fatd"
args = ["disk/live-virtio", "fat-live"]
type = { scheme = "fat-live" }
"""
```
For runtime auto-mount of removable devices (USB, SD), a separate `redbear-automount`
service would watch `/scheme/disk/` for new block devices, probe for FAT signatures,
and launch `fatd` instances dynamically. This follows the same `[unit]`/`[service]`
TOML pattern. Reference implementation: `config/redbear-device-services.toml` lines
1426 (`05_firmware-loader.service` uses `type = { scheme = "firmware" }`).
### Phase 4: Runtime Auto-Mount & Desktop Integration — 12 weeks
#### 4.1 Block Device Discovery
When a block device appears (USB insertion, SD card detect), a service should:
1. Detect new block device via `/scheme/disk/` or equivalent
2. Probe for FAT filesystem (read first sector, check for valid BPB signature)
3. If FAT detected, launch `fatd <device> <scheme_name>`
4. The FAT filesystem becomes accessible at `/scheme/<scheme_name>/`
#### 4.2 Unmount Handling
On device removal or system shutdown:
1. Send SIGTERM to `fatd` daemon
2. Daemon flushes and drops `fatfs::FileSystem` (auto-flush on drop)
3. Scheme is unregistered
#### 4.3 Desktop File Manager Integration
For the KDE Plasma desktop path (Phases 34 of the desktop plan):
- Solid/UDisks2 backend recognizes mounted FAT volumes
- Volume labels displayed in file manager
- "Safely remove" triggers clean unmount via SIGTERM to fatd
### Phase 5: Testing & Hardening — 1 week
#### 5.1 Unit Tests
Test against FAT images created with `fat-mkfs`:
- Create/read/write/delete files with short names
- Create/read/write/delete files with long names (LFN)
- Create/remove directories
- Rename files and directories
- Read filesystem stats (fstatvfs)
- Handle full filesystem (ENOSPC)
- Handle read-only filesystem (EROFS)
#### 5.2 Edge Cases
From the `fatfs` crate's bug history and FAT specification:
- **0xE5 first byte**: Short names starting with 0xE5 are stored as 0x05
- **FSInfo unreliability**: Never trust FSInfo free count blindly
- **FAT32 upper 4 bits**: Must be preserved when writing FAT entries
- **LFN checksum**: Must verify against SFN to detect orphaned entries
- **Max path length**: FAT LFN max is 255 characters
- **Case sensitivity**: FAT is case-insensitive, must normalize lookups
- **Fragmentation**: Large fragmented files should still read/write correctly
- **Timestamp precision**: 2-second granularity, 19802107 date range
#### 5.3 Compatibility Testing
Test with FAT images from:
- Windows 10/11 formatted USB drives
- Linux `mkfs.fat` created images
- macOS formatted FAT32 SD cards
- Digital camera FAT32 SD cards (often fragmented)
- Large FAT32 volumes (128 GB+ SD cards)
## 4. Task Breakdown for Delegation
### Wave 1: Foundation (Phase 1.11.2) — Parallel
| Task | Category | Effort | Dependencies | QA |
|------|----------|--------|--------------|-----|
| Create workspace structure, Cargo.toml, recipe.toml, symlinks | quick | 30 min | None | `cargo check --target x86_64-unknown-redox` succeeds from workspace root; `ls -la recipes/core/fatd` shows valid symlink |
| Implement `fat-blockdev` FileDisk (Linux) | unspecified-low | 2 hr | Workspace | Unit test: create 1 MB temp file, open via FileDisk, read 512 bytes at offset 0, verify zero-filled; seek to offset 1024, write pattern, read back, verify match |
| Implement `fat-blockdev` RedoxDisk (Redox, feature-gated) | unspecified-low | 2 hr | Workspace | `cargo check --target x86_64-unknown-redox --features redox` succeeds; `cargo check` (Linux, no redox feature) also succeeds |
### Wave 2: Scheme Daemon (Phase 1.31.5) — Sequential on Wave 1
| Task | Category | Effort | Dependencies | QA |
|------|----------|--------|--------------|-----|
| Implement `handle.rs` (FileHandle, DirHandle, Handle) | unspecified-low | 1 hr | Wave 1 | `cargo check` passes; handle.path() returns correct path; handle.flags() returns O_RDONLY/O_WRONLY/O_RDWR as set |
| Implement `scheme.rs` (FatScheme with SchemeSync) | unspecified-high | 23 days | Wave 1 | Integration test: create 10 MB FAT32 image via `fatfs::format_volume()`, mount via FatScheme, `openat` a file, `write` 100 bytes, `read` back 100 bytes, verify match; `getdents` on root dir returns "." and ".."; `fstat` returns st_mode with S_IFREG; `fstatvfs` returns non-zero f_blocks |
| Implement `mount.rs` (event loop) | unspecified-low | 2 hr | scheme.rs | `cargo check` passes; verify event loop compiles with `register_sync_scheme` and `socket.next_request()` |
| Implement `main.rs` (daemon lifecycle) | unspecified-low | 2 hr | mount.rs | Build `fatd` binary: `cargo build --bin fatd`; run `fatd --help` shows usage; run `fatd test.img test-scheme` with a FAT32 test image, verify scheme registered at `/scheme/test-scheme/` |
| LFN integration testing | deep | 1 day | scheme.rs | Create file named "This Is A Very Long Filename.txt" (33 chars), read it back, verify full name returned; create file with 200-char name, verify LFN entries; create file with Unicode name "café_日本語.txt", verify round-trip |
| FAT12/16/32 auto-detection testing | deep | 1 day | scheme.rs | Create three images (FAT12: 1 MB, FAT16: 16 MB, FAT32: 64 MB) via `fat-mkfs`, mount each via FatScheme, write and read a file on each, verify all three succeed |
### Wave 3: Management Tools (Phase 2) — Parallel after Wave 1
| Task | Category | Effort | Dependencies | QA |
|------|----------|--------|--------------|-----|
| Implement `fat-mkfs` binary | unspecified-low | 3 hr | fat-blockdev | Create 64 MB image: `fat-mkfs /tmp/test.img`; verify: `fatfs::FileSystem::new()` can mount it; verify: `fat-mkfs -F 32 /tmp/test32.img` creates FAT32; verify: `fat-mkfs -n TESTVOL /tmp/test.img` sets label |
| Implement `fat-label` binary | unspecified-low | 3 hr | fat-blockdev | After `fat-mkfs -n TESTVOL /tmp/test.img`: `fat-label /tmp/test.img` prints "TESTVOL"; `fat-label /tmp/test.img NEWNAME` succeeds; `fat-label /tmp/test.img` prints "NEWNAME" |
| Implement `fat-check` verifier (Phase 2a) | unspecified-high | 1 week | fat-blockdev | Run on clean image: exits 0, reports "filesystem clean"; corrupt FAT chain (write bad entry manually): `fat-check` detects and reports "cross-linked files" or "lost clusters"; run on image with orphaned LFN: reports "orphaned LFN entries" |
| Implement `fat-check` safe-repair (Phase 2b) | unspecified-high | 1 week | Phase 2a | Corrupt FSInfo free count: `fat-check --repair` fixes it, re-run verifier exits 0; set dirty bit: `fat-check --repair` clears it |
### Wave 4: Integration (Phase 34) — Sequential on Waves 23
| Task | Category | Effort | Dependencies | QA |
|------|----------|--------|--------------|-----|
| Add fatd to config TOMLs | quick | 15 min | Wave 2 | `grep fatd config/redbear-desktop.toml` shows `fatd = {}`; `grep fatd config/redbear-full.toml` shows `fatd = {}` |
| Create init service for FAT mounting | unspecified-low | 3 hr | Wave 2 | Service file exists at `/usr/lib/init.d/15_fatd.service` with `[unit]` and `[service]` sections; `cmd = "fatd"` present; `type = { scheme = "..." }` present; follows `config/redbear-device-services.toml` pattern exactly |
| Build + test full integration | deep | 2 days | Waves 23 | `make all CONFIG_NAME=redbear-desktop` succeeds; boot in QEMU: `fatd --help` runs; create FAT image on host, attach to QEMU VM, verify `fatd` can mount it at `/scheme/fat-test/` |
| Edge case + compatibility testing | deep | 3 days | Wave 2 | Test images: Windows-formatted FAT32 USB (4 GB), Linux mkfs.fat FAT16 (128 MB), macOS FAT32 SD (32 GB); all mount and read/write correctly via fatd |
## 5. Dependency Graph
```
Phase 1.1 (workspace) ──┬──→ Phase 1.2 (blockdev) ──┬──→ Phase 1.3 (scheme daemon)
│ │
│ ├──→ Phase 2.1 (fat-mkfs)
│ ├──→ Phase 2.2 (fat-label)
│ └──→ Phase 2.3a (fat-check verify)
│ │
│ └──→ Phase 2.3b (fat-check repair)
Phase 1.3 ──────────────────────────────────────────→ Phase 3 (config/integration)
Phase 3 ──────────────────────────────────────────────→ Phase 4 (auto-mount)
Phase 4 + Phase 2 ───────────────────────────────────→ Phase 5 (testing)
```
**Critical path**: Phase 1.1 → 1.2 → 1.3 → Phase 3 → Phase 4 → Phase 5
**Parallel opportunities**: Phase 2 tools can start after Phase 1.2 (blockdev),
overlapping with Phase 1.3 (scheme daemon).
## 6. Technical Notes
### FAT Limitations in Unix Context
Since FAT is data/ESP only (not root), most Unix metadata issues are irrelevant:
| FAT Limitation | Impact for data volumes | Mitigation |
|----------------|------------------------|------------|
| No Unix permissions | Files appear as 0o644/0o755 | Acceptable for data volumes |
| No symlinks | Cannot store symlinks | Data volumes don't need them |
| No device nodes | Cannot store /dev entries | Data volumes don't need them |
| No ownership | All files appear uid=0/gid=0 | Acceptable for data volumes |
| 2s timestamp precision | Some timestamps rounded | Acceptable for data volumes |
| 255 char filename max | No path component > 255 chars | Sufficient for data use |
| Case-insensitive | Lookups must normalize | Scheme daemon handles this |
| No sparse files | Holes consume disk space | Acceptable for data volumes |
| Max file size: 4 GB - 1 | Large files may not fit | Acceptable for most use |
### `fatfs` Crate Feature Configuration
```toml
[dependencies]
# For the scheme daemon (full features)
fatfs = { version = "0.3.6", default-features = false, features = ["lfn", "alloc", "log"] }
# For fat-mkfs (formatting support)
fatfs = { version = "0.3.6", default-features = false, features = ["lfn", "alloc"] }
# For fat-check (read-only)
fatfs = { version = "0.3.6", default-features = false, features = ["lfn", "alloc"] }
```
Features available:
- `lfn` — VFAT long filename support (REQUIRED)
- `alloc` — Use alloc crate for dynamic allocation (REQUIRED for no_std)
- `log` — Logging via `log` crate (optional, useful for debugging)
- `chrono` — Timestamp creation via chrono (optional, not needed with our time adapter)
- `std` — Use std library (NOT used — we want no_std compatibility)
### Block Caching Strategy
Without caching, `fatfs` performs one I/O operation per metadata read — extremely slow.
The recommended approach:
```rust
use fscommon::BufStream;
// Wrap raw disk in buffered stream
let disk = RedoxDisk::open(disk_path)?;
let buf_disk = BufStream::new(disk);
// fatfs operates on the buffered stream
let fs = fatfs::FileSystem::new(buf_disk, fatfs::FsOptions::new())?;
```
`BufStream` provides a configurable read/write buffer (default 512 bytes, should be
increased to 4096 or larger for better throughput on block devices).
### Scheme Name Convention
Following the ext4d pattern:
- `fatd /scheme/disk/0 disk-fat-0` registers scheme `disk-fat-0`
- Access at `/scheme/disk-fat-0/path/to/file`
- Multiple FAT volumes: `disk-fat-0`, `disk-fat-1`, etc.
Alternative: Use a single `fat` scheme namespace and multiplex based on the
device path embedded in the mount command.
### Concurrency Model
`fatfs::FileSystem` is NOT thread-safe. The scheme daemon handles this by:
1. Single-threaded event loop (same as ext4d)
2. One `FileSystem` instance per daemon process
3. Sequential request processing via `socket.next_request()`
4. No internal mutability tricks needed
This matches the Redox scheme model — requests are serialized by the kernel.
## 7. Risks and Mitigations
| Risk | Probability | Impact | Mitigation |
|------|-------------|--------|------------|
| `fatfs` crate bug in LFN handling | Low | Medium | v0.3.6 has known fixes; test thoroughly |
| Performance without caching | High | High | BufStream wrapper is mandatory, not optional |
| FAT corruption on unsafe removal | Medium | High | Write-fat-sync on flush; journal not possible on FAT |
| FAT32 max file size (4 GB) | Low | Low | Document limitation; return EFBIG for oversized writes |
| `fatfs` API doesn't support needed operations | Low | Medium | Fall back to direct BPB/FAT manipulation |
| Feature flag conflicts with no_std | Low | Medium | Test both Linux and Redox builds in CI |
## 8. Files to Create
```
local/recipes/core/fatd/
├── recipe.toml
└── source/
├── Cargo.toml ← Workspace root
├── fat-blockdev/
│ ├── Cargo.toml
│ └── src/
│ ├── lib.rs
│ ├── file_disk.rs
│ └── redox_disk.rs
├── fatd/
│ ├── Cargo.toml
│ └── src/
│ ├── main.rs
│ ├── mount.rs
│ ├── scheme.rs
│ └── handle.rs
├── fat-mkfs/
│ ├── Cargo.toml
│ └── src/
│ └── main.rs
├── fat-label/
│ ├── Cargo.toml
│ └── src/
│ └── main.rs
└── fat-check/
├── Cargo.toml
└── src/
└── main.rs
recipes/core/fatd → ../../local/recipes/core/fatd (symlink, matching ext4d pattern)
config/redbear-desktop.toml ← add fatd, fat-mkfs, fat-label, fat-check packages
config/redbear-full.toml ← same
config/desktop.toml ← add fatd (upstream or local override)
```
## 9. Estimated Timeline
| Phase | Duration | Deliverable |
|-------|----------|-------------|
| Phase 1: FAT scheme daemon | 34 weeks | `fatd` binary, mount/unmount FAT volumes |
| Phase 2: Management tools | 23 weeks | `fat-mkfs`, `fat-label`, `fat-check` |
| Phase 3: Build integration | 1 week | Config entries, recipe symlinks |
| Phase 4: Auto-mount service | 12 weeks | Block device detection, auto-mount |
| Phase 5: Testing & hardening | 1 week | Edge cases, compatibility |
| **Total** | **811 weeks** | **Full VFAT support** |
Phase 2 can overlap with Phase 1.3, reducing wall-clock time to approximately
**610 weeks** with parallel execution.
## 10. Success Criteria
- [x] `fatd` mounts FAT12, FAT16, and FAT32 filesystems as Redox schemes (compiles, links on Redox target only)
- [x] Read/write files with both short (8.3) and long (LFN) filenames
- [x] Create/delete files and directories
- [x] Rename files and directories
- [x] Correctly report filesystem stats (fstatvfs)
- [x] `fat-mkfs` creates valid FAT filesystems usable by Windows/Linux/macOS
- [x] `fat-label` reads and writes volume labels (BPB + root-directory entry updated)
- [x] `fat-check` detects and reports FAT filesystem errors (verify + repair mode)
- [x] Integration with Redox config system (TOML)
- [x] (deferred: not on desktop critical path) Works on both Linux host (management tools ✅) and Redox target (fatd untested — requires runtime)
- [x] No `unwrap()`/`expect()` in library/driver code
- [x] (deferred: not on desktop critical path) Runtime auto-mount service (Phase 4 deferred to runtime validation)
- [x] (deferred: not on desktop critical path) Runtime validation of fatd on Redox target (requires QEMU/bare metal boot)
## 11. Test Results
### Edge Case Testing (2026-04-17, Linux host)
| Test | Result | Notes |
|------|--------|-------|
| Corrupt boot signature (0x00 0x00) | ✅ Detected | Exit 1, reports "invalid boot sector signature" |
| Zero bytes_per_sector | ✅ Detected | Exit 1, reports "invalid bytes per sector: 0" |
| Tiny FAT12 (512KB) | ✅ Clean | Auto-detected as FAT16 by fat-check (fatfs classifies small volumes) |
| Large FAT32 (256MB) | ✅ Clean | 516214 clusters, cluster size 512 bytes |
| Very large FAT32 (1GB) | ✅ Clean | 261631 clusters, cluster size 4096 bytes (auto-selected) |
| No volume label | ✅ | Reports "NO NAME" |
| Max length label (11 chars) | ✅ | "12345678901" round-trips correctly |
| Too-long label (12 chars) | ✅ Rejected | Exit 1, "volume label too long" |
| Auto-detect FAT type (32MB) | ✅ | Selected FAT16 automatically |
| Cross-platform (Linux mkfs.fat FAT32) | ⚠️ Partial | fatfs v0.3.6 rejects small mkfs.fat images (non-zero total_sectors_16 for FAT32 — fatfs strictness) |
| FAT12 (1MB) | ✅ Clean | mkfs + check pass |
| FAT16 (16MB) | ✅ Clean | mkfs + check pass |
| FAT32 (64MB) | ✅ Clean | mkfs + check pass |
| File creation on all FAT types | ✅ | 7 files + 1 dir created via fatfs on FAT12/16/32, all verified clean |
| Label write on populated image | ✅ | No data corruption after label change, files still accessible |
| FSInfo repair (FAT32) | ✅ | Detected mismatch (0xFFFFFFFF vs actual), repaired, re-check clean |
| Repair on clean image (FAT16) | ✅ | "Repaired: nothing needed", exit 0 |
| Directory count accuracy | ✅ | Fixed: files: 7, directories: 1 (was 0/0 due to tuple borrowing bug) |
**Known limitation**: `fatfs` v0.3.6 strictly requires `total_sectors_16 == 0` for FAT32,
but Linux's `mkfs.fat` may set it non-zero for small FAT32 images. This is a fatfs crate
strictness issue, not a Red Bear code bug. Files created by `fat-mkfs` are always accepted.
## 12. Quality Assessment (2026-04-17)
### 12.1 Code Metrics
| Crate | Lines | Files | `unwrap()` | `expect()` | `TODO/FIXME` | `#[cfg(test)]` |
|-------|-------|-------|------------|------------|--------------|----------------|
| fat-blockdev | 134 | 3 | 0 | 0 | 0 | 0 |
| fatd | 1376 | 4 | 0 | 0 | 0 | 25 tests |
| fat-mkfs | 158 | 1 | 0 | 0 | 0 | 0 |
| fat-label | 436 | 1 | 0 | 0 | 0 | 7 tests |
| fat-check | 1399 | 1 | 0 | 0 | 0 | 28 tests |
| **Total** | **3503** | **10** | **0** | **0** | **0** | **60 tests** |
### 12.2 Anti-Patterns Found
| Severity | File | Line | Issue |
|----------|------|------|-------|
| ~~Medium~~ | ~~`fat-blockdev/src/file_disk.rs`~~ | ~~17~~ | ~~✅ Fixed: logs warning~~ |
| ~~Medium~~ | ~~`fat-blockdev/src/redox_disk.rs`~~ | ~~26,32,38,50~~ | ~~✅ Fixed: preserves error details~~ |
| ~~Medium~~ | ~~`fat-label/src/main.rs`~~ | ~~281-291~~ | ~~✅ Fixed: warns on full root dir~~ |
| Low | `fatd/src/scheme.rs` | 633 | `handle.flags().unwrap_or(O_RDONLY)` silently defaults to read-only |
| ~~Low~~ | ~~`fatd/src/scheme.rs`~~ | ~~214-220~~ | ~~✅ Fixed: dead code removed~~ |
| Low | `fatd/src/main.rs` | 98,106,113 | `let _ = pipe.write_all(...)` silently ignores status pipe errors |
| ~~Low~~ | ~~`fat-check/src/main.rs`~~ | ~~484~~ | ~~✅ Fixed: FAT12 dirty flag implemented~~ |
| ~~Low~~ | ~~`fat-mkfs/src/main.rs`~~ | ~~72-82~~ | ~~✅ Fixed: pre-zero with 64K chunks~~ |
### 12.3 Functional Gaps vs Reference (ext4d)
| Operation | ext4d | fatd | Notes |
|-----------|-------|------|-------|
| `linkat` (hard links) | ✅ | ❌ | FAT doesn't support hard links — gap is by design |
| `renameat` | ✅ | ✅ | `frename` via fatfs `Dir::rename()` — cross-directory rename supported |
| `symlinkat`/`readlinkat` | ✅ | ❌ | FAT doesn't support symlinks — gap is by design |
| `refresh_file_handle` | ✅ | ❌ | ext4d re-opens after truncate; fatd just seeks |
| Directory non-empty check | ✅ | ✅ | `unlinkat` checks for entries before `AT_REMOVEDIR` |
| Real inode numbers | ✅ | ⚠️ | fatd uses synthetic hash-based inodes |
| `st_nlink` | ✅ | ⚠️ | Hardcoded to 1 (files) or 2 (dirs) |
| `fsync` scope | Full FS | Single file | ext4d syncs entire filesystem |
### 12.4 Error Handling Quality
**Pattern**: CLI tools use `unwrap_or_else(\|e\| { eprintln!(...); process::exit(1) })` consistently.
Daemon code uses `?` operator and `map_err(fat_error)` for syscall error conversion.
**Issue**: `fat_error()` in `scheme.rs:811-834` uses string matching on `io::Error` descriptions
to map to syscall error codes. This is fragile — error message changes in fatfs would break it.
ext4d's `ext4_error()` is simpler and more robust.
### 12.5 Missing Features vs Standard Linux Tools
#### fat-mkfs vs mkfs.fat
| Option | mkfs.fat | fat-mkfs | Notes |
|--------|----------|----------|-------|
| Cluster size (`-s`) | ✅ | ✅ | `-c <sectors>` option, power-of-2 validation |
| Reserved sectors (`-f`) | ✅ | ❌ | |
| Number of FATs | ✅ | ❌ | Hardcoded to 2 |
| Bytes per sector (`-S`) | ✅ | ❌ | Hardcoded to 512 |
| Drive number | ✅ | ❌ | |
| Backup boot sector | ✅ | ❌ | |
| Media descriptor | ✅ | ❌ | Uses fatfs default (0xF8) |
| Bad cluster check (`-c`) | ✅ | ❌ | |
| Invariant mode (`-I`) | ✅ | ❌ | |
| Pre-zeroing of image | ✅ | ✅ | 64K-chunk zero-fill |
#### fat-check vs fsck.fat
| Check | fsck.fat | fat-check | Severity |
|-------|----------|-----------|----------|
| Media descriptor byte (BPB:21) | ✅ | ❌ | Medium |
| FAT type string (BPB:54-61) | ✅ | ❌ | Low |
| Cross-linked files | ✅ | ❌ | Medium |
| Duplicate directory entries | ✅ | ❌ | Medium |
| Invalid volume label chars | ✅ | ❌ | Low |
| Timestamp validation | ✅ | ❌ | Low |
| FSInfo reserved bits | ✅ | ❌ | Medium |
| FAT32 fs_version field | ✅ | ❌ | Medium |
| Automatic repair (`-a`) | ✅ | ❌ | Low |
| FAT12 dirty flag | ✅ | ✅ | Bits 11:10 of cluster 1 entry |
### 12.6 Style Consistency
- Follows ext4d reference patterns closely (workspace layout, scheme structure, handle types)
- Consistent naming: `snake_case` functions, `PascalCase` types
- Error messages prefixed with binary name (`fat-label:`, `fat-check:`, etc.)
- `rustfmt.toml` at workspace root: max_width=100, brace_style=SameLineWhere
- 60 unit tests across 3 crates (25 scheme + 7 label + 28 check) + 13+ integration edge cases
### 12.7 Build Integration Assessment
| Check | Status | Notes |
|-------|--------|-------|
| `recipe.toml` correctness | ✅ | Custom template, COOKBOOK_CARGO_PATH for all 4 binaries |
| Symlink `recipes/core/fatd` | ✅ | Points to `../../local/recipes/core/fatd` |
| `redbear-device-services.toml` | ✅ | Packages + init service at `/usr/lib/init.d/15_fatd.service` |
| Included in `redbear-desktop.toml` | ✅ | Via include chain |
| Included in `redbear-full.toml` | ✅ | Via include chain |
| Included in `redbear-minimal.toml` | ✅ | Via include chain |
| Included in `redbear-full.toml` | ✅ | Via include chain |
| Included in `redbear-wayland.toml` | ❌ | Does NOT include `redbear-device-services.toml` |
| `cargo check` passes | ✅ | All crates check clean |
| `cargo build --release` (tools) | ✅ | fat-mkfs, fat-label, fat-check build on Linux |
| `cargo build --release` (fatd) | ⚠️ | Compiles but links only on Redox target (expected) |
### 12.8 Documentation Assessment
| Document | Accurate | Notes |
|----------|----------|-------|
| `VFAT-IMPLEMENTATION-PLAN.md` | ✅ | Status, success criteria, and test results all accurate |
| `local/AGENTS.md` FAT section | ✅ | Workspace layout, tool status, limitations documented |
| Success criteria checkboxes | ✅ | Done items checked, deferred items unchecked |
| Test results table | ✅ | 13+ edge cases documented with outcomes |
### 12.9 Maturity Rating
| Dimension | Rating (1-5) | Notes |
|-----------|-------------|-------|
| Code correctness | 4 | Clean error handling, no unwrap/expect in daemon code |
| Feature completeness | 4 | Rename + rmdir check + cluster size now implemented |
| Test coverage | 4 | 60 unit tests + 13+ integration edge cases (helper-level, not end-to-end scheme tests) |
| Code style | 4 | Consistent with ext4d reference, clean formatting |
| Documentation | 4 | Comprehensive plan, accurate status, known limitations |
| Build integration | 5 | Wired into 5/5 configs via `redbear-device-services.toml` include chain |
| Error resilience | 3 | fatfs re-opens on each file access (no persistent handles) |
| Production readiness | 2 | Not runtime-tested on Redox; Phase 4 auto-mount deferred |
**Overall**: 3.6/5 (provisional — pending runtime validation on Redox/QEMU). Solid implementation with good test coverage at the helper and tool level. fatd scheme daemon has not been runtime-tested.
### 12.10 Cleanup Status
| # | Cleanup | Status | Detail |
|---|---------|--------|--------|
| 1 | `redox_disk.rs` error discarding | ✅ Done | 3 read/write/flush `.map_err(\|_\|...)` replaced with `.map_err(\|e\| format!("redox {op}: {e:?}"))`; seek already had detail |
| 2 | `file_disk.rs:17` silent failure | ✅ Done | Logs warning instead of silently returning 0 |
| 3 | `fat-label` full-root-dir warning | ✅ Done | Both FAT32 and FAT12/16 paths warn when root dir full |
| 4 | `scheme.rs:214-220` dead code | ✅ Done | Redundant uid==0 check removed |
| 5 | Pre-zero image in `fat-mkfs` | ✅ Done | 64K-chunk zero-fill before format, no sparse files |
| 6 | FAT12 dirty flag detection | ✅ Done | Bits 11:10 of cluster 1 entry; detect + repair verified |
| 7 | `frename` support | ✅ Done | `Dir::rename()` for cross-directory rename, handle path updated post-rename |
| 8 | Rmdir non-empty check | ✅ Done | `unlinkat` checks directory entries before AT_REMOVEDIR |
| 9 | Cluster size option in `fat-mkfs` | ✅ Done | `-c <sectors>` with power-of-2 validation |
| 10 | Unit test suite | ✅ Done | 60 tests across 3 crates (25 scheme + 7 label + 28 check) |
| 11 | `lfn_checksum` overflow fix | ✅ Done | wrapping_add for u8 arithmetic, regression test added |
### 12.11 Remaining Improvements (Deferred)
1. **Runtime validate fatd on QEMU** — Boot Red Bear OS, mount a FAT image, perform read/write/rename ops
2. ~~**Evaluate `redbear-wayland.toml` inclusion**~~ — Verified: wayland.toml includes redbear-device-services.toml, so FAT tools are in all 5 configs
3. **`handle.flags().unwrap_or(O_RDONLY)`** — Low severity silent default in fcntl
4. **`let _ = pipe.write_all(...)` in main.rs** — Low severity, hides daemon startup status pipe errors
5. **`fsync` only flushes single file** — Doesn't sync filesystem metadata (by design: fatfs has no journal)
6. **`fat_error()` string matching** — Medium severity; depends on exact fatfs error message text. Low risk on stable fatfs 0.3.6 but fragile across versions
### 12.12 Independent Audit Results (2026-04-17, 3rd pass)
Three parallel explore agents audited: (A) scheme daemon code quality vs ext4d reference, (B) management tools quality, (C) build integration and documentation accuracy.
**Scheme daemon audit (A):**
- `fevent` error codes: Verified identical to ext4d — NOT a bug (EPERM = operation not supported, EBADF = bad fd)
- `frename` permission checks: `lookup_parent` already enforces PERM_EXEC | PERM_WRITE on both source and destination parents
- `fat_error` string matching: Known, documented, low risk on stable fatfs 0.3.6
- `fsync` scope: By design — fatfs has no journal, single-file flush is appropriate
- Handle path update after `frename`: Correctly implemented with `update_path()`
- `unlinkat` non-empty check: Correct — iterates entries, returns ENOTEMPTY if any non-dot entry found
- Match arm completeness: All SchemeSync trait methods fully implemented
**Management tools audit (B):**
- `fat-mkfs`: Argument parsing complete (-F, -n, -s, -c), validation correct, pre-zeroing works
- `fat-label`: BPB offset calculation correct (43 for FAT12/16, 71 for FAT32), root-dir entry creation verified
- `fat-check`: BPB validation thorough, FAT chain walking correct, dirty flag logic correct for all FAT types
- `lfn_checksum`: Wrapping arithmetic verified correct with known test vectors
- Exit codes: 0=clean, 1=errors, 2=repaired — matches fsck conventions
- Unit test vectors: All verified correct (FAT12/16/32 encoding, round-trip, classification)
**Build integration audit (C):**
- All 5/5 redbear configs include `redbear-device-services.toml` via include chain (including redbear-wayland via wayland.toml)
- Recipe symlink correct: `recipes/core/fatd → ../../local/recipes/core/fatd`
- Workspace Cargo.toml: All 5 crates correctly configured (fixed stale `chrono` reference)
- Init service at `/usr/lib/init.d/15_fatd.service` correct
- AGENTS.md FAT section: Accurate
- VFAT-IMPLEMENTATION-PLAN.md Sections 10/12: Accurate
**Audit conclusion**: No critical or high-severity issues found in implementation code. One medium doc accuracy issue corrected (redox_disk.rs error detail fix was claimed but not persisted — now actually applied). All code spot-checks passed. Remaining items are low severity and documented in Section 12.10.
-320
View File
@@ -1,320 +0,0 @@
# Zsh Porting Plan for Red Bear OS
**Status:** ✅ FULLY IMPLEMENTED — Production recipe builds, configs updated, WIP removed
**Target:** zsh 5.9 (upstream stable tag `zsh-5.9`)
**Recipe:** `recipes/shells/zsh/`
**Build Result:** `cook zsh - successful` (CI=1, non-interactive)
---
## 1. Executive Summary
Zsh 5.9 has been successfully ported to Red Bear OS. The build produces a working `zsh` binary for `x86_64-unknown-redox` with:
- Full interactive shell support (ZLE line editor)
- Completion system (`zsh/complete` built-in)
- Parameter module (`zsh/parameter` built-in)
- History and prompt expansion
- Job control primitives (`setpgid`, `tcsetpgrp`)
- Multibyte / UTF-8 support (`--enable-multibyte`)
- System `malloc` (no custom allocator)
- Static modules (no dynamic `.so` loading)
- Manjaro-style system-wide configuration (`/etc/zsh/`, `/etc/skel/`)
The port required **one source patch** (`redox.patch`, ~150 lines) plus a deterministic `signames.c` generation step in the build script to work around cross-compilation limitations.
---
## 2. What Was Done
### 2.1 Recipe Created
**Location:** `recipes/shells/zsh/`
```
recipes/shells/zsh/
├── recipe.toml # Production recipe (custom template)
├── redox.patch # Redox-specific source patches
├── README.md # Redox-specific build and usage notes
└── etc/ # Manjaro-style system-wide config files
├── zsh/
│ ├── zshenv
│ ├── zprofile
│ └── zshrc
└── skel/
├── .zprofile
└── .zshrc
```
### 2.2 Source
- **URL:** `https://github.com/zsh-users/zsh/archive/refs/tags/zsh-5.9.tar.gz`
- **BLAKE3:** `a15b94fae03e87aba6fc6a27df3c98e610b85b0c7c0fc90248f07fdcb8816860`
- **Patches applied:** `redox.patch`
### 2.3 Build Configuration
The recipe uses the `custom` template with explicit configure flags:
```bash
COOKBOOK_CONFIGURE_FLAGS+=(
--disable-gdbm
--disable-pcre
--disable-cap
zsh_cv_sys_elf=no
)
```
**Rationale:**
- `--disable-gdbm` — No gdbm package in base system.
- `--disable-pcre` — PCRE library not wired as dependency for initial build; can be re-enabled later.
- `--disable-cap` — No libcap (Linux capabilities).
- `zsh_cv_sys_elf=no` — Redox does not use ELF-style shared library versioning.
**Signames workaround:** The cross-compilation environment cannot run the `signames1.awk``cpp``signames2.awk` pipeline natively. The build script pre-generates `signames.c` and `sigcount.h` deterministically using the host `gawk` and cross-compiler.
### 2.4 Patch Summary (`redox.patch`)
| File | Change | Reason |
|------|--------|--------|
| `configure.ac` | Cache `ac_cv_func_times=no` | `times()` missing in relibc |
| `configure.ac` | Cache `ac_cv_func_setpgrp=no` | BSD `setpgrp()` missing; zsh falls back to `setpgid` |
| `configure.ac` | Cache `ac_cv_func_killpg=no` | `killpg()` missing; zsh defines `kill(-pgrp,sig)` fallback |
| `configure.ac` | Cache `ac_cv_func_initgroups=no` | Not available in relibc |
| `configure.ac` | Cache `ac_cv_func_pathconf=no` | Not available in relibc |
| `configure.ac` | Cache `ac_cv_func_sysconf=no` | Not available in relibc |
| `configure.ac` | Cache `ac_cv_func_getrlimit=no` | Relibc has it, but configure probe may misdetect; safe to cache |
| `configure.ac` | Cache `ac_cv_func_tcgetsid=no` | Relibc has it, but configure probe may misdetect; safe to cache |
| `configure.ac` | Cache `ac_cv_func_tgetent=yes` | Available via ncursesw |
| `configure.ac` | Cache `ac_cv_func_tigetflag=yes` | Available via ncursesw |
| `configure.ac` | Cache `ac_cv_func_tigetnum=yes` | Available via ncursesw |
| `configure.ac` | Cache `ac_cv_func_tigetstr=yes` | Available via ncursesw |
| `configure.ac` | Cache `ac_cv_func_setupterm=yes` | Available via ncursesw |
| `configure.ac` | Remove `AC_SEARCH_LIBS([tgetent], [tinfo curses ncurses])` | Redox uses ncursesw directly |
| `configure.ac` | Remove `AC_SEARCH_LIBS([tigetstr], [tinfo curses ncurses])` | Redox uses ncursesw directly |
| `configure.ac` | Remove `AC_SEARCH_LIBS([setupterm], [tinfo curses ncurses])` | Redox uses ncursesw directly |
| `configure.ac` | Remove `AC_SEARCH_LIBS([del_curterm], [tinfo curses ncurses])` | Redox uses ncursesw directly |
| `Src/rlimits.c` | Define `RLIM_NLIMITS` fallback | Relibc header may not define it |
| `Src/rlimits.c` | Define `RLIM_SAVED_CUR` / `RLIM_SAVED_MAX` fallbacks | Relibc header may not define them |
| `Src/rlimits.c` | Define `RLIMIT_NPTS` / `RLIMIT_SWAP` / `RLIMIT_KQUEUES` stubs | BSD-only limits not in relibc |
| `Src/rlimits.c` | Define `RLIMIT_RTTIME` stub | Linux-only limit not in relibc |
| `Src/rlimits.c` | Define `RLIMIT_NICE` / `RLIMIT_MSGQUEUE` / `RLIMIT_RTPRIO` stubs | Linux-only limits not in relibc |
| `Src/rlimits.c` | Define `RLIMIT_NLIMITS` as 16 if still undefined | Final fallback |
| `Src/params.c` | Guard `getpwnam`/`getpwuid` return value | Relibc returns basic structs; add NULL checks |
| `Src/Modules/termcap.c` | Link against `ncursesw` not `termcap` | Redox has ncursesw, not standalone termcap |
| `Src/Modules/clone.c` | Disable `clone` module | `clone()` / `unshare()` not available on Redox |
| `Src/Modules/zpty.c` | Disable `zpty` module | `openpty` / `forkpty` not available on Redox |
### 2.5 Config Files Updated
- `config/redbear-full.toml` — Added `"zsh"` to `[packages]`
- `config/redbear-mini.toml` — Added `"zsh"` to `[packages]`
### 2.6 WIP Recipe Removed
- `recipes/wip/shells/zsh/` — Removed after successful migration to production.
---
## 3. Build Verification
### 3.1 Build Command
```bash
CI=1 ./target/release/repo cook zsh
```
### 3.2 Build Output
```
cook zsh - successful
repo - publishing zsh
repo - generating repo.toml
```
### 3.3 Staged Artifacts
```
stage/
├── etc/
│ ├── zsh/
│ │ ├── zshenv # System-wide env setup
│ │ ├── zprofile # System-wide profile
│ │ └── zshrc # System-wide interactive config
│ └── skel/
│ ├── .zprofile # New-user template
│ └── .zshrc # New-user interactive config
└── usr/
├── bin/
│ ├── zsh # → zsh-5.9 (symlink)
│ └── zsh-5.9 # Actual binary (~1.2 MB stripped)
└── share/
└── zsh/
├── 5.9/
│ └── functions/ # 800+ completion functions
└── site-functions/ # Site-local completions
```
### 3.4 Binary Check
```bash
$ file zsh
zsh: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
$ ls -la zsh
-rwxr-xr-x 1 kellito kellito 1267176 Apr 26 02:14 zsh
```
---
## 4. POSIX Dependency Matrix (Actual vs Planned)
| API / Feature | Planned Action | Actual Result |
|---------------|---------------|---------------|
| `getrlimit` / `setrlimit` | Remove obsolete cache | Cached `no` for safety; relibc has it |
| `times` | Cache `ac_cv_func_times=no` | ✅ Cached; zsh uses `getrusage` fallback |
| `tcgetsid` | Remove obsolete cache | Cached `no` for safety; relibc has it |
| `setpgrp()` | Cache `ac_cv_func_setpgrp=no` | ✅ Cached; zsh falls back to `setpgid` |
| `killpg` | Cache `ac_cv_func_killpg=no` | ✅ Cached; zsh defines `kill(-pgrp,sig)` |
| `initgroups` | Cache if missing | ✅ Cached `no` |
| `pathconf` / `sysconf` | Cache if missing | ✅ Cached `no` |
| `RLIM_NLIMITS` | Patch if missing | ✅ Defined fallback in `rlimits.c` |
| `tgetent` / `setupterm` | Cache `yes` | ✅ Cached `yes`; linked via ncursesw |
| `dlopen` / `dlsym` | Start with `--disable-dynamic` | ✅ Static build; dynamic deferred |
| `pcre_compile` | Start without, then enable | ✅ Disabled for initial build |
| `locale` / `nl_langinfo` | `--enable-multibyte` | ✅ Enabled by default |
| `getpwnam` / `getpwuid` | Add NULL guards | ✅ Patched in `params.c` |
| `zpty` module | Disable if needed | ✅ Disabled in `zpty.c` |
| `clone` module | Disable if needed | ✅ Disabled in `clone.c` |
---
## 5. Deviations from Original Plan
| Original Plan | What Actually Happened | Reason |
|---------------|------------------------|--------|
| Use `configure` template | Used `custom` template | Needed deterministic `signames.c` generation step |
| Depend on `pcre` | No `pcre` dependency | Simpler initial build; can add later |
| `--disable-dynamic` | Implicitly static | No `--enable-dynamic` flag passed; modules are built-in |
| `--enable-zsh-mem=no` | Not needed | Default behavior uses system malloc |
| `--enable-zsh-secure-free=no` | Not needed | Default behavior is safe |
| `--with-tcsetpgrp` | Not needed | Auto-detected correctly |
| Separate `config.site` | Patches embedded in `redox.patch` | Cleaner single-file approach |
| `git` source | `tar` source with BLAKE3 | Faster fetch, reproducible builds |
---
## 6. Runtime Validation (Pending)
The following acceptance criteria have **not yet been verified** in QEMU/bare metal:
| # | Criterion | Status |
|---|-----------|--------|
| 1 | `zsh` binary compiles and links for `x86_64-unknown-redox` | ✅ Verified |
| 2 | `zsh -c 'echo hello'` runs in QEMU without crash | ⏳ Pending |
| 3 | Interactive prompt (`zsh -f`) accepts input and executes commands | ⏳ Pending |
| 4 | `ulimit`, `cd`, `echo`, `for`, `if`, `function` builtins work | ⏳ Pending |
| 5 | History file (`HISTFILE`) persists across sessions | ⏳ Pending |
| 6 | Tab completion (`zle`) functions without crash | ⏳ Pending |
| 7 | Job control (`set -m`, `fg`, `bg`, `jobs`) works | ⏳ Pending |
| 8 | PCRE module (`zsh/pcre`) loads and `=~` works | ⏳ Deferred |
| 9 | Dynamic modules load via `zmodload` | ⏳ Deferred |
| 10 | Added to `redbear-full.toml` and `redbear-mini.toml` | ✅ Done |
### 6.1 Runtime Test Commands
```bash
# Build full image
make all CONFIG_NAME=redbear-full
# Run in QEMU
make qemu CONFIG_NAME=redbear-full
# Inside QEMU:
zsh -c 'echo hello' # Basic execution
zsh -f # Interactive without user config
print -P '%n@%m %~ %# ' # Prompt expansion
for i in 1 2 3; do echo $i; done # Loop
function hello { echo "hi $1" }; hello world # Function
ulimit -a # Resource limits
bindkey # Key bindings
echo "test" > /tmp/hist; fc -R /tmp/hist # History
touch /tmp/file{A,B,C}; ls /tmp/file<TAB> # Completion
```
---
## 7. Future Work
### 7.1 Feature Expansion
| Feature | Action | Priority |
|---------|--------|----------|
| PCRE support | Add `pcre` dependency, enable `--enable-pcre` | Low |
| Dynamic modules | Enable `--enable-dynamic`, verify `dlopen` | Low |
| `zpty` module | Implement `openpty` in relibc or patch zpty | Low |
| `clone` module | Implement `clone` in relibc or keep disabled | Low |
| GDBM support | Add `gdbm` recipe, enable `--enable-gdbm` | Very Low |
### 7.2 Integration
| Task | Location | Status |
|------|----------|--------|
| Add `/usr/bin/zsh` to `/etc/shells` | `recipes/core/userutils` or `local/recipes/branding/redbear-release` | ⏳ Pending |
| `chsh` support | `recipes/core/userutils` | ⏳ Pending |
| Set zsh as default shell | `config/redbear-full.toml` `[users]` section | ⏳ Pending |
---
## 8. Files
### Created
```
recipes/shells/zsh/recipe.toml
recipes/shells/zsh/redox.patch
recipes/shells/zsh/README.md
recipes/shells/zsh/etc/zsh/zshenv
recipes/shells/zsh/etc/zsh/zprofile
recipes/shells/zsh/etc/zsh/zshrc
recipes/shells/zsh/etc/skel/.zprofile
recipes/shells/zsh/etc/skel/.zshrc
```
### Modified
```
config/redbear-full.toml
config/redbear-mini.toml
local/docs/ZSH-PORTING-PLAN.md
```
### Removed
```
recipes/wip/shells/zsh/ (entire directory)
```
---
## 9. Quick Reference
```bash
# Build zsh
CI=1 ./target/release/repo cook zsh
# Build full image with zsh
make all CONFIG_NAME=redbear-full
# Test in QEMU
make qemu CONFIG_NAME=redbear-full
# Clean and rebuild
rm -rf recipes/shells/zsh/target
CI=1 ./target/release/repo cook zsh
```
---
*Document version: 2.0 — Implementation complete*
*Last updated: 2026-04-26*