Files
Sylva/AGENTS.md
T
2026-06-05 20:14:21 +08:00

3.7 KiB

Sylva OS — Agent Guide

x86_64 UEFI hobby OS. C17 boot → C++17 kernel, ELF64 → PE32+ via objcopy.

Build & Run

Command What
make Build build/BOOTX64.EFI + build/Kernel.elf
make disk Build FAT32 disk image (128 MiB) only — no QEMU
make run make disk + QEMU/OVMF. Serial 1 → serial.log (gitignored), paused for GDB (:1234)
make vdir Stage BOOTX64.EFI + Kernel.elf + resources/ into vdir/EFI/BOOT/ for manual boot
make clean wipes build/, vdir/, and serial.log

Prereqs for make run: qemu-system-x86_64, OVMF at /usr/share/ovmf/OVMF.fd, mtools (mformat/mmd/mcopy). QEMU starts paused — connect GDB to :1234 to proceed. Kernel debug output goes to serial.log.

Architecture

boot.c is legacy UEFI glue — loads Kernel.elf from the FAT volume, parses ELF PHDRs, jumps to entry. Don't refactor unless touching the boot stage. Bundled gnu-efi sources live in efi/.

Kernel lives in kernel/. Boot calls _start (kernel/entry.cpp:8), which saves EFI_SYSTEM_TABLE* in global ST, then extern "C" kernel_main() (kernel/main.cpp:73) runs:

  1. init_gop()gfx_init(GOP) framebuffer (graphics/context.cpp)
  2. init_serial() → locate SERIAL_IO protocol
  3. pmm_init() — bitmap + free-list page allocator (kernel/memory/pmm.cpp)
  4. init_heap() — kmalloc/kfree/kcalloc/krealloc, first-fit w/ coalescing (kernel/memory/heap.cpp)
  5. fs_init() / fs_list() — reads FAT volume via UEFI (kernel/fs.cpp)
  6. gdt_init()idt_init()pic_init()pit_init() (kernel/interrupt/)
  7. ASM("sti") — interrupts on
  8. layer_init() + layer_create(...) for desktop + windows (kernel/graphics/layer.cpp)
  9. task_create("compositor", layer_compositor_task)
  10. scheduler_run() — never returns. Preemptive, 100 Hz PIT, 5-tick time slice (kernel/scheduler/)

PIT IRQ 0 dispatches to pit_irq_handlerscheduler_tick via the IRQ handler in kernel/main.cpp:56.

include/common.h — use these, not raw equivalents

Always #include <common.h> (it pulls in <types.h> + <string_utils.h> and defines the ASM macro):

Provided Use instead of
SSINT8/16/32/64, SUINT8/16/32/64 raw int*_t / uint*_t
String (const char*), WString (const uint16_t*) raw char* / CHAR16*
str_len, str_cmp, str_eq, str_copy hand-rolled loops on char*
wstr_len, wstr_cmp, wstr_eq, wstr_copy, wstr_to_ascii hand-rolled loops on CHAR16*
mem_set, mem_copy hand-rolled byte loops
ASM(...) raw asm volatile(...) — e.g. ASM("cli"), ASM("hlt"), ASM("sti")

All string_utils.h helpers are static inline — header-only, no link issues. New kernel code should reach for these before adding anything new to string_utils.h.

Conventions

  • Commits: [type] message — types: feat, fix, chore, docs, refactor (see git log).
  • Languages: C17 (boot.c), C++17 (kernel/) — -ffreestanding -fno-stack-protector -fshort-wchar -mno-red-zone -fcf-protection=none. Kernel adds -DGNU_EFI_USE_MS_ABI -fno-pic.
  • kernel_main must be extern "C"boot.c (C) calls into C++ (kernel/entry.cpp:6).
  • All UEFI protocol calls must use uefi_call_wrapper — calling the member fn directly page-faults in long mode. See kernel/main.cpp:23-24 and throughout.
  • Kernel linked at 0x100000 (kernel/kernel.ld); .bss start/end symbols exposed as __bss_start / __bss_end.
  • No tests, no CI, no lint configmake is the only verification step. Boot by hand in QEMU to confirm kernel output in serial.log.