This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Serix is a hybrid-kernel x86_64 operating system written in Rust (#![no_std], nightly toolchain). It boots via the Limine v10.x bootloader and uses capability-based security. Currently at v0.0.6, Phase 4 development (FAT32 filesystem).
cargo build --release # Build kernel only
cargo build -p <crate> --release # Build a specific crate
make init # Build userspace init binary (required before iso)
make iso # Build bootable ISO (kernel + init + Limine)
make run # Build everything and run in QEMU
make clean && cargo clean # Remove all build artifacts
cargo fmt # Format (tabs, 100-char width)
cargo clippy # LintNo automated test suite exists. Validate by booting in QEMU (make run) and checking serial output + framebuffer.
QEMU debug flags: qemu-system-x86_64 ... -d int,cpu_reset -no-reboot to catch triple faults.
Cargo workspace with 16 member crates. .cargo/config.toml sets x86_64-unknown-none as default target and enables build-std — no --target flag needed.
Key crates: kernel/ (entry, GDT, syscalls), memory/ (paging, heap, frame allocator), hal/ (serial, CPU, I/O ports), apic/ (LAPIC, I/O APIC, timer), idt/ (exception handlers), graphics/ (framebuffer console), task/ (async executor, scheduler), capability/ (security), drivers/ (VirtIO, PCI), vfs/ (ramdisk), ipc/ (port-based messaging), loader/ (ELF loader), ulib/ (userspace syscall wrappers), keyboard/ (PS/2 driver).
Internal crate dependencies use { path = "../crate_name" }.
- HHDM: All physical RAM mapped at
0xFFFF_8000_0000_0000— always useHHDM_REQ.get_response()for offset, never hardcode - Kernel heap:
0xFFFF_8000_4444_0000(1 MB, configured inmemory/src/heap.rs) - Userspace: Lower half, entry at
0x200000(viauser.ldlinker script)
Serial init → disable PIC/enable APIC → load IDT → enable interrupts/start LAPIC timer → process Limine responses → init page tables from CR3 → init heap → init graphics → init VFS → load init binary → idle loop.
Critical ordering: heap must exist before any allocations; IDT must be loaded before enabling interrupts.
0-31: CPU exceptions, 32: PIT (disabled), 33: PS/2 keyboard, 49: LAPIC timer (~625 Hz). All handlers must signal EOI to APIC.
Linux-style ABI via SYSCALL/SYSRET. RAX=number, RDI/RSI/RDX/R10/R8/R9=args. Dispatch in kernel/src/syscall.rs, wrappers in ulib/src/lib.rs. Syscalls: READ(0), WRITE(1), SEND(20), RECV(21), YIELD(24), EXIT(60).
TaskCB stores state + stack pointer. Scheduler with RunQueue (round-robin). AsyncTask with Future trait. Context switch via assembly in task/ crate (callee-saved GPRs + CR3 swap).
- Tabs, not spaces (
hard_tabs = true,tab_spaces = 8,max_width = 100) - C-style block comments for function headers:
/* function_name - description */ - Global state pattern:
static INSTANCE: Once<Mutex<Type>> = Once::new() - Debug output:
serial_println!(kernel),fb_println!(framebuffer) - Address types: Use
x86_64::PhysAddrandx86_64::VirtAddr, not raw integers - Syscall naming: prefix with
serix_(e.g.,serix_write) - Handler naming: suffix with
_handler(e.g.,timer_interrupt_handler) - Commit format:
<type>(<scope>): <subject>— types: feat/fix/docs/style/refactor/perf/test/build/ci/chore, scopes: crate names
Each subsystem crate has its own README.md. Technical docs in docs/ cover: ARCHITECTURE.md, BOOT_PROCESS.md, MEMORY_LAYOUT.md, INTERRUPT_HANDLING.md, KERNEL_API.md, GRAPHICS_API.md, HAL_API.md, ROADMAP.md.