| Filename | Latest commit message | Latest commit date |
|---|---|---|
ui_panel was written for this screen during the loader restyle and then never called -- dead code sitting in boot/common/ui.c waiting for the row that would use it. This is that row: F8 -> System Information, showing firmware vendor and revision, UEFI revision, CPU brand, usable memory, current mode and whether ACPI was found. Everything is read when the screen is drawn rather than captured at startup, because the resolution row above it can have changed the mode, and a panel still reporting what the machine booted with is worse than no panel at all. Two facts are deliberately read through the same code that feeds the kernel -- efi_type_to_e820() for what counts as usable memory, and find_rsdp() for ACPI. A panel with its own idea of either would be a second implementation to keep in step, and the ACPI line exists precisely because a missing RSDP means no MADT, no IOAPIC and no SMP, which has already been debugged once from the far end. The screenshot caught a bug in the screen it was taken to verify: UEFI revision read "21587.2286". EFI_TABLE_HEADER begins with a UINT64 Signature, so Revision is at offset 8 and I had read offset 4 -- the upper half of "IBI SYST", formatted as a version number. It now reads 2.7 under OVMF, which is correct. Verified by driving the menu over the QEMU monitor and reading the pixels: five rows with the hint updated to 1-5, the panel centred, and every value cross-checkable -- EDK II, firmware 1.0, UEFI 2.7, "QEMU Virtual CPU version 2.5+" against -cpu qemu64, 1018 MB of the 1 GB given, 1280x800 matching what fbshot captures, ACPI present. The highlight sits 9 px inside both panel borders, symmetric. F8 has a 1.5 s window, so the capture presses it repeatedly through boot rather than guessing when OVMF finishes -- and only F8, since any other key breaks the wait and boots. Also: every ESP drive now says format=raw. QEMU warned about probing the format on each of the fifteen or so places that attach it, which is new noise on what is now the only boot path. 110 [ok], no failures, no warnings. |
||
| .. | ||
| common | ||
| uefi | ||
| README.md | ||
Booting SchOS
One firmware path:
boot/
uefi/ the loader: a 64-bit PE application
common/ the user interface, shared with nothing else now
There were two. boot/bios/ held an MBR, an El Torito CD stub and a real-mode
stage 2, and it was a separate directory rather than #ifdefs because the two
shared almost nothing: a BIOS loader lives in 16-bit real mode and talks to the
firmware through software interrupts, while UEFI hands a loader long mode with
paging already on and a table of function pointers to call.
That asymmetry is what removed it. Everything since roughly 2012 boots UEFI,
CSM — the firmware-side BIOS emulation that let legacy loaders run at all — has
been going away since Intel dropped support for it in 2020, and the cost of the
second path was not the code but the tax on everything that touched it: stage 2
had a 65-sector ceiling that it silently overflowed, and the resolution menu
could not be shared because VBE mode setting is INT 10h and needs real mode.
The contract below survives it. It was written to let a second loader exist, and it is worth keeping in that shape: it is what the kernel expects, stated once, rather than a description of whoever happens to be calling.
What the loader must hand the kernel
Whichever path runs, the kernel expects the same things. This is the contract; a second loader is correct exactly when it satisfies it.
| Where | Notes | |
|---|---|---|
| Kernel image | loaded per its ELF program headers | entry at entry64 |
| CPU state | see below -- the two paths differ here | |
| Memory map | E820_MAP_ADDR, 24-byte entries, count at E820_COUNT_ADDR |
kernel/arch/x86_64/e820.c reads it |
| Framebuffer | VBE_INFO_ADDR |
address, pitch, width, height, depth |
| Verbose flag | BOOT_VERBOSE_FLAG_ADDR |
set by the F8 menu |
The addresses are defined once, in include/memlayout.h and include/schboot.h.
The kernel does not care which firmware produced them.
The entry point
UEFI hands a loader long mode with paging already on. Dropping back to
protected mode only to climb out again is a mode switch whose failure mode is a
triple fault with no console, so the kernel publishes an entry that takes the
machine as it already is.
kernel/arch/x86_64/entry.S carries a sch64_header — magic SCH64BOO,
8-byte aligned within the first 16 KB, followed by a 64-bit physical address —
found by scanning. include/schboot.h holds the magic so loader and kernel
cannot disagree.
The 32-bit multiboot entry is still in entry.S and now has no caller: the
BIOS loader was the only thing that used it. It is left in place rather than
removed in the same change that removed the loader, because deleting kernel
entry code is its own piece of work with its own way of failing silently.
What that entry expects:
- long mode, interrupts off
- CR3 pointing at tables that identity-map the low 4 GB and map the same
4 GB at
0xffff800000000000.entry64low's first instruction is amovabsto a high address, so identity alone triple faults immediately. - RBX = the framebuffer physical address, and never 1 — that value marks an
application processor in
entry64high.
The kernel loads its own GDT at that entry (entry64uefi), rather than the
loader doing it. A loader arriving in long mode is still on the firmware's
descriptors, and the first thing the kernel does that depends on its own
selectors takes a #GP against a GDT the firmware no longer owns — it
surfaced as unexpected trap 13 ... cs=38, a long way from the cause.
e820.c reads a BIOS memory map. UEFI hands out a different structure
(EFI_MEMORY_DESCRIPTOR, from GetMemoryMap), so the UEFI loader has to
translate it into the same 24-byte entries rather than inventing a second
format for the kernel to learn.
What booting looks like now
make esp stages EFI/BOOT/BOOTX64.EFI and schos/kernel, and QEMU is
pointed at OVMF with that directory as a virtual FAT volume — make qemu.
make iso builds a disc with a single El Torito entry pointing at a FAT image
holding the same two files.
Neither is an installable disk. A real GPT image with a real FAT partition is the installer's job, and until it exists there is nothing here that writes to a disk a machine could boot from unaided.
Secure Boot is not addressed either: the loader is unsigned, so a machine enforcing it will refuse to run this.