acpi: take the RSDP from the loader when firmware gives it to us

find_rsdp() scanned the EBDA and 0xE0000-0x100000. That is a BIOS
convention, and UEFI firmware is under no obligation to leave a copy
there -- OVMF does not. So the kernel found no RSDP, no MADT and no
IOAPIC, and nothing routed IRQ 4. Serial output is polled, so the machine
booted all the way to a shell prompt and then ignored every key, which
reads as a broken console rather than a missing table.

The UEFI loader reads the RSDP out of the EFI configuration table,
preferring ACPI 2.0 for its XSDT, and leaves it at SCHBOOT_RSDP_ADDR --
the same low-memory hand-off block the e820 map already uses, now
described in include/schboot.h so the two sides cannot disagree.

The kernel validates it rather than trusting it: the BIOS path never
writes that slot, so there it holds whatever was in memory, and following
a wild pointer faults before there is anything to report the fault with.
Signature and checksum do that. It deliberately does not require 16-byte
alignment -- that rule is about searching the BIOS area, and OVMF's RSDP
sits at 0x3f77e014, so demanding it threw away the one address this code
exists to use.

UEFI now reports "acpi: 1 cpu, lapic at ..., ioapic id 0" and the ISO
boots to an interactive shell: uname, ls /bin (241), writing and reading
a file, ps, /proc/schfs -- all driven over serial.

BIOS unchanged: bootcheck 108 [ok], same ACPI line as before.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Nexoniarz 2026-08-09 22:02:57 +02:00
commit 9735279970
4 changed files with 101 additions and 0 deletions

View file

@ -171,6 +171,23 @@ typedef struct {
void *ConfigurationTable;
} EFI_SYSTEM_TABLE;
// --- configuration tables -------------------------------------------------
//
// Where UEFI publishes things a BIOS left lying in low memory. The ACPI RSDP is
// the one that matters here: the kernel finds it by scanning the EBDA and
// 0xE0000-0x100000, which is a BIOS convention that firmware is under no
// obligation to honour -- and OVMF does not.
#define EFI_ACPI_20_TABLE_GUID \
{ 0x8868E871, 0xE4F1, 0x11D3, { 0xBC, 0x22, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81 } }
#define EFI_ACPI_10_TABLE_GUID \
{ 0xEB9D2D30, 0x2D88, 0x11D3, { 0x9A, 0x16, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } }
typedef struct {
EFI_GUID VendorGuid;
void *VendorTable;
} EFI_CONFIGURATION_TABLE;
// --- loaded image ---------------------------------------------------------
#define EFI_LOADED_IMAGE_PROTOCOL_GUID \