selecting the displays native resolution

This commit is contained in:
2026-07-03 10:07:51 +01:00
parent 21cc0c87e4
commit 6a08081bfe
5 changed files with 322 additions and 13 deletions
+21 -5
View File
@@ -58,10 +58,26 @@ The comment in `boot()` says exactly this:
### 1. Query the framebuffer (`queryFramebuffer`)
We ask the firmware for the **Graphics Output Protocol (GOP)**, which describes
the linear framebuffer — its address, resolution, pitch, and pixel format. We
copy those facts into our own `Framebuffer` struct. This *must* happen now,
because after exit there's no GOP to ask. (See [framebuffer.md](framebuffer.md)
for what those fields mean.)
the linear framebuffer — its address, resolution, pitch, and pixel format —
and, when we can, switch the display to its native resolution first:
- Locate GOP via its *handle* (not `locateProtocol`), because the same handle
also carries the display's **EDID**.
- Read the EDID (trying the `EDID_ACTIVE` then `EDID_DISCOVERED` protocol on each
GOP handle) and parse the first Detailed Timing Descriptor — by convention the
panel's preferred (native) resolution. This is best-effort: firmware installs
these protocols inconsistently, and OVMF with QEMU's stdvga doesn't expose them
at all.
- If we got a native resolution, enumerate the GOP modes with `queryMode` and
`setMode` to the one that matches it (must be a linear 32bpp layout we can
paint into). If EDID gave us nothing, we **keep the firmware's current default
mode** rather than guess — with a valid EDID the firmware normally defaults to
the native mode itself, so its choice beats second-guessing it with, say, the
largest advertised mode.
- Copy the resulting address/resolution/pitch/format into our own `Framebuffer`.
All of this *must* happen now, because after exit there's no GOP to ask. (See
[framebuffer.md](framebuffer.md) for what those fields mean.)
### 2. Load the kernel (`loadKernel` + `loadElf`)
@@ -149,7 +165,7 @@ power on
-> UEFI firmware initialises hardware
-> finds esp/EFI/BOOT/BOOTX64.efi, runs it (our efi.zig main)
-> grab boot services
-> queryFramebuffer (via GOP)
-> queryFramebuffer (via GOP: EDID native res, setMode, describe fb)
-> loadKernel (read danos ELF, load PT_LOAD segments to 0x100000)
-> exitBootServices (retry until the memory-map key holds)
-> jump to e_entry, boot_info pointer in RDI