Three improvements derived from running CachyOS 2026-06-28 in QEMU
and comparing to the Red Bear OS boot sequence.
drivers/pcid/src/main.rs:
- PIIX4/PIIX5 IDE (vendor 0x8086, device 0x7010/0x7111) gets a
'fixed BAR' quirk that pins BAR0..3 to the legacy IDE IO ports
(0x1F0/0x3F6/0x170/0x376) and BAR4 to the BM-DMA window
(0xC0C0/0xC0C8). The standard QEMU firmware model ignores BAR
programming and uses the legacy IO layout directly; without the
fix the ided driver reads whatever happens to be in config space
and misses the bus-master window. Linux applies the same quirk in
drivers/ata/ata_piix.c.
- Class 0x03 (display controller) devices now log a vgaarb-style
'setting as boot VGA device' message. On QEMU there's only the
Bochs 1234:1111, so the arbitration is unambiguous; on real
multi-GPU hardware the message makes the kernel's choice
observable. Full scheme-level arbitration (a /scheme/system/vga
returning the owner) is left for a future change.
initfs/tools/Cargo.toml + initfs/tools/src/bin/loop_mnt.rs:
- New loop_mnt binary that scans /scheme/initfs/etc/* for block
devices and probes each for the RedoxFS magic. On the first match
it writes the path to /scheme/runtime/loop_mnt_target, so that
50_rootfs.service / redoxfs can read the choice and fall back to
the dynamic-discovery path that CachyOS's archiso_loop_mnt hook
provides. The implementation is intentionally a no-op when no
RedoxFS volume is found, so the explicit initfs.toml path remains
the source of truth on a normal boot.
init.initfs.d/45_loop_mnt.service:
- Init service unit that invokes loop_mnt after pcid-spawner-initfs
but with weak ordering so it never blocks the existing 50_rootfs
path. Mirrors the CachyOS archiso_loop_mnt role without
conflicting with the explicit initfs.toml flow.
recipes/core/base-initfs/recipe.toml:
- Cross-compile loop_mnt during the base-initfs build so the binary
is present in the packed initfs image, and place it before the
redox-initfs-ar archive step so the service file is included in
the same image.
thermald and redbear-upower read_dir /scheme/acpi/{thermal,power} to
enumerate ACPI _TZ zones and _PR power sources. The acpid scheme
returned EIO for these new directory variants, which std::fs::read_dir
interprets as 'the path is not a directory or doesn't exist' and
emits a warning.
Return Ok with no entries for Thermal/Power getdents so read_dir
sees an existing-but-empty directory and consumers gracefully fall
through to the empty-state path.
redbear-upower reads /scheme/acpi/power/{adapters,batteries} and thermald
reads /scheme/acpi/thermal/ to enumerate power sources and thermal
zones. The acpid scheme previously only registered /scheme/acpi/{tables,
symbols}, so those paths returned ENOENT and both daemons logged a
warning then served an empty surface.
Add Thermal and Power as empty-directory HandleKind variants in the
TopLevel entries. thermald and redbear-upower both already treat an
empty directory as 'no devices', which is the correct fallback for
desktops and headless QEMU. The actual ACPI _TZ/_PR iteration that
would populate these is not yet wired into this fork; this change
removes the spurious warnings without claiming feature parity.
daemon/src/lib.rs: Daemon::ready() previously called .unwrap() on the
init pipe write, causing a panic with BrokenPipe when init had already
closed its read end during the startup phase. Daemons like i2c-gpio-expanderd,
intel-gpiod, dw-acpi-i2cd, and i2c-hidd hit this in redbear-mini boots.
Now BrokenPipe is silently ignored — the daemon is operational regardless
of init's readiness tracking state.
drivers/usb/ucsid/src/main.rs and drivers/gpio/i2c-gpio-expanderd/src/main.rs:
read_i2c_control_response() returned an empty buffer (no I2C adapters
registered) and then tried ron::from_str('') which failed at 1:1 with
'Unexpected end of RON'. This produced false-positive warnings on every
boot where no I2C hardware is present. Now an empty/whitespace response
returns AdapterList(Vec::new()) gracefully.