3.2 KiB
AGENTS.md
Project
curiOS is an x86-64 OS kernel written (mostly) from scratch in Rust. It boots via
Limine and runs in QEMU. A companion blog in
org-mode format lives in blog/.
Workspace layout
Cargo workspace with members crates/* and kernel:
kernel/— the kernel:no_stdlibrary crate (src/lib.rs) plus ano_std/no_mainbinary (src/main.rs). Custom target specx86_64-unknown-kernel.json;.cargo/config.tomlwires up the target,build-std, and the QEMU runner.crates/rbtree/— a no_std red-black tree crate used by the kernel's physical memory manager. Unit-tests on the host (it opts intostdundercfg(test)).
Toolchain
- Rust nightly (edition 2024) with many unstable features — see the
#![feature(...)]lists at the top ofkernel/src/lib.rsandcrates/rbtree/src/lib.rs. - Development environment is a Nix flake devshell (direnv via
.envrc). It provides the toolchain plusqemu,limine-full,OVMF,mtools,clang,gdb,mold, etc. - The kernel is built with
build-stdand the custom target; do not build it for the host target.kernel/.cargo/config.tomlsets the target and ajson-target-spec-enabled nightly; rust-analyzer needsCARGO_UNSTABLE_JSON_TARGET_SPEC=true(seekernel/.dir-locals.el).
Build & test
Run these from inside kernel/ (the workspace root uses the host target and won't
build the kernel binary):
cargo build # build the kernel (runs build.rs which links kernel/kernel.lds)
cargo clippy # lint
cargo fmt --check # format check
cargo run / cargo test invoke kernel/run.sh via the runner in
.cargo/config.toml, which boots the kernel in QEMU. Tests are special [[test]]
binaries (e.g. kernel/tests/simple.rs, stack_overflow.rs) that run inside the
kernel in QEMU with a custom test harness (harness = false) and exit via the
QEMU isa-debug-exit port:
cargo test # run all integration tests in QEMU
cargo test --test simple
crates/rbtree runs its unit tests normally on the host (cargo test from
crates/rbtree/).
The test framework (#![cfg_attr(test, custom_test_frameworks)] with test_runner
from kernel/src/tests.rs), QEMU exit handling, and the Testable trait live in
kernel/src/testing.rs and kernel/src/tests.rs. A #[panic_handler] is defined in
the test binaries — don't add another.
Conventions
no_stdeverywhere in kernel code;extern crate allocwhere allocation is needed.- Unsafe blocks require a
// SAFETY:comment justifying the invariant. - Use the
serial_println!/serial_print!macros for logging (defined inkernel/src/serial.rs) — there is no std output. - Kernel-wide statics prefer the
sync::LazyLockwrapper inkernel/src/sync/mod.rsover barestatic mut. - Follow existing patterns in
kernel/src/x86_64/(GDT, IDT, paging, cpuid) for new arch code. #[cfg(test)]gate test-only modules and items.- No comments unless they convey something non-obvious (e.g. safety justifications).
Commit style
Short lowercase messages, crate: prefixed, e.g. kernel: fix unsafenode impl,
rbtree: fix compile warnings.