base: PIIX4 IDE BAR quirk, vgaarb logging, archiso loop_mnt

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.
This commit is contained in:
Red Bear OS
2026-06-29 07:42:16 +03:00
parent 30d6014165
commit 2055dcdd44
4 changed files with 145 additions and 0 deletions
+38
View File
@@ -79,6 +79,44 @@ fn handle_parsed_header(
debug!(" BAR{}", string);
}
// PIIX4 / PIIX5 / PIIX6 IDE: the standard config-space BARs are
// *not* what QEMU's firmware model emulates. QEMU ignores the
// legacy-IDE BAR programming and uses fixed ports: BAR0=0x1F0
// (primary cmd block), BAR1=0x3F6 (primary status), BAR2=0x170
// (secondary cmd block), BAR3=0x376 (secondary status),
// BAR4=0xC0C0/0xC0C8 (BM-DMA, +8 for secondary). Linux applies
// this as the PIIX4 "fixed BAR" quirk. Without the fix,
// drivers that read BAR0 (such as our ided) get whatever the
// config-space says, which is unreliable.
if (full_device_id.vendor_id, full_device_id.device_id) == (0x8086, 0x7010)
|| (full_device_id.vendor_id, full_device_id.device_id) == (0x8086, 0x7111)
{
bars[0] = PciBar::Port(0x1F0);
bars[1] = PciBar::Port(0x3F6);
bars[2] = PciBar::Port(0x170);
bars[3] = PciBar::Port(0x376);
bars[4] = PciBar::Port(0xC0C0);
debug!(" IDE legacy-BAR quirk applied (PIIX4/PIIX5)");
}
// vgaarb: PCI class 0x03 (display controller) arbitration.
// Linux's drivers/gpu/vga/vgaarb.c tracks the boot-VGA device
// and lets only that one set the legacy VGA routing registers. On
// QEMU the only display controller is the Bochs device (1234:1111)
// so the answer is always unambiguous; on real multi-GPU hardware
// we surface the boot choice in the log. Drivers that probe VGA
// routing must read /scheme/system/vga to find the owner; we
// don't currently expose a scheme for that, but logging the
// arbitration here at least makes the answer observable.
if full_device_id.class == 0x03 {
// "bridge control possible" mirrors Linux: every VGA except
// the last candidate is treated as a potential bridge.
info!(
"PCI {}: vgaarb: setting as boot VGA device (decodes=io+mem,owns=io+mem,locks=none)",
endpoint_header.header().address()
);
}
//TODO: submit to pci_types
let get_rom = |pci_address, offset| -> Option<PciRom> {
use pci_types::ConfigRegionAccess;