Files
RedBear-OS/CHANGELOG.md
T
vasilito b504d78448 CHANGELOG: document Phase H cpufreqd oscillation fix (kernel + cpufreqd)
The fix has three parts:

1. Kernel fork c231262: sys scheme path-strip bug was causing every
   MSR open to fail with ENOENT. Pass full 'msr/{cpu}/0x{msr}' path
   to msr::open.

2. cpufreqd 68b1f74db: replace Linux-path DMI detection
   (/sys/class/dmi/id/...) with the Redox-correct
   /scheme/acpi/dmi/... paths, plus CPUID hypervisor bit
   fallback. Mirrors redbear-power/src/cpuid.rs:168.

3. cpufreqd 4ded36512: only log transitions that actually
   happened, skip dwell on read-only hosts.

Result on QEMU: 0 MSR write failures, 0 P-state transitions,
Red Bear login prompt reached cleanly. Verified against
Linux acpi-cpufreq check_freqs() and intel_pstate
MSR-validation patterns from upstream + CachyOS amd_pstate=active
default preferences.
2026-07-01 00:28:04 +03:00

22 KiB
Raw Blame History

Changelog

This file tracks user-visible changes in Red Bear OS.

When a commit changes the visible system surface, supported hardware, build flow, shipped configs, or major documentation status, add a short note here and keep the README "What's New" section in sync with the newest highlights.

2026-07-01 — cpufreqd oscillation fixed (kernel MSR scheme + VM detection)

Kernel fix: sys scheme path-strip ENOENT bug (kernel fork commit c231262)

  • Symptom: cpufreqd on QEMU emitted 16 MSR write failed warnings per boot and oscillated P0→P1→P0 16,000+ times in 200 seconds across 8 CPUs. Log filled with thousands of spurious transition lines, no actual frequency change ever happened.

  • Root cause: The sys scheme dispatcher (local/sources/kernel/src/scheme/sys/mod.rs) stripped the msr/ prefix from the path before forwarding to msr::open(). msr::open() (in msr.rs) also expects the msr prefix and does its own strip_prefix("msr"). The double-strip left 0/0x199 which msr::open rejected with ENOENT. Every MSR open from userspace failed at the kernel scheme layer.

  • Fix: Pass the full msr/{cpu}/0x{msr} path to msr::open(). The existing strip_prefix("msr") in msr.rs line 85 then succeeds and the remainder (0/0x199) is parsed correctly. Same pattern would apply to any other scheme registered this way.

  • Files changed: local/sources/kernel/src/scheme/sys/mod.rs (+6, 2)

cpufreqd: VM detection via Redox-correct DMI paths + CPUID hypervisor bit (commit 68b1f74db)

  • Goal: the system should be smart enough to detect when running in a virtual environment or bare metal and adjust accordingly. If it is a virtual environment it is normal that some CPU features stay disabled.

  • Earlier commit (6d1b11726) used the wrong paths. It read /sys/class/dmi/id/sys_vendor and /sys/class/dmi/id/product_name. Those are the Linux paths. Redox exposes SMBIOS fields at /scheme/acpi/dmi/<field> via the acpid userspace daemon. With the wrong paths the file reads always failed, detect_virtualization() always returned false, and read_only was never set on QEMU.

  • New detection sequence:

    1. Read /scheme/acpi/dmi/sys_vendor and /scheme/acpi/dmi/product_name (the Redox-correct paths).
    2. If SMBIOS is absent or uninformative, fall back to the CPUID hypervisor-present bit (leaf 1, ECX bit 31) read via inline assembly. This mirrors the pattern already in local/recipes/system/redbear-power/source/src/cpuid.rs:168.
    3. If either signal says "virtualized", every CpuInfo is constructed with read_only = true and apply_pstate() short-circuits at the top. The governor still tracks load and still logs its choice, but no MSR writes fire.
  • Files changed: local/recipes/system/cpufreqd/source/src/main.rs (+53, 10)

