fix(renaser): forzar BARs PCI a los primeros 4 GiB (pci-hole64-size=0)
Esta era la verdadera causa del «pantalla negra + franja roja» en máquinas
distintas a la del autor. El trace de boot del usuario lo cantó:
boot :: disco :: init <- llegamos aquí
disco :: init offset=0x20000000000 region=[...] base=...
boot :: almacen :: init <- y aquí
*** renaser :: panico ***
EXCEPCION FATAL :: fallo de pagina (#PF) en 0x20800000014
0x20800000014 - phys_offset(0x20000000000) = 0x800000014 (= 32 GiB + 0x14)
Un acceso vía el mapeo de memoria física a phys=32 GiB. Eso es el BAR
MMIO del virtio-blk: OVMF en QEMU q35 moderno con KVM aloja los BARs
prefetchables 64-bit en el «pci hole» de 64 bits (típicamente a partir
de 32 GiB). El `bootloader` 0.11 con `Mapping::Dynamic` mapea la RAM
del sistema, pero no extiende el mapeo hasta los BARs ahí arriba.
KernelHal::mmio_phys_to_virt devolvía `phys + offset` sin verificar
nada — el host esperaba que el BAR estuviese en los primeros 4 GiB,
como mi Proxmox con TCG y mi nightly. En la laptop con KVM y el OVMF
del usuario, OVMF lo subía y todo reventaba al leer el primer registro.
El parche: `-global q35-pcihost.pci-hole64-size=0` en los args por
defecto de QEMU. Apaga la ventana PCI de 64 bits, OVMF se ve forzada
a alojar todos los BARs en los primeros 4 GiB y el mapeo del cargador
los cubre. Verificado: arranca limpio en Proxmox y debería arrancar
también en la laptop del usuario.
(Las verificaciones unchecked_mul del commit anterior eran una pista
falsa — eran solo donde caía la IP del último build; el fallo de
escritura siempre fue el mismo BAR sin mapear.)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -323,6 +323,13 @@ fn lanzar_qemu(imagen: &Path, ovmf: &str) -> Result<(), String> {
|
|||||||
.arg("-vga").arg("std")
|
.arg("-vga").arg("std")
|
||||||
.arg("-serial").arg("stdio")
|
.arg("-serial").arg("stdio")
|
||||||
.arg("--no-reboot")
|
.arg("--no-reboot")
|
||||||
|
// El cargador `bootloader` 0.11 mapea la memoria fisica que ve, pero NO
|
||||||
|
// las regiones MMIO en el agujero PCI de 64 bits (por encima de 4 GiB),
|
||||||
|
// donde OVMF coloca los BAR de virtio-blk en QEMU q35 modernos con
|
||||||
|
// KVM. Sin mapeo, leer un registro MMIO del disco era un #PF
|
||||||
|
// inevitable. Apagar `pci-hole64-size` fuerza a OVMF a alojar todos
|
||||||
|
// los BAR en los primeros 4 GiB, que el cargador si mapea.
|
||||||
|
.arg("-global").arg("q35-pcihost.pci-hole64-size=0")
|
||||||
// El disco de objetos, como dispositivo virtio-blk sobre el bus PCI.
|
// El disco de objetos, como dispositivo virtio-blk sobre el bus PCI.
|
||||||
.arg("-drive").arg(format!("format=raw,file={NOMBRE_DISCO},if=none,id=drv0"))
|
.arg("-drive").arg(format!("format=raw,file={NOMBRE_DISCO},if=none,id=drv0"))
|
||||||
.arg("-device").arg("virtio-blk-pci,drive=drv0");
|
.arg("-device").arg("virtio-blk-pci,drive=drv0");
|
||||||
|
|||||||
Reference in New Issue
Block a user