SchOS/boot/uefi
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Nexoniarz 3a0b570c23 boot: mirroring cannot stall the machine, and the loader says where it is
Two reports from an Asus TUF FA607NU, which now gets as far as the splash:
the progress bar does not move, and after a resolution change the screen keeps
the background colour with no mark and no bar. Both point at the same code,
and it is code this loader did not have a week ago.

**Modes were being matched on every frame.** mirrors_match() ran from inside
mirrors_show(), so every menu redraw and every segment of the kernel load
asked another display adapter to change mode. On QEMU that is instant and
idempotent. On real hardware a mode set can take the best part of a second, can
blank a panel while it happens, and -- on a laptop -- is quite often being
asked of the *same* panel reached through a second GOP. A loader that does that
in the middle of drawing a progress bar is a loader that shows a background
colour and then waits on a firmware call that is not coming back.

It now happens exactly once, at discovery, before anything is drawn. The
second head is centred and cropped afterwards rather than re-moded, and the
booted system matches resolutions anyway because the kernel driver and vgpud
both follow the console.

**And mirroring no longer runs per segment of the kernel load.** Copying a
megabyte-and-a-half framebuffer to every other adapter, three times, to animate
a bar on a screen nobody is looking at.

**One refusal now turns it off for the rest of the boot**, and
`\schos\nomirror` -- an empty file whose only job is to exist -- turns it off
before it starts. There is no console to ask a question on at that point and no
menu to reach if the menu is what is broken, so the answer has to already be on
the volume. That also makes it a one-file experiment on hardware we cannot
instrument.

**The loader names its stages on screen.** After the splash, print() goes to
the serial port and nowhere else, so on a machine with no serial port a stall
leaves a progress bar and no information at all. Every stage after the kernel
load now labels itself under the bar -- Reading the console font, Reading the
memory map, Leaving the firmware -- so the last thing on the screen names the
call that did not return. Past ExitBootServices there is nothing left to report
with, which is itself worth knowing: a machine stopped on the last label
stopped in the jump.

Opening the boot volume moved ahead of the display, because what is on the
volume now decides some of what the display does.

Both supported configurations: one boot each, no traps, no panics, socktest and
memfdtest green. Mirroring still verified end to end -- F8, a resolution
change, boot, and both heads byte-identical at the new mode.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 19:50:28 +02:00
..
efi.h gfx: the second head shows the boot, not just what comes after it 2026-09-22 21:47:35 +02:00
main.c boot: mirroring cannot stall the machine, and the loader says where it is 2026-09-23 19:50:28 +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.