From 06b316076f39d3f3171a6f7a327f4ea4f5ed7f00 Mon Sep 17 00:00:00 2001 From: vasilito Date: Fri, 19 Jun 2026 11:39:24 +0300 Subject: [PATCH] =?UTF-8?q?restore=20driver-manager=20+=20pcid=20service?= =?UTF-8?q?=20+=20lost=20configs=20from=200.2.3=E2=86=920.2.4=20sync?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause: the 0.2.4 upstream sync silently removed driver-manager (our in-house PCI driver orchestrator) and never added a pcid init service, leaving /scheme/pci uncreated and breaking all PCI device enumeration. Changes: - base-initfs/recipe.toml: restore driver-manager dep, binary copy, drivers.d/ config dir, set -eo pipefail - redbear-device-services.toml: add driver-manager = {} to packages - redbear-boot-stages.toml: restore from 0.2.3 (109 lines) - protected-recipes.toml: restore from 0.2.3 (99 lines) - redbear-mini.toml: add boot-stages to include chain - driver-manager Cargo.toml: fix pcid path from symlink to physical - base fork pointer: acdcb183 (adds 35_pcid.service to initfs) - UPSTREAM-SYNC-PROCEDURE.md: document sync flaw, never-delete rule, driver-manager rationale - PACKAGE-BUILD-QUIRKS.md: document pcid/pcid-spawner architecture, Redox flag values, kernel kcall on AcpiScheme Verified: redbear-mini boots to login prompt in QEMU UEFI with working PCI enumeration (6 devices), e1000d network driver, DHCP, driver-manager. --- config/protected-recipes.toml | 99 ++++++++++++++++ config/redbear-boot-stages.toml | 109 ++++++++++++++++++ config/redbear-device-services.toml | 1 + config/redbear-mini.toml | 2 +- local/docs/PACKAGE-BUILD-QUIRKS.md | 93 +++++++++++++++ local/docs/UPSTREAM-SYNC-PROCEDURE.md | 75 ++++++++++++ .../recipes/system/driver-manager/Cargo.toml | 2 +- .../system/driver-manager/source/Cargo.toml | 2 +- local/sources/base | 2 +- recipes/core/base-initfs/recipe.toml | 8 +- scripts/run_mini.sh | 3 + 11 files changed, 391 insertions(+), 5 deletions(-) create mode 100644 config/protected-recipes.toml create mode 100644 config/redbear-boot-stages.toml create mode 100755 scripts/run_mini.sh diff --git a/config/protected-recipes.toml b/config/protected-recipes.toml new file mode 100644 index 0000000000..cd35177cbf --- /dev/null +++ b/config/protected-recipes.toml @@ -0,0 +1,99 @@ +# Protected recipes — these recipes are NEVER re-fetched from upstream. +# They use offline/archived sources from sources/redbear-/. +# +# Protection reasons: +# - patched: carries Red Bear patches (upstream changes could break patches) +# - custom: Red Bear-specific recipe (no upstream equivalent) +# - core: core system component (kernel, libc, bootloader, etc.) +# +# The Rust code in src/cook/fetch.rs reads this file at startup. +# Recipes NOT listed here but carrying patches (patches = [...] in recipe.toml) +# are automatically protected by the recipe_has_patches() check. + +# Core patched recipes (upstream + Red Bear patches) +[patched] +recipes = [ + "relibc", "bootloader", "kernel", "base", "base-initfs", + "installer", "redoxfs", "grub", +] + +# Red Bear custom core recipes +[custom] +recipes = [ + "ext4d", "fatd", +] + +# Red Bear driver infrastructure +[drivers] +recipes = [ + "redox-driver-sys", "linux-kpi", "firmware-loader", + "redbear-btusb", "redbear-iwlwifi", + "redox-drm", "amdgpu", +] + +# Red Bear system tools +[system] +recipes = [ + "cub", "evdevd", "udev-shim", "iommu", + "redbear-firmware", "redbear-hwutils", "redbear-info", "rbos-info", + "redbear-meta", "redbear-netctl", "redbear-netctl-console", + "redbear-netstat", "redbear-btctl", "redbear-wifictl", + "redbear-traceroute", "redbear-mtr", "redbear-nmap", + "redbear-sessiond", "redbear-authd", "redbear-session-launch", + "redbear-greeter", "redbear-dbus-services", "redbear-notifications", + "redbear-upower", "redbear-udisks", "redbear-polkit", "redbear-quirks", + "redbear-release", "redbear-keymapd", "redbear-ime", "redbear-accessibility", +] + +# Qt stack with Red Bear patches +[qt] +recipes = [ + "qtbase", "qtwayland", "qtdeclarative", "qtbase-compat", +] + +# Graphics / display stack with Red Bear patches +[graphics] +recipes = [ + "libdrm", "mesa", + "libwayland", "libevdev", "libinput", + "libepoxy", "libxcvt", "libdisplay-info", "lcms2", + "dbus", "glib", +] + +# Red Bear custom libs (no stubs) +[libs] +recipes = [ + "zbus", "libqrencode", + "pipewire", "wireplumber", +] + +# Red Bear Wayland +[wayland] +recipes = [ + "qt6-wayland-smoke", "smallvil", "seatd-redox", +] + +# Red Bear KDE (47 recipes) +[kde] +recipes = [ + "kf6-extra-cmake-modules", "kf6-kcoreaddons", "kf6-kwidgetsaddons", + "kf6-kconfig", "kf6-ki18n", "kf6-kcodecs", "kf6-kguiaddons", + "kf6-kcolorscheme", "kf6-kauth", "kf6-kitemmodels", "kf6-kitemviews", + "kf6-karchive", "kf6-kwindowsystem", "kf6-knotifications", + "kf6-kjobwidgets", "kf6-kconfigwidgets", "kf6-kcrash", "kf6-kdbusaddons", + "kf6-kglobalaccel", "kf6-kservice", "kf6-kpackage", "kf6-kiconthemes", + "kf6-kxmlgui", "kf6-ktextwidgets", "kf6-solid", "kf6-sonnet", + "kf6-kio", "kf6-kbookmarks", "kf6-kcompletion", "kf6-kdeclarative", + "kf6-kcmutils", "kf6-kidletime", "kf6-kwayland", "kf6-knewstuff", + "kf6-kwallet", "kf6-prison", "kf6-kirigami", + "kf6-ksvg", "kf6-pty", "kf6-notifyconfig", "kf6-parts", + "kdecoration", "kwin", "plasma-desktop", "plasma-workspace", + "plasma-framework", "plasma-wayland-protocols", "kirigami", + "kglobalacceld", +] + +# Orbutils (has local patch) +[other] +recipes = [ + "orbutils", +] diff --git a/config/redbear-boot-stages.toml b/config/redbear-boot-stages.toml new file mode 100644 index 0000000000..112b21851a --- /dev/null +++ b/config/redbear-boot-stages.toml @@ -0,0 +1,109 @@ +# Red Bear OS boot stage targets +# +# Semantic boot stages that create ordering through the init system's +# BFS dependency traversal. Each target depends on the previous one. +# +# Stage mapping: +# 00_base.target — kernel schemes ready (defined in base package initfs) +# 02_early_hw.target — ACPI + PCI bus access ready +# 04_drivers.target — driver spawning complete +# 06_services.target — system services (D-Bus, session broker) +# 08_userland.target — user-facing (console, greeter, desktop) +# +# Services use requires_weak against their stage target. +# Targets use requires_weak to chain to the previous stage. +# +# Serial boot markers (02-08_serial_*.service) echo a stage completion +# message to stderr, which appears on the serial console for diagnostics. + +[[files]] +path = "/etc/init.d/02_early_hw.target" +data = """ +[unit] +description = "Early hardware: ACPI + PCI bus access" +requires_weak = [ + "00_base.target", +] +""" + +[[files]] +path = "/etc/init.d/02_serial_early_hw.service" +data = """ +[unit] +description = "Serial boot marker: early hardware stage" +requires_weak = ["02_early_hw.target"] + +[service] +cmd = "echo" +args = ["RB_STAGE_02_EARLY_HW"] +type = "oneshot" +""" + +[[files]] +path = "/etc/init.d/04_drivers.target" +data = """ +[unit] +description = "Driver spawning stage" +requires_weak = [ + "02_early_hw.target", +] +""" + +[[files]] +path = "/etc/init.d/04_serial_drivers.service" +data = """ +[unit] +description = "Serial boot marker: drivers stage" +requires_weak = ["04_drivers.target"] + +[service] +cmd = "echo" +args = ["RB_STAGE_04_DRIVERS"] +type = "oneshot" +""" + +[[files]] +path = "/etc/init.d/06_services.target" +data = """ +[unit] +description = "System services: D-Bus, session broker, seat management" +requires_weak = [ + "04_drivers.target", +] +""" + +[[files]] +path = "/etc/init.d/06_serial_services.service" +data = """ +[unit] +description = "Serial boot marker: services stage" +requires_weak = ["06_services.target"] + +[service] +cmd = "echo" +args = ["RB_STAGE_06_SERVICES"] +type = "oneshot" +""" + +[[files]] +path = "/etc/init.d/08_userland.target" +data = """ +[unit] +description = "User-facing: console, greeter, desktop" +requires_weak = [ + "06_services.target", +] +""" + +[[files]] +path = "/etc/init.d/08_serial_userland.service" +data = """ +[unit] +description = "Serial boot marker: userland stage" +requires_weak = ["08_userland.target"] + +[service] +cmd = "echo" +args = ["RB_STAGE_08_USERLAND"] +type = "oneshot" +""" diff --git a/config/redbear-device-services.toml b/config/redbear-device-services.toml index 5412757645..887ef58bca 100644 --- a/config/redbear-device-services.toml +++ b/config/redbear-device-services.toml @@ -6,6 +6,7 @@ redbear-quirks = {} pciids = {} fatd = {} +driver-manager = {} # Firmware fallback chain configs [[files]] diff --git a/config/redbear-mini.toml b/config/redbear-mini.toml index d821662081..36e17db0ad 100644 --- a/config/redbear-mini.toml +++ b/config/redbear-mini.toml @@ -9,7 +9,7 @@ # - all non-graphics, non-firmware packages from the full profile # - no linux-firmware payload, no firmware-loader, no GPU/display drivers -include = ["minimal.toml", "redbear-legacy-base.toml", "redbear-netctl.toml", "redbear-device-services.toml"] +include = ["minimal.toml", "redbear-legacy-base.toml", "redbear-netctl.toml", "redbear-device-services.toml", "redbear-boot-stages.toml"] [general] filesystem_size = 1536 diff --git a/local/docs/PACKAGE-BUILD-QUIRKS.md b/local/docs/PACKAGE-BUILD-QUIRKS.md index 2513b2e96a..abff40062a 100644 --- a/local/docs/PACKAGE-BUILD-QUIRKS.md +++ b/local/docs/PACKAGE-BUILD-QUIRKS.md @@ -378,6 +378,99 @@ When you encounter a new build quirk: --- +## Package: base-initfs (initfs image builder) + +### pcid Must Start Before pcid-spawner + +**Problem:** `pcid-spawner` calls `fs::read_dir("/scheme/pci")` as its first +action. `/scheme/pci` is created by `pcid` via `register_sync_scheme()`. If +`pcid` is not started, `pcid-spawner` fails with `ENODEV`. + +**Root cause:** No init service started `pcid` in initfs. The upstream model +assumed `pcid` would be started, but no `.service` file existed for it. This +was masked in 0.2.3 because `driver-manager` (Red Bear's replacement) does +its own PCI enumeration via `redox_driver_pci` and doesn't depend on +`/scheme/pci`. + +**Fix:** Added `35_pcid.service` to `init.initfs.d/`: +```ini +[unit] +description = "PCI bus enumeration daemon (creates /scheme/pci)" +requires_weak = ["30_acpid.service"] + +[service] +cmd = "pcid" +type = { scheme = "pci" } +``` + +The `type = { scheme = "pci" }` tells init to wait for `/scheme/pci` to be +registered before marking the service as started. This ensures `pcid-spawner` +(which depends on `35_pcid.service` via `requires_weak`) only runs after +`/scheme/pci` exists. + +### driver-manager Removed During Sync + +**Problem:** The 0.2.3 → 0.2.4 upstream sync silently removed `driver-manager` +from `base-initfs` dependencies and `redbear-device-services.toml` packages. + +**Root cause:** Upstream doesn't have `driver-manager` — it's a Red Bear +in-house project. The sync blindly overwrote tracked files with upstream +versions. + +**Fix:** Restored: +- `"driver-manager"` in `base-initfs/recipe.toml` dependencies +- `cp driver-manager` binary copy to initfs/bin/ +- `driver-manager = {}` in `redbear-device-services.toml` `[packages]` +- `drivers.d/` config directory creation in build script +- `set -eo pipefail` in build script + +**See also:** `UPSTREAM-SYNC-PROCEDURE.md` § "driver-manager: Upstream Not Ready" + +--- + +## Redox Flag Values (Critical for Ported Code) + +Redox flag values differ from Linux. Code ported from Linux that assumes +Linux conventions will be WRONG on Redox: + +| Flag | Linux | Redox | +|------|-------|-------| +| `O_RDONLY` | `0` | `0x0001_0000` | +| `O_WRONLY` | `1` | `0x0002_0000` | +| `O_RDWR` | `2` | `0x0003_0000` | +| `O_ACCMODE` | `3` | `0x0003_0000` | +| `O_CLOEXEC` | `0x80000` | `0x0100_0000` | + +**Common bug:** `flags & O_ACCMODE == O_RDONLY` evaluates to `0 == 0` on Linux +(read-only check passes), but on Redox `O_CLOEXEC & O_ACCMODE = 0 ≠ O_RDONLY`, +so a file opened with `O_CLOEXEC` without explicit `O_RDONLY` fails with `EROFS`. + +**Fix:** Always pass `O_RDONLY` explicitly when opening for read: +```rust +let fd = Fd::open(path, O_RDONLY | O_CLOEXEC, 0)?; +``` + +### Kernel kcall on ACPI Scheme + +**Problem:** Upstream-synced `acpid` uses `AcpiVerb` call API (`ReadRxsdt=1`, +`CheckShutdown=2`) but the kernel's `AcpiScheme` didn't implement `kcall`, +returning `EOPNOTSUPP`. + +**Fix:** Added `kcall` method to `impl KernelScheme for AcpiScheme` in +`src/scheme/acpi.rs`. The kernel fork commit is `c7af6c43`. + +**Signature:** +```rust +fn kcall(&self, fds: &[usize], payload: UserSliceRw, flags: CallFlags, + metadata: &[u64], token: &mut CleanLockToken) -> Result +``` + +- `fds[0]` = handle id +- `metadata[0]` = verb (u64): `1` = ReadRxsdt, `2` = CheckShutdown +- `payload` = UserSliceRw (read/write buffer) + +--- + ## Cross-Reference | Document | Relevance | diff --git a/local/docs/UPSTREAM-SYNC-PROCEDURE.md b/local/docs/UPSTREAM-SYNC-PROCEDURE.md index 8589389ca7..b6f6d348e3 100644 --- a/local/docs/UPSTREAM-SYNC-PROCEDURE.md +++ b/local/docs/UPSTREAM-SYNC-PROCEDURE.md @@ -684,3 +684,78 @@ relibc, and installer from `build-redbear.sh`. Only bootloader (which uses `git + patches`, not `path=`) still gets `apply_patch_dir`. **Verification:** Kernel source hashes now identical before and after build. + +--- + +## CRITICAL: Red Bear Package Preservation Rules + +### Never Delete — Comment Out + +When syncing with upstream removes or restructures packages, configs, or +services that are Red Bear in-house projects: + +1. **NEVER delete** the package, config, or service entry. +2. **Comment it out** with a clear explanation of why. +3. **ASK THE USER** if uncertain whether to keep or remove. + +This applies to: +- Packages in `[packages]` sections of config TOMLs +- Dependencies in `recipe.toml` files +- Init service files (`.service`, `.target`) +- Build system patches and scripts +- Any file under `local/` or `config/redbear-*` + +### driver-manager: Upstream Not Ready + +**Status:** Red Bear internal project. Upstream Redox does NOT have an equivalent. + +`driver-manager` (`local/recipes/system/driver-manager/`) is a combined PCI +enumeration + driver matching + hotplug daemon that replaces the upstream +`pcid + pcid-spawner` pair. It was developed because upstream's PCI driver +launching was not ready for Red Bear's needs (advanced driver matching via +`/lib/drivers.d/*.toml`, ACPI device enumeration, hotplug event handling). + +**Upstream may provide its own solution in the future.** If and when upstream +Redox offers a concrete, working replacement that matches or exceeds +driver-manager's capabilities, notify the user for a route decision. + +Until then, `driver-manager` is the canonical PCI driver orchestration path. + +### Systemic Sync Flaw (2026-06 Incident) + +**Root cause:** The 0.2.3 → 0.2.4 upstream sync blindly overwrote tracked +config and recipe files. Red Bear in-house packages, services, and configs +were silently dropped because upstream doesn't have them. + +**What was lost (partial list):** +- `driver-manager` removed from base-initfs dependencies and packages +- `config/protected-recipes.toml` deleted (99 lines of protection rules) +- `config/redbear-boot-stages.toml` deleted (109 lines of boot stage targets) +- `set -eo pipefail` removed from base-initfs build script +- `drivers.d/` initfs config directory creation removed +- Multiple patches lost (libdrm, mesa, pipewire, sddm, wireplumber) +- `local/recipes/AGENTS.md` deleted + +**Prevention:** Before ANY upstream sync: +1. Run `git diff` between the pre-sync and post-sync tree. +2. Flag ALL removed files, especially under `config/`, `local/`, and `recipes/`. +3. Flag ALL removed entries from `[packages]` sections and dependency arrays. +4. Cross-reference with `config/protected-recipes.toml` — protected recipes + must NEVER be removed. +5. Any removal must be explicitly approved by the user. + +### pcid + pcid-spawner Architecture + +**Upstream model:** +1. `pcid` creates `/scheme/pci` (PCI bus enumeration) +2. `pcid-spawner` reads `/scheme/pci` and launches drivers per `pcid.d/*.toml` + +**Red Bear model (0.2.3 and forward):** +1. `pcid` creates `/scheme/pci` (initfs service `35_pcid.service`) +2. `pcid-spawner --initfs` launches critical boot drivers (initfs) +3. `driver-manager --hotplug` handles full driver matching + hotplug (rootfs) + +**Key learning:** Without `35_pcid.service` in initfs, `/scheme/pci` is never +created, and BOTH `pcid-spawner` (initfs and rootfs) fail with ENODEV. This +was masked in 0.2.3 because driver-manager does its own PCI enumeration via +`redox_driver_pci` and doesn't depend on `/scheme/pci`. diff --git a/local/recipes/system/driver-manager/Cargo.toml b/local/recipes/system/driver-manager/Cargo.toml index b3233faaff..bea61f138f 100644 --- a/local/recipes/system/driver-manager/Cargo.toml +++ b/local/recipes/system/driver-manager/Cargo.toml @@ -11,7 +11,7 @@ path = "src/main.rs" [dependencies] redox-driver-core = { path = "../../drivers/redox-driver-core" } redox-driver-pci = { path = "../../drivers/redox-driver-pci" } -pcid_interface = { path = "../../../../recipes/core/base/source/drivers/pcid", package = "pcid" } +pcid_interface = { path = "../../../../local/sources/base/drivers/pcid", package = "pcid" } redox_syscall = "0.7" log = "0.4" toml = "0.8" diff --git a/local/recipes/system/driver-manager/source/Cargo.toml b/local/recipes/system/driver-manager/source/Cargo.toml index a7515c4c0e..6c8cee5381 100644 --- a/local/recipes/system/driver-manager/source/Cargo.toml +++ b/local/recipes/system/driver-manager/source/Cargo.toml @@ -11,7 +11,7 @@ path = "src/main.rs" [dependencies] redox-driver-core = { path = "../../../drivers/redox-driver-core/source" } redox-driver-pci = { path = "../../../drivers/redox-driver-pci/source" } -pcid_interface = { path = "../../../../../recipes/core/base/source/drivers/pcid", package = "pcid" } +pcid_interface = { path = "../../../../../local/sources/base/drivers/pcid", package = "pcid" } redox-scheme = "0.11" syscall = { package = "redox_syscall", version = "0.8" } log = "0.4" diff --git a/local/sources/base b/local/sources/base index 7766fb91f3..acdcb183cd 160000 --- a/local/sources/base +++ b/local/sources/base @@ -1 +1 @@ -Subproject commit 7766fb91f3b1ea23f960969dc4ea7087778410a2 +Subproject commit acdcb183cd1b191ead18ea74bc5b0e61a2b6a72c diff --git a/recipes/core/base-initfs/recipe.toml b/recipes/core/base-initfs/recipe.toml index 717e2c2a29..19f21c5835 100644 --- a/recipes/core/base-initfs/recipe.toml +++ b/recipes/core/base-initfs/recipe.toml @@ -6,8 +6,11 @@ template = "custom" dependencies = [ "redoxfs", "ion", + "driver-manager", ] script = """ +set -eo pipefail + BINS=( init logd @@ -71,8 +74,10 @@ mkdir -p "${COOKBOOK_BUILD}/initfs/lib/init.d" cp "${COOKBOOK_SOURCE}/init.initfs.d"/* "${COOKBOOK_BUILD}/initfs/lib/init.d/" +mkdir -pv "${COOKBOOK_BUILD}/initfs/lib/drivers.d" +cp -v "${COOKBOOK_SOURCE}/drivers/initfs-storage.toml" "${COOKBOOK_BUILD}/initfs/lib/drivers.d/00-storage.toml" mkdir -pv "${COOKBOOK_BUILD}/initfs/lib/pcid.d" -cp -v "${COOKBOOK_SOURCE}/drivers/initfs.toml" "${COOKBOOK_BUILD}/initfs/lib/pcid.d/initfs.toml" +cp -v "${COOKBOOK_SOURCE}/drivers/initfs-pcid-storage.toml" "${COOKBOOK_BUILD}/initfs/lib/pcid.d/00-storage.toml" export CARGO_PROFILE_RELEASE_OPT_LEVEL=s export CARGO_PROFILE_RELEASE_PANIC=abort @@ -96,6 +101,7 @@ done cp "${COOKBOOK_SYSROOT}/usr/bin/redoxfs" "${COOKBOOK_BUILD}/initfs/bin" cp "${COOKBOOK_SYSROOT}/usr/bin/ion" "${COOKBOOK_BUILD}/initfs/bin" +cp "${COOKBOOK_SYSROOT}/usr/bin/driver-manager" "${COOKBOOK_BUILD}/initfs/bin" ARCH="$(echo "${GNU_TARGET}" | cut -d - -f1)" RUSTFLAGS="$RUSTFLAGS -Ctarget-feature=+crt-static -Clink-arg=-nostartfiles -Clink-arg=-nostdlib" cargo \ diff --git a/scripts/run_mini.sh b/scripts/run_mini.sh new file mode 100755 index 0000000000..9f131b156f --- /dev/null +++ b/scripts/run_mini.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +qemu-system-x86_64 -m 8G -drive if=pflash,format=raw,readonly=on,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd -drive file=/home/kellito/Builds/rbos/build/x86_64/redbear-mini.iso,format=raw -device virtio-gpu-pci -serial mon:stdio