5cde25495c
Per local/AGENTS.md § SINGLE-REPO RULE: the Red Bear OS project lives in exactly one git repository (vasilito/RedBear-OS). Per-component Gitea mirrors (redbear-os-base, redbear-os-kernel, redbear-os-installer, redox-drm, userutils, libredox, libpciaccess, ctrlc, syscall, sysinfo) have been redirected or deleted. For each per-component repo with source content, the working-tree HEAD was pushed as a 'submodule/<component>' branch on RedBear-OS: - submodule/base - submodule/bootloader - submodule/installer - submodule/kernel - submodule/libredox - submodule/redoxfs - submodule/relibc - submodule/syscall - submodule/userutils The .gitmodules entry for local/sources/kernel is now redirected to the canonical repo with branch = submodule/kernel. The other submodule .gitmodules entries remain to be added in a follow-up. Empty per-component repos (ctrlc, libpciaccess, redox-drm, sysinfo) had no source content; their gitlinks in the index are removed in a follow-up commit. Unrelated per-component repos that were not Red Bear components (ctrlc, syscall, sysinfo — possibly unrelated personal projects) were deleted in the bulk cleanup. Gitea state under vasilito/ is now exactly: RedBear-OS, hiperiso. Adds: - local/scripts/redirect-to-submodules.sh - local/scripts/delete-per-component-repos.sh Updates: - .gitmodules (kernel → RedBear-OS#submodule/kernel) - local/AGENTS.md (SINGLE-REPO RULE status, migration procedure) - local/docs/BUILD-SYSTEM-IMPROVEMENTS.md §11 (resolved) - local/docs/QUIRKS-AUDIT.md (drop dead links) - local/docs/SLEEP-IMPLEMENTATION-PLAN.md (mark historical) - CHANGELOG.md (mark historical references)
742 lines
35 KiB
Markdown
742 lines
35 KiB
Markdown
# 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 — Phase I/II complete: full s2idle + S3 entry + LG Gram DMI
|
||
|
||
### Phase I.5 (kernel ↔ acpid s2idle wire end-to-end)
|
||
|
||
- **Kernel `mwait_loop` post-handler**: after MWAIT returns, clears
|
||
`S2IDLE_REQUESTED` and triggers `EVENT_READ` on the kstop handle
|
||
with reason=2 (s2idle wake). Mirrors Linux 7.1
|
||
`acpi_s2idle_wake` in `drivers/acpi/sleep.c:758`.
|
||
- **Kernel `kstop` reason codes** (Phase I.5): `KSTOP_FLAG` is now
|
||
a `u8` with 0=idle, 1=shutdown (S5), 2=s2idle wake, 3=s3 wake.
|
||
`kstop_set_reason()` and the `CheckShutdown` AcpiVerb return the
|
||
reason. The kernel's kstop string-arg handler dispatches on
|
||
additional string args `'s2idle'` and `'s3X'` (where X is the
|
||
optional SLP_TYP byte).
|
||
- **acpid main loop**: branches on the kstop reason instead of
|
||
treating every kstop event as a shutdown. Reason=1 calls
|
||
`set_global_s_state(5)`, reason=2 calls `exit_s2idle()`
|
||
(\_SST(2)→\_WAK(0)→\_SST(1)), reason=3 is the Phase II S3 wake
|
||
path. `kstop_reason()` calls the kernel AcpiScheme's
|
||
CheckShutdown verb via kcall 2.
|
||
- **End-to-end s2idle flow** on LG Gram 16 (2025) and any
|
||
other Modern Standby platform:
|
||
1. acpid: `enter_s2idle()` (\_TTS(0), \_PTS(0), \_SST(3))
|
||
2. acpid: write `'s2idle'` to /scheme/sys/kstop
|
||
3. kernel kstop handler: sets S2IDLE_REQUESTED, returns
|
||
4. kernel idle path: `mwait_loop()` at deepest C-state
|
||
5. SCI breaks MWAIT
|
||
6. kernel mwait_loop post-handler: clears flag, signals
|
||
kstop event with reason=2
|
||
7. acpid: `kstop_reason()` returns 2
|
||
8. acpid: `exit_s2idle()` (\_SST(2)→\_WAK(0)→\_SST(1))
|
||
9. loop
|
||
|
||
### Phase II (S3 entry path)
|
||
|
||
- **Kernel FADT parser** (`acpi/fadt.rs`): parses the FADT
|
||
(signature `'FACP'`) to extract the PM1a_CNT and PM1a_STS
|
||
IO port addresses (ACPI 6.5 §5.2.9 / Table 5.6). 32-bit
|
||
General-Purpose Event Register Block 0 Addresses.
|
||
- **Kernel S3 entry** (`arch/x86_shared/stop.rs::enter_s3`):
|
||
hardware-agnostic S3 entry path mirroring Linux 7.1
|
||
`acpi_hw_legacy_sleep` in
|
||
`drivers/acpi/acpica/hwsleep.c:81-127`. Sequence:
|
||
1. clear WAK_STS (bit 15 of PM1a_STS)
|
||
2. flush CPU caches (wbinvd)
|
||
3. write SLP_TYP to PM1a_CNT
|
||
4. write SLP_TYP|SLP_EN to PM1a_CNT (split-write for
|
||
hardware compat)
|
||
5. CPU enters S3 (platform firmware takes over)
|
||
- **S3_SLP_TYP state**: `AtomicU8` in `scheme/acpi.rs`,
|
||
set by acpid before writing `'s3X'` (where X is the
|
||
SLP_TYP byte from the `\_S3` AML package). Default
|
||
SLP_TYP=5 (standard for x86 systems). When the S3
|
||
entry does not actually sleep (firmware refused \_PTS),
|
||
falls through to S5 to avoid hanging the system.
|
||
- **Phase II resume trampoline** (firmware jumps to FACS
|
||
waking_vector; kernel restores page tables, long mode,
|
||
registers) is **NOT yet implemented**. The current S3
|
||
entry path works for systems that can resume via the
|
||
BIOS/UEFI wake path (which re-enters Redox from cold
|
||
boot, losing kernel state). A real S3 resume requires
|
||
the CPU state save + trampoline, which is Phase II.X
|
||
(deferred).
|
||
- **Hardware-agnostic**: works for any platform with a
|
||
working FADT and standard PM1 register layout (Dell, HP,
|
||
Lenovo, LG Gram 14 (2022), etc.). Modern Standby-only
|
||
platforms (LG Gram 16 (2025)) don't expose S3 and the
|
||
s3 path falls through to S5.
|
||
|
||
### Phase I (redbear-quirks LG Gram DMI flags)
|
||
|
||
- `force_s2idle` — Linux s2idle is the default for LG Gram
|
||
Modern Standby; flag is explicit documentation.
|
||
- `acpi_irq1_skip_override` — Linux `drivers/acpi/resource.c`
|
||
`irq1_level_low_skip_override[]` (lines 522-534). Without
|
||
this the ACPI core rewrites the DSDT's ActiveLow to
|
||
ActiveHigh and the i8042 keyboard IRQ stops firing.
|
||
- `kbd_deactivate_fixup` — Linux `drivers/input/keyboard/atkbd.c`
|
||
line 1913-1917. Prevents spurious keyboard ACK / dropped
|
||
keys.
|
||
- `no_legacy_pm1b` — Red Bear OS specific. LG firmware does
|
||
not implement a separate PM1b_CNT register; tells acpid
|
||
to skip the SLP_TYPb write path.
|
||
|
||
### Phase J (deferred: libredox fork + syscall extension)
|
||
|
||
- The `AcpiVerb::EnterS2Idle` and `ExitS2Idle` extensions
|
||
for the syscall crate are written as a durable overlay
|
||
patch at `local/patches/syscall/P1-acpiverb-enter-exit-s2idle.patch`.
|
||
Applied to a local fork of `redox_syscall` at
|
||
`local/sources/syscall/`. NOT yet wired into the
|
||
base/kernel `Cargo.toml` `[patch.crates-io]` because
|
||
`libredox = "0.1.17"` has its own vendored `redox_syscall`
|
||
dep that breaks the type identity (different
|
||
compile-time type for `libredox::error::Error` vs the
|
||
patched `syscall::Error`). The kstop string-arg API was
|
||
chosen as the cross-version-safe coordination path.
|
||
|
||
### Build artifacts
|
||
|
||
- `build/x86_64/redbear-mini.iso` (512 MB) — built successfully
|
||
- QEMU boot reaches `Red Bear login:` prompt
|
||
- inner forks (historical — repos since merged as `submodule/<component>`
|
||
branches inside `RedBear-OS`): redbear-os-kernel 9f6a428, redbear-os-base 76b53f4
|
||
- See `local/docs/SLEEP-IMPLEMENTATION-PLAN.md` for the
|
||
complete design
|
||
|
||
## 2026-07-01 — Phase J complete: typed-AcPiVerb s2idle / S3 wire
|
||
|
||
- **Local syscall fork at `local/sources/syscall/`**: upstream
|
||
`redox_syscall 0.8.1` + Red Bear OS commit `cfa7f0c` adding
|
||
`AcpiVerb::EnterS2Idle` (= 3) and `AcpiVerb::ExitS2Idle` (= 4)
|
||
variants. The version field stays at upstream 0.8.1 per the
|
||
AGENTS.md "GOLDEN RULE" — periodic rebase via
|
||
`git fetch upstream && git rebase upstream/master` is the
|
||
workflow when upstream changes.
|
||
- **Local libredox fork at `local/sources/libredox/`**: upstream
|
||
`libredox 0.1.17` with the `redox_syscall` dep redirected
|
||
to `path = "../syscall"`. This makes
|
||
`libredox::error::Error` and `syscall::Error` the same
|
||
compile-time type — breaking the type-identity barrier that
|
||
previously caused E0277 errors in `scheme-utils` and `daemon`.
|
||
- **base `Cargo.toml`**: `[patch.crates-io] libredox = { path = "../libredox" }`
|
||
wires the local libredox fork. The existing
|
||
`[patch.crates-io] redox_syscall = { path = "../syscall" }`
|
||
is redundant (the base's workspace.dependencies already uses
|
||
the local path).
|
||
- **kernel `Cargo.toml`**: `[workspace] members = [".", "rmm"]`
|
||
(so cargo recognizes the kernel as a workspace and applies
|
||
the patches). `[patch."https://gitlab.redox-os.org/redox-os/syscall.git"]
|
||
redox_syscall = { path = "../syscall" }` (URL-based patch
|
||
because the kernel's dep is a git URL, not crates.io).
|
||
`[patch.crates-io] libredox = { path = "../libredox" }`.
|
||
- **Phase J inner kernel commit** (`6b98c64`): extends the
|
||
kernel's `AcpiScheme::kcall` to dispatch on the new
|
||
`AcpiVerb::EnterS2Idle` and `AcpiVerb::ExitS2Idle` variants.
|
||
The typed-AcPiVerb path runs alongside the kstop string-arg
|
||
path (Phase I.5); both are functional.
|
||
- **Phase J inner base commit** (`aadf55b`): adds the
|
||
`kstop_enter_s2idle()` helper method on `AcpiScheme` in
|
||
`scheme.rs` that wraps the typed-AcPiVerb kcall. The acpid
|
||
main loop can call this directly.
|
||
- **Patch file**: `local/patches/syscall/P1-acpiverb-enter-exit-s2idle.patch`
|
||
is the durable overlay patch backing the syscall fork
|
||
commit. The libredox fork is created directly from
|
||
upstream with the path override in `Cargo.toml.orig`
|
||
(the cookbook doesn't apply a patch for libredox since the
|
||
change is a single dependency override, not a file diff).
|
||
- **Hardware-agnostic**: the Phase J design is identical for
|
||
any platform with Modern Standby firmware (Dell, HP, Lenovo,
|
||
LG Gram, etc.).
|
||
- **Build verification**: `redbear-mini.iso` (512 MB) builds
|
||
successfully with all Phase J commits. The patch system
|
||
works end-to-end.
|
||
|
||
## 2026-07-01 — Phase II.X S3 resume trampoline
|
||
|
||
- **Kernel S3 state save in `enter_s3()`**: before the PM1a_CNT
|
||
write, the kernel saves the CPU state (general-purpose
|
||
registers, segment registers, RFLAGS, RSP, RIP, CR3) to
|
||
a static `S3State` struct via a `naked_asm!` block. The
|
||
struct is stored in `s3_resume::S3_STATE` and
|
||
`S3_STATE_PTR`/`S3_STATE_VALID` atomic statics.
|
||
- **Kernel S3 resume trampoline** (`s3_resume::s3_trampoline`):
|
||
a 64-bit `naked_asm!` block that runs when the platform
|
||
firmware jumps to FACS.waking_vector on S3 wake. Mirrors
|
||
Linux 7.1 `arch/x86/kernel/acpi/wakeup_64.S`:
|
||
- Checks the magic value (0x123456789abcdef0) in
|
||
S3_STATE.saved_magic. If zero (cold boot), halts.
|
||
- Restores segment registers to __KERNEL_DS.
|
||
- Restores CR3 (page table base).
|
||
- Restores RSP, RFLAGS, 13 general-purpose registers.
|
||
- Sets the RESUMING_FROM_S3 flag.
|
||
- Pushes saved RIP onto the stack and uses `ret`.
|
||
- **Kernel exposes `s3_resume_address()`** that acpid writes
|
||
to FACS.waking_vector via the kernel AcpiScheme.
|
||
- **Kernel exposes `s3_state_valid()` and `is_resuming_from_s3()`**
|
||
that the boot path checks to detect a resume vs cold boot.
|
||
- **Hardware-agnostic**: works on any x86_64 system with
|
||
standard ACPI S3 support (Dell, HP, Lenovo, LG Gram 14).
|
||
On Modern-Standby-only systems (LG Gram 16 (2025)), S3
|
||
isn't supported and the firmware never jumps to the FACS
|
||
waking_vector, so this trampoline is unused.
|
||
- **Build**: redbear-mini.iso (512 MB) builds successfully.
|
||
The S3 resume path is verified to compile and be present
|
||
in the ISO. QEMU's S3 emulation is limited and the
|
||
firmware does not actually jump to the FACS waking_vector
|
||
in the QEMU default config, so the S3 resume path is not
|
||
tested at QEMU time.
|
||
- **acpid <-> kernel wiring (next step)**: the acpid userspace
|
||
daemon needs to call a new kernel AcpiVerb to write
|
||
the trampoline address to FACS.waking_vector before
|
||
\_PTS(3). This is a separate Phase II.X.W commit.
|
||
|
||
## 2026-07-01 — Phase II.X.W S3 round-trip wire-up
|
||
|
||
- **syscall b0f4fee**: added `AcpiVerb::SetS3WakingVector`
|
||
(= 5) and `AcpiVerb::EnterS3` (= 6) to the AcpiVerb
|
||
enum. Hardware-agnostic: works on any x86_64
|
||
system with standard ACPI S3 support (Dell, HP, Lenovo,
|
||
LG Gram 14).
|
||
- **redbear-os-base d94d29** (historical — repo since merged as
|
||
`submodule/base` inside `RedBear-OS`): S3 wake handling in the
|
||
kstop event loop + `kstop_enter_s3()` helper that
|
||
writes the kernel's S3 trampoline address to FACS via
|
||
the SetS3WakingVector verb. Calls
|
||
`wake_from_sleep_state(3)` on S3 wake.
|
||
- **redbear-os-kernel 9bc1fbf**:
|
||
- **Comprehensive FACS parser** matching Linux 7.1's
|
||
`struct acpi_table_facs` from `include/acpi/actbl.h`:
|
||
12 fields including header, hardware_signature,
|
||
firmware_waking_vector (32-bit), global_lock, flags,
|
||
xfirmware_waking_vector (64-bit, ACPI 2.0+), version,
|
||
reserved[3], ospm_flags (ACPI 4.0+), reserved1[24].
|
||
- **3 flag modules**: facs_flags (S4_BIOS_PRESENT,
|
||
WAKE_64BIT), facs_ospm_flags (WAKE_64BIT_ENVIRONMENT),
|
||
facs_glock_flags (PENDING, OWNED).
|
||
- **FADT.x_firmware_ctrl + firmware_ctrl accessors**:
|
||
FADT offsets 140 and 36.
|
||
- **Sdt.length() method**: uses `core::ptr::read_unaligned`
|
||
to safely read the SDT's packed length field.
|
||
- **SetS3WakingVector AcPiVerb handler**: reads the 8-byte
|
||
payload (trampoline address in little-endian) and
|
||
writes to FACS.xfirmware_waking_vector. A zero payload
|
||
is a sentinel for "use the kernel's default
|
||
trampoline address" (s3_trampoline symbol).
|
||
- **acpi init** (src/acpi/mod.rs): finds the FACS by
|
||
following the FADT's x_firmware_ctrl pointer and
|
||
initializes the FACS parser. Logs a warning if FACS
|
||
is not found.
|
||
- **Full S3 round-trip flow** is now wired:
|
||
1. acpid: enter_sleep_state(3) does the AML prep
|
||
(`_TTS(3)`, `_PTS(3)`, `_SST(3)`)
|
||
2. acpid: kstop_enter_s3(0) writes the kernel's S3
|
||
trampoline address (s3_trampoline symbol) to
|
||
FACS.xfirmware_waking_vector
|
||
3. acpid: writes 's3' to /scheme/sys/kstop with the
|
||
SLP_TYP byte
|
||
4. kernel: stop::enter_s3 reads S3_SLP_TYP, writes
|
||
SLP_TYP|SLP_EN to PM1a_CNT
|
||
5. firmware: enters S3
|
||
6. ... on wake ... firmware jumps to FACS.waking_vector
|
||
7. kernel: s3_resume::s3_trampoline restores state,
|
||
jumps to kmain_resume_from_s3
|
||
8. acpid: receives kstop reason=3, runs
|
||
wake_from_sleep_state(3) (`_SST(2)` -> `_WAK(3)` ->
|
||
`_SST(1)`)
|
||
|
||
## 2026-07-01 — Build system: explicit patch verification
|
||
|
||
The user requested "build system must report complete when
|
||
upstream have our patches applied". This session adds the
|
||
explicit verification tools:
|
||
|
||
- **`local/scripts/check-cargo-patches.sh`** (Improvement C):
|
||
For each local source's `Cargo.toml`, scans for
|
||
`[patch.crates-io]` and `[patch."<URL>"]` sections,
|
||
resolves the patch via `cargo metadata`, and verifies
|
||
that the resolved source URL (or manifest_path for
|
||
path-deps) matches the expected local fork path. Returns
|
||
non-zero on any unresolved patch. Wraps `cargo metadata`
|
||
in a 30s timeout to handle large workspaces (relibc,
|
||
base). Explicitly skips relibc (its `[patch]` is only the
|
||
cc-rs git branch override, no `path` patches).
|
||
- **`make verify-patches`**: runs the above script. The
|
||
current kernel Phase J patch
|
||
([patch."<URL>"] redox_syscall) is verified
|
||
end-to-end.
|
||
- **`make verify-file-patches`**: runs
|
||
`local/scripts/check-unwired-patches.sh --strict` which
|
||
verifies all file-level .patch files in `local/patches/`
|
||
are referenced by at least one recipe.toml `patches = [...]`
|
||
entry.
|
||
- **`make verify-all`**: runs both. The comprehensive
|
||
Phase J end-to-end verification. Returns non-zero on any
|
||
failure (CI-friendly).
|
||
|
||
The cookbook itself already logs `[SUMMARY] All N patches
|
||
validated successfully` for file-level patches. These new
|
||
Makefile targets make the verification part of the standard
|
||
build workflow.
|
||
|
||
## 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 A–D — 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 A–D:**
|
||
- **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 S1–S4 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 A–F 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 (historical at time of writing — `vasilito/redbear-os-base`,
|
||
`vasilito/redbear-os-kernel`, `vasilito/redbear-os-relibc`; since merged
|
||
as `submodule/<component>` branches inside `RedBear-OS` per the
|
||
SINGLE-REPO RULE in `local/AGENTS.md`),
|
||
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
|