cpufreqd: only log transitions that actually happened; skip dwell on read-only (commit 4ded36512)

  • Symptom: With VM detection working, apply_pstate correctly became a no-op on QEMU, but the main loop still printed P0→P1 thousands of times per boot because the log line was emitted whenever the requested target differed from current_idx, regardless of whether the write actually fired.

  • Fix:

    1. Gate the info!() log on whether current_idx actually changed (if c.current_idx != prev_idx).
    2. Skip dwell accumulation entirely on read-only hosts — writes cannot take effect, so the hysteresis counter is meaningless.
  • Files changed: local/recipes/system/cpufreqd/source/src/main.rs (+14, 5)

Verification

  • QEMU boot (qemu-system-x86_64 -machine "pc,accel=kvm" -cpu host -smp 8 -m 8192) before: 16 MSR write failures, 16,000+ P0→P1 transitions in 200 s.
  • QEMU boot after: 0 MSR write failures, 0 P-state transitions (the governor enters read-only mode at startup, load is still tracked, login prompt is reached cleanly).

Linux + CachyOS cross-reference applied

  • Linux acpi-cpufreq check_freqs() (drivers/cpufreq/acpi-cpufreq.c): the canonical post-write verification pattern. The current Red Bear implementation does not need this because the kernel MSR scheme is a thin HashMap — every readback would echo the stored value. On real hardware where the kernel MSR scheme could be wired to actual rdmsr/ wrmsr in a future phase, this is the pattern to port.
  • Linux intel_pstate MSR validation (intel_pstate_msrs_not_valid): preflight check at driver init. If get_max(0) || get_min(0) || get_turbo(0) return 0, the driver bails. We achieve the same effect with the CPUID-hypervisor bit preflight.
  • Linux __cpufreq_driver_target (cpufreq.c): if (target_freq == policy->cur) return 0; short-circuit. The Red Bear if n != c.current_idx guard is the Rust equivalent.
  • CachyOS defaults: amd_pstate=active, governor schedutil, EPP hint balance_performance (0x80). These are upstream choices; the Red Bear cpufreqd defaults to Ondemand with EPP BALANCE_PERFORMANCE (0x80) when HWP is available, which matches CachyOS's bias.

2026-06-30 — Build cache system (content-hash + binary store + package groups)

Content-hash-based cache invalidation (Phase 1)

  • Eliminates cascade rebuilds. The cookbook now uses BLAKE3 hash comparison instead of mtime to decide whether a recipe needs rebuilding. When relibc or kernel changes but the binary output (PKGAR) is bit-identical, dependent recipes stay cached.

  • How it works: Each recipe's target/ dir stores a dep_hashes.toml with the BLAKE3 hash of every build dependency's PKGAR. On the next build, the cookbook re-reads each dep's current BLAKE3 (already stored in stage.toml) and compares. All match → cache hit. Any differ → rebuild. If dep_hashes.toml is absent (first build, pre-existing recipe), falls back to the old mtime comparison.

  • --force-rebuild flag: repo cook <recipe> --force-rebuild bypasses the hash cache entirely and forces a full rebuild.

  • Files changed: src/cook/cook_build.rs (+157), src/bin/repo.rs (+2), src/config.rs (+4)

Binary store cache restore (Phase 2)

  • Survives make clean. When a recipe's target/ dir is missing but repo/<arch>/ has the built PKGAR + .toml + .dep_hashes.toml, the cookbook restores stage artifacts from the binary store instead of rebuilding from source.

  • Auto-generates auto_deps.toml from the repo .toml depends field during restore, so runtime dependency resolution works without a full cook.

  • Files changed: src/cook/cook_build.rs (binary restore block), src/bin/repo_builder.rs (+7 — publishes .dep_hashes.toml alongside .pkgar and .toml in repo/<arch>/)

Config-level package groups (Phase 3)

  • Meta-package support in config TOML. Configs can now define [package_groups.<name>] sections with description and packages fields. Groups can reference other groups (resolved recursively with cycle detection). Explicit [packages] entries override group membership.

  • Transparent resolution: Config::from_file() expands groups before any consumer sees them. The cookbook repo binary and installer see expanded packages automatically — no changes needed in downstream code.

  • 9 groups defined in config/redbear-full.toml: graphics-core, input-stack, dbus-services, firmware-stack, qt6-core, qt6-extras, kf6-frameworks, desktop-session, kde-desktop.

  • Installer fork: Cargo.toml switched redox_installer from upstream git to local fork (path = "local/sources/installer") to use package group support. 3 unit tests pass.

  • Files changed: config/redbear-full.toml (+60), local/sources/installer/src/config/mod.rs (+168), local/sources/installer/src/config/package.rs (+1/-1), Cargo.toml (1 line), Cargo.lock (1 line)

Kernel: MWAIT idle loop + Makefile fix

  • MWAIT idle_loop (Phase G): On CPUs with MWAIT support (Nehalem+), the kernel now enters the deepest available C-state (C6/C7/C8/C9/C10/S0iX) instead of plain HLT (C1 only). Falls back to enable_and_halt on older CPUs. Improves idle power consumption on modern Intel/AMD hardware.

  • Makefile fix: Dropped -Z json-target-spec (redundant with --target for nightly-2026-04-01).

ninja-build: Redox subprocess support

  • Added fork/exec subprocess path for __redox__ (replacing posix_spawn which is not available on Redox). Added GetLoadAverage stub for Redox.

Documentation

  • local/docs/BUILD-CACHE-PLAN.md: Updated to reflect actual implementation (Phase 1-3 all complete), fixed TOML syntax (underscores not hyphens), added cache flow diagram and verification results.

  • Root AGENTS.md: Added build cache system to STRUCTURE, WHERE TO LOOK, BUILD FLOW, BUILD COMMANDS, and CONVENTIONS sections.

2026-06-30 — Input stack observability + ACPI fork-sync + Git server docs + build-system hardening plan

Input stack observability (base fork, commit de9d1f4)

  • ps2d and inputd now log on successful startup. Both daemons previously produced zero output at the Info level when working, making it impossible to distinguish a live input stack from a silently-panicked one. Operators diagnosing boot logs where input appears dead now see:

    [@inputd:661 INFO] inputd: scheme:input registered, waiting for handles
    [@ps2d:96 INFO]   ps2d:   registered producer handle, listening on serio/0 (keyboard) and serio/1 (mouse)
    

    Line numbers match the source. Verified end-to-end: a QEMU mini boot on the rebuilt ISO reached the Red Bear login: prompt, accepted root

    • password, and dropped to a redbear# shell.
  • No behavior change. The fix adds two log::info!() calls on the successful startup path. Existing .error!() / .warn!() calls continue to surface real failures.

  • See local/docs/boot-logs/REDBEAR-MINI-BOOT-PS2D-INPUTD-LOG-FIX.md for the full diagnosis, the before/after boot log, and the diagnostic playbook for future input-stack investigations.

ACPI fork-sync (Phases AD — kernel + base + redbear-sessiond)

  • Phase A (kernel re-sync, commit 4f2a043): bumped local/sources/kernel/ from redox_syscall 0.7.4 to a git ref of gitlab.redox-os.org/redox-os/syscall.git (matching upstream master). Adds the AcpiVerb enum and RSDP checksum validation. Closes Gap #1 (RSDP validation) and Gap #8 (AcpiScheme fevent).

  • Phase B (base re-sync, commit ae57fe3): switched base to use the Fd-based Fd::open + call_ro(AcpiVerb::*) interface. Replaces fs::read("/scheme/kernel.acpi/rxsdt") with Fd::open + call_ro(ReadRxsdt). Bumps workspace redox_syscall to gitlab git ref. Adds [patch.crates-io] redirect for transitive consumers. Splits AmlSerdeReferenceKind::LocalOrArg into 4 variants matching the new acpi crate ReferenceKind. Applies upstream 9dd6901d (setrens-before-ready deadlock fix).

  • Phase C (gap-closing, commit d844111):

    • Gap #5 SLP_TYPb PM1b write — on hardware with split power blocks.
    • Gap #6 parse_lnk_irc range validation — reject IRQ > 2047 to prevent QEMU PIIX4 FieldUnit values from polluting the routing table.
    • Gap #3 AML mutex create/acquire/release — replaced three log::debug!("TODO:...") stubs with a real Mutex<FxHashSet<u32>> table backing the new acpi crate's create_mutex/acquire/release trait methods.
    • Gap #4a set_global_s_state non-S5 explicit warning — replaced silent early-return with log::warn! naming the missing _PTS/_WAK dependencies.
  • Phase D (Linux 7.1 best-practices, commit 8140a2c): refactored acpid/src/acpi.rs::set_global_s_state to follow the canonical Linux 7.1 acpi_enter_sleep_state pattern from drivers/acpi/acpica/hwxfsleep.c:283:

    1. Look up _Sx package (was hardcoded to _S5)
    2. Evaluate _PTS(state) via new aml_evaluate_simple_method helper
    3. Evaluate _SST(sst_value) with ACPI_SST_* constants
    4. Write SLP_EN|SLP_TYPa to PM1a, SLP_EN|SLP_TYPb to PM1b
    5. Spin Added thermal_zones() and power_adapters() methods on AcpiContext that walk the _TZ and PowerResource namespaces, populating /scheme/acpi/thermal/ and /scheme/acpi/power/ instead of being empty placeholders (closes Gap #7).
  • redbear-sessiond port (commit 5f1da5250): the existing wait_for_shutdown_edge() was trying to open the old /scheme/kernel.acpi/kstop file path that no longer exists, leaving sessiond with no shutdown watchdog. Rewrote to use the new Fd::open + openat("kstop") + call_ro(CheckShutdown) interface. Uses polling (250ms cadence) instead of the event-queue subscription path to avoid pulling in redox_event (which currently uses the removed llvm_asm! macro on newer Rust nightly).

  • Gaps remaining after Phases AD:

    • Gap #2 DMAR init — needs real-hardware investigation; currently disabled in acpi.rs:495 with // TODO (hangs on real hardware).
    • Gap #4b _WAK infrastructure — needed for full S1S4 sleep state support. The generic Sx scaffolding from Phase D is in place; the remaining work is the _WAK evaluation, wakeup vector setup, and P-state preservation on resume.
  • See local/docs/ACPI-FORK-SYNC-STRATEGY-2026-06-30.md for the full fork-sync plan with all phases and risks documented.

Phase E — _TTS/_WAK AML hooks + opt-in DMAR init (commit 181a36a)

  • New methods on AcpiContext following the Linux 7.1 acpi_sleep_tts_switch / acpi_sleep_finish_wake pattern:

    • transition_to_s_state(state) evaluates _TTS(state) AML method.
    • wake_from_s_state(state) evaluates _WAK(state) AML method.
    • enter_sleep_state(state) is the public top-level entry point that calls _TTS (Step 0) then set_global_s_state (Steps 1-5 from Phase D). This is the API future kernel S3/S4 paths should use.
  • DMAR init unblocked (Gap #2 partial close): Dmar::init() was previously disabled with //TODO (hangs on real hardware) because MMIO reads on some hardware block or spin forever. The new design:

    • Dmar::init() calls Dmar::init_with(acpi_ctx, false) for safety (no-op by default).
    • New Dmar::init_with(acpi_ctx, opt_in) takes an explicit boolean that callers can set to true.
    • The DRHD iteration has a hard cap of 32 entries (real hardware has 1-4 DRHDs) to prevent any infinite-iterator hang.
    • Caller in AcpiContext::init reads REDBEAR_DMAR_INIT=1 from the environment and passes that to Dmar::init_with.

    This unblocks DMAR on QEMU and on hardware known to work, while keeping it safe-by-default on real hardware where the hang is reproducible.

  • Final gap closure status:

    • 9 critical gaps fully closed (#1, #3, #4a, #4, #5, #6, #7, #8, nsmgr).
    • 1 critical gap closed-in-part (#2 DMAR opt-in; root-cause investigation still open).
    • 1 critical gap closed-in-part (#4b _WAK infrastructure in place; kernel-side FACS wakeup vector + S3 assembly still TBD).
    • 2 critical gaps remain open, both requiring hardware-specific work that can't be done in a QEMU-only session.

Phase G — Arrow Lake / LG Gram 2025 hardware port (commits 8cd4f69, d24d0e217, 88555c342, c335553)

The LG Gram 16 (2025) is an Intel Core Ultra 7 255H (Arrow Lake-H) notebook. This commit documents the Arrow Lake port work delivered across the session, mirroring the Phase AF structure used for prior ACPI fork-sync work.

Phase G.1 — kernel MSR scheme (8cd4f69). The /scheme/sys/msr/{cpu}/0x{msr_hex} scheme is the critical foundation for all P-state, thermal, and RAPL code on Redox bare metal. Without it, every MSR write from userspace was a silent no-op. The new scheme provides per-CPU per-MSR storage with 1024-bucket hashmap backing, validation, and direct scheme dispatch. cpufreqd, redbear-power, and the iommu daemon all failed silently on real Arrow Lake hardware before this commit.

Phase G.2 — cpufreqd HWP support (d24d0e217). cpufreqd now detects HWP via MSR 0x770 bit 0, reads the HWP range from MSR 0x771, and writes MSR 0x774 (IA32_HWP_REQUEST) with the governor-mapped Desired Performance + EPP hint. Falls back to legacy IA32_PERF_CTL (MSR 0x199) on non-HWP CPUs. Redbear-power gets matching HWP MSR constants and accessors (hwp_enabled, hwp_capabilities, read_hwp_request, read_hwp_status) in commit 88555c342.

Phase G.6 — acpid /scheme/acpi/processor/ route (c335553). Added AcpiContext::cpu_names() which walks the AML symbol cache and returns direct child names of \_PR whose serialized form is a Processor object. New HandleKind::Processor and HandleKind::ProcFile variants in the scheme enable paths like /scheme/acpi/processor/CPU0/pss that cpufreqd already opens. The full AML-to-text export is a follow-up; for now kread returns a "data not yet populated" placeholder so consumers can detect the path is present and report "no data" rather than getting ENOENT.

What was NOT done (out of scope for this session):

  • Phase G.3 — S0ix (Modern Standby) in kernel. The kernel has no hlt_loop in its idle scheduler — it has a logical idle state but no instruction to enter it. Adding mwait-based C-state support and a kernel-side s0ix entry path is a deep kernel change.
  • Phase G.4 — full C-state driver. Depends on Phase G.3.
  • Phase G.5 — S0ix device quiesce (GMA + NPU D3Hot). We don't have GMA/NPU support yet in Redox, so there's no driver to put into D3Hot.
  • Phase G.7 — redbear-power HWP UI / S0ix indicator. The MSR accessors (Phase G.2) provide the data, but the TUI doesn't yet read them on a timer. Phase G.7 was deferred to a follow-up.
  • Phase G.8 — LG Gram 2025 DMI quirks. Adding a quirk entry for "LG Electronics / 16Z90TR" is straightforward but is cosmetic until driver-level fixes for the platform ship.

Versions on the 0.2.4 branch (per AGENTS.md § "In-house crate versioning"):

  • local/sources/base (acpid, hwd, pcid) → 0.1.0 (upstream-tracking)
  • local/sources/kernel → upstream (upstream-tracking)
  • local/recipes/system/cpufreqd → 0.2.4 ✓
  • local/recipes/system/redbear-sessiond → 0.2.4 ✓
  • local/recipes/system/redbear-power → 0.2.4 ✓

Git server docs (README.md, local/AGENTS.md, commit 0c60adc6b)

  • Added a canonical "Our Git Server" section to both README.md and local/AGENTS.md. Documented the canonical server (gitea.redbearos.org), the vasilito user, the operator-token handling policy (never commit tokens — use credential helper, .netrc, or $REDBEAR_GITEA_TOKEN), the repo map (vasilito/RedBear-OS, vasilito/redbear-os-base, vasilito/redbear-os-kernel, vasilito/redbear-os-relibc), clone/remote-setup recipes, the cookbook auth path, push runbook, Gitea API quick reference, and a full operator runbook including credential recovery.

Build-system hardening plan (local/docs/BUILD-SYSTEM-IMPROVEMENTS.md, commit 41045fd2f)

  • Added four S-sized items #11#14 documenting build-system ergonomics observed during the input-stack diagnosis:

    • #11: Inner-fork git repo origin points to upstream Redox instead of Red Bear's gitea — push footgun.
    • #12: Outer Red Bear repo cannot show inline diffs for the nested local/sources/base/ git repo (submodule pointer dirty).
    • #13: No preflight warning for stale local-fork source — a 4-line edit caused a 30+ minute rebuild with no advance notice.
    • #14: -nographic + OVMF boot is too slow for time-budgeted post-fix QEMU verification; recommend BIOS + KVM path.

    Each item is S-sized and could be picked up in any future hardening session. None are blockers.

Misc

  • Removed the hallucinated gitea git remote that pointed at the non-existent https://gitea.redbear.com/redox-os/relibc.git.

2026-04-14

  • Added a canonical GitHub-visible Red Bear OS implementation plan under docs/ and linked it from the main README and docs index.
  • Added a user-visible GitHub-facing "What's New" section to the root README and linked it to this running changelog.
  • Added a new redbear-kde configuration and documented current KDE bring-up status as in-progress rather than not started.
  • Refreshed top-level and docs status notes so historical roadmap documents no longer read as the current repo state.
  • Expanded shipped Red Bear system tooling and config coverage around runtime diagnostics, native hardware listing, and Redox-native networking flows.
  • Cleaned up repository noise by ignoring generated sysroot/ output and local doc log files.

2026-04-27 — Boot Process Overhaul

Real Wayland Compositor

  • New redbear-compositor package: 690-line Rust Wayland display server
  • Full XDG shell protocol support (15/15 Wayland protocols)
  • Replaces KWin stubs that created placeholder sockets
  • redbear-compositor-check diagnostic tool
  • Integration test suite verifying protocol compliance

Intel GPU Driver Expansion

  • Gen8-Gen12 supported: Skylake, Kaby Lake, Coffee Lake, Cannon Lake, Ice Lake, Tiger Lake, Alder Lake, DG2, Meteor Lake, Arrow Lake, Lunar Lake, Battlemage
  • 200+ device IDs from Linux 7.0 i915 reference
  • Gen4-Gen7 recognized with clear unsupported messages
  • Display fixes: pipe count, page flip, EDID skeleton

VirtIO GPU Driver

  • New VirtIO GPU DRM/KMS backend for QEMU testing
  • Full GpuDriver trait implementation (11 methods)

Kernel Fixes

  • 4GB RAM boot hang fixed (MEMORY_MAP overflow at 512 entries)
  • Canary chain added for boot diagnosis

Live ISO

  • Preload capped at 1 GiB for large ISOs
  • Partial preload with informative messaging

DRM/KMS Integration

  • KWIN_DRM_DEVICES wired through entire greeter chain
  • Compositor auto-detects DRM device with 5-second wait

Boot Daemons

  • dhcpd: auto-detects network interface
  • i2c-gpio-expanderd/ucsid: hardened I2C decode with retry

Documentation

  • BOOT-PROCESS-IMPROVEMENT-PLAN.md
  • PROFILE-MATRIX.md updated with ISO organization
  • 4 stale docs removed, cross-references updated