| Filename | Latest commit message | Latest commit date |
|---|---|---|
The three F8 screens painted into the framebuffer and nowhere else. That is
right on a machine with a screen and useless on one driven over a serial cable
-- which is how this loader is usually driven, and which f8_window() already
went out of its way to support: it accepts 'o' as well as F8 because, in its
own words, "a serial console sends no scan codes at all".
So the prompt invited a serial user in, drew them a menu they could not see,
and then blocked for ever on a key they had no way to choose. The whole visible
behaviour was:
Press F8 for boot options...
<nothing, for ever>
Each screen echoes itself to COM1 now -- the boot menu, the resolution list and
System Information. The whole thing once on entry, then one line per *move*;
not on every keypress, because a serial terminal has no cursor to paint over
and an unrecognised key would scroll the selection past again for nothing.
Straight to COM1 rather than through print(): print() goes to ConOut until the
splash is up, and ConOut on a machine with graphics draws its text across the
menu that was just painted there.
Two details found by actually driving it, neither cosmetic:
- **The item number is shown only where it is a key you can press.** The boot
menu takes 1-5. The resolution list takes only W/S and Enter and is longer
than nine entries, so numbering it printed ':', ';', '<' past the ninth --
a character nobody can type, offering to select something.
- **Q goes back as well as Esc.** A lone ESC byte on a serial line is
indistinguishable from the start of an escape sequence, so the terminal
driver holds it back waiting for the rest and it never arrives as a key.
Esc is the obvious thing to press on a screen and unreachable on a cable --
the same shape of problem as F8, and the same answer.
Driven end to end over serial: open the menu, walk it with W/S, open System
Information and come back, open Resolution and come back with Q, then boot.
The graphical menu is unchanged apart from the hint now naming Q.
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.