boot: separate BIOS from UEFI

boot/bios/ now holds the MBR, the El Torito stub and the real-mode stage
2; boot/uefi/ is empty and documented.

Separate directories rather than #ifdefs, because the two share almost
nothing. A BIOS loader lives in 16-bit real mode, reaches the firmware
through software interrupts, and walks itself up into long mode. A UEFI
loader is a 64-bit PE that the firmware has already placed in long mode
with paging on, calling services through a table of function pointers.
What they do share is the hand-off contract, which boot/README.md now
writes down: ELF segments placed, long mode, a 24-byte-entry memory map
at E820_MAP_ADDR, framebuffer geometry at VBE_INFO_ADDR.

That contract is the point of documenting it now. UEFI's GetMemoryMap
returns EFI_MEMORY_DESCRIPTORs, and the right move is to translate them
into the entries kernel/arch/x86_64/e820.c already parses rather than
teach the kernel a second format.

Build output paths under $(BUILD)/boot are unchanged; only sources moved.
This commit is contained in:
Nexoniarz 2026-08-09 16:00:03 +02:00
commit 08a1a9033a
19 changed files with 125 additions and 33 deletions

View file

@ -354,7 +354,7 @@ stops being extendable: it is 16-bit real mode, INT 10h VBE, and PIO ATA, none
of which exist on a UEFI-only machine. The realistic shape is a *second*
loader — an EFI application that gets the framebuffer from GOP, the memory map
from `GetMemoryMap()`, loads the kernel off a FAT ESP, and enters at the same
place `boot/stage2main.c` does — rather than a port of the existing one. Worth
place `boot/bios/stage2main.c` does — rather than a port of the existing one. Worth
noting that the splash work just done survives that transition: it is a mask, a
palette and a layout, none of which care how the pixels were found. What does
not survive is every assumption in `stage2main.c` about where things live in low
@ -465,9 +465,9 @@ does not. Measured 2026-08-08: boots at 224M and above, triple faults at 192M
and below. Nothing is actually being *used* — the requirement is entirely
fictional.
**The fix is already half-built.** `boot/stage2.S` collects a full E820 memory
**The fix is already half-built.** `boot/bios/stage2.S` collects a full E820 memory
map in real mode and leaves it at `VBE_INFO_ADDR + 0x200` (count) and `+ 0x208`
(24-byte entries); `boot/stage2main.c` already parses it to print detected RAM.
(24-byte entries); `boot/bios/stage2main.c` already parses it to print detected RAM.
**The kernel never reads it.** So: have `main()` take the top of the highest
usable E820 region instead of the constant, clamp it to what the direct map
covers, and keep `PHYSTOP` only as a fallback for the case where the firmware