| Filename | Latest commit message | Latest commit date |
|---|---|---|
Two things, both asked for. **The crash report no longer says which monitors it reached.** "The report is on the virtio-gpu display too" was a line about the crash screen printed on the crash screen. The report says what happened and where to read it again; that is not part of it. **And the second head now shows the F8 menu and the boot.** It used to be black until vgpud started several seconds into userspace -- through the splash, through the menu, through every boot message -- which from the outside is indistinguishable from a display that does not work. Three stages now cover the whole boot and hand over to each other without coordinating: *The loader.* LocateProtocol() answers with the first GOP and offers no way to ask for the rest, so the rest are found by handle and fed the primary's framebuffer as a Blt source at the points where a screen is finished: the menu, the resolution chooser, system information, the splash, each segment of the kernel load. Blt rather than a second framebuffer to draw into, because a virtio GOP does not have one -- the same fact that made a virtio-only machine reboot-loop two commits ago. *The kernel.* gfx remembers which rows were drawn, as one span rather than a list of rectangles, because console output is lines and a span is what lines make. display_mirror_console() copies that span across: a line of boot text is one cell-row transfer, not a screen. Primed once after pci_init(), because a display that has just appeared has a black scanout and the console it should be showing was drawn by the loader into a framebuffer it knows nothing about. *Then vgpud*, from the same console framebuffer, unchanged. **Two bugs found building it, both worth the retelling.** The mirror ran per character from inside vt_feed -- which is inside the console lock -- and vga_disp_acquire() announces its back buffer with a cprintf. A CPU taking a lock it already holds, with a call chain that said exactly that. It runs at the end of consolewrite() and cprintf() now, outside the lock, which is also the better batching: one transfer per write instead of one per character. And "is this the console's own screen" was asked of the pointer acquire() returned. vga_fb hands back a back buffer it copies onto the console's framebuffer afterwards, so on a one-screen machine the answer was "a different screen" -- and the console was mirrored onto itself through two megabytes of intermediate, allocated for the purpose. display_ops grew scanout_phys, which is a fact about the hardware rather than a policy a driver can get subtly wrong, and it is asked first: it has no side effects and acquire() has two. Verified with two heads under QEMU, screendumping the virtio head every 400 ms from power-on: splash, splash, splash, then the console, and it stays. The F8 menu appears on it; choosing 1024x768 there brings both heads up at 1024x768 byte-identical. A panic still reaches both. Both supported configurations: one boot each, no traps, no panics, socktest and memfdtest green. One gap remains and is documented rather than hidden: while the kernel's driver resets the device during probe, QEMU shows "Display output is not active" for a fraction of a second. A device being taken over has no scanout until the new driver sets one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
| .. | ||
| efi.h | ||
| main.c | ||
| README.md | ||
| startup.nsh | ||
UEFI loader
The loader. This directory once existed only so the BIOS path could be moved
into boot/bios/ without pretending the split was hypothetical; it is now the
only path there is.
See ../README.md for the hand-off contract a loader has to satisfy. The
short version: the kernel wants long mode with paging on, its ELF segments
placed, a 24-byte-entry E820-shaped memory map, and framebuffer geometry — and
it does not care which firmware produced them.
What this will need, in rough order:
- A PE/COFF target. clang can emit one directly
(
--target=x86_64-unknown-windows -fuse-ld=lld-link), so no new toolchain: the same LLVM install already builds every other target here. - The handful of UEFI structures actually used — the system table, boot
services,
LOADED_IMAGE,SIMPLE_FILE_SYSTEM,GRAPHICS_OUTPUT. Written from the specification rather than by importing gnu-efi or EDK II, which is both a licence question and a large dependency for something this small. GetMemoryMaptranslated into the same 24-byte entriese820.calready parses. Not a second format for the kernel to learn.ExitBootServicesbefore touching the memory it described.- Graphics Output Protocol for the framebuffer, filling the same
VBE_INFO_ADDRstructure the kernel reads.
The image goes at EFI/BOOT/BOOTX64.EFI on a FAT ESP, which also means the
ISO carries a single El Torito EFI entry.