a simple OS kernel, made at PAIR camp 2025 by max, zehao, and rohan
Makefilelinker.ldkernel.c(C entry point that writes “Hello, world!” to the screen)- The entry point to a UEFI application is a C file, no other assembly files needed.
Makefile- Defines how
makecompiles each.Sand.cinto.oobject files. - Invokes the linker with
linker.ldto lay out those objects in memory and set the entry point. - Packages the resulting
kernel.efiinto a bootable image (FAT-ESP).
- Defines how
linker.ld- Tells the linker where to place the code/data sections and which symbol is the entry point.
- Linker (
i686-elf-ld)- Takes all the
.ofiles plus the script, resolves symbols, applies relocations, and produces the final EFI image (kernel.efi).
- Takes all the
- Boot Image
- Creates a FAT image (
esp.img) withEFI/BOOT/BOOTX64.EFI→ done with QEMU with OVMF
- Creates a FAT image (
[Our Code] <--> [UEFI] <--> [QEMU (simulated hardware)]
- UEFI runs our code which is stored in a
bootx.esifile - We use
GNU-EFIlibrary to call UEFI Boot Services from C.- UEFI Boot Services give rich APIs to do things like memory services without early bootloader codes.
At the beginning, maybe pangea kinda time, we spent 10 minutes struggling with no c standard library, what the hell?
It turns out, we imported the libraries the wrong way round. Next, what a beautiful error, there was missing library?!
No, we missed the -c flag in our Makefile for approximately half an hour.
Then, we were on the home stretch, but the InitializeLib function was missing :(. How? I swore I included it?
Oh, a missing, underscore.
