SchOS/boot/uefi
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Nexoniarz 3f2c0bdf05 loader: the F8 menu on the serial line
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>
2026-09-22 12:10:37 +02:00
..
efi.h boot/uefi: choose a resolution with R, the same as the BIOS path 2026-08-10 05:30:03 +02:00
main.c loader: the F8 menu on the serial line 2026-09-22 12:10:37 +02:00
README.md boot: the BIOS loader is gone 2026-08-11 10:20:28 +02:00
startup.nsh boot/uefi: a working UEFI loader, with one known limitation 2026-08-09 17:13:09 +02:00

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:

  1. 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.
  2. 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.
  3. GetMemoryMap translated into the same 24-byte entries e820.c already parses. Not a second format for the kernel to learn.
  4. ExitBootServices before touching the memory it described.
  5. Graphics Output Protocol for the framebuffer, filling the same VBE_INFO_ADDR structure 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.