TerranoxOS is the kernel that knows what it’s doing. Not because I’m a better programmer than when I wrote KairosOS — though I am — but because every decision in TerranoxOS was informed by a specific failure in a previous kernel.
It’s also the first kernel I’ve built with AI assistance. Claude handles the boilerplate — syscall table scaffolding, header file generation, documentation — while I make the architecture decisions. The division of labor is surprisingly clean in kernel development, where the hard parts are design decisions (what should this syscall do?) not implementation details (how do you declare a function pointer array in C?).
The 91-Syscall ABI
KairosOS had maybe 5 syscalls, added ad-hoc as I needed them. TerranoxOS has 91, designed as a coherent ABI before implementation started.
The syscalls are organized by category:
| Range | Category | Examples |
|---|---|---|
| 0-9 | Process | fork, exec, exit, wait, getpid |
| 10-19 | Memory | mmap, munmap, brk, mprotect |
| 20-29 | File I/O | open, close, read, write, seek, stat |
| 30-39 | Directory | opendir, readdir, mkdir, rmdir, chdir |
| 40-49 | Network | socket, bind, listen, accept, connect |
| 50-59 | IPC | pipe, shmget, semget, msgget |
| 60-69 | Signal | kill, sigaction, sigprocmask |
| 70-79 | Time | gettimeofday, nanosleep, clock_gettime |
| 80-89 | System | mount, umount, reboot, sysinfo |
| 90 | Capability | cap_grant, cap_revoke, cap_check |
Why 91? Because I listed every operation a libc needs to wrap for a POSIX-like environment, organized them into categories, and numbered them. The range-based numbering isn’t required by the CPU — syscall dispatch is just an array index — but it makes the ABI readable. You can look at a syscall number and know its category without checking a table.
Designing the ABI before implementing it was the lesson from KairosOS. When syscalls are added ad-hoc, the numbering is arbitrary, the argument conventions vary, and the error handling is inconsistent. When the ABI is designed up front, the implementation follows the specification — and a specification is something you can review, discuss, and get right before writing code.
Capability Tokens
The most architecturally distinctive feature. Instead of UNIX-style permission bits (owner/group/other, rwx), TerranoxOS uses 128-bit capability tokens for permission management.
A capability token is an unforgeable reference to a resource with associated permissions. To read a file, you don’t check “does this user have read permission on this file.” You check “does this process hold a capability token that grants read access to this file.”
typedef struct {
uint64_t resource_id; // what resource this grants access to
uint64_t permissions; // bitmask of allowed operations
uint64_t issuer; // who created this token
uint64_t expiry; // when it expires (0 = never)
} capability_t; The advantage: capabilities are transferable, revocable, and fine-grained. A process can grant a subset of its own capabilities to a child process. Revocation is a tree operation — revoking a capability revokes all capabilities derived from it.
The idea came from the D exokernel experiment. Exokernels expose hardware resources directly, and capabilities are the natural access control mechanism. TerranoxOS isn’t an exokernel — it has a traditional syscall interface — but the capability system gives processes fine-grained control over what their children can do.
The ELF Loader
The assembly experiments started with writing ELF headers by hand. TerranoxOS closes the loop by parsing them in the kernel.
When exec is called, the kernel:
- Reads the ELF header from the file
- Validates the magic bytes (
\x7fELF), architecture (x86_64), and type (executable) - Iterates through the program header table
- For each
PT_LOADsegment, allocates pages and copies the segment data - Sets up the user stack with
argc,argv, andenvp - Transfers control to the ELF entry point
This is what the Linux kernel does when you run ./program. I understood it abstractly after writing ELF headers by hand in the assembly era. I understood it concretely after implementing the parser in TerranoxOS.
What Carried Forward from Each Kernel
| Previous Kernel | Lesson Applied |
|---|---|
| Assembly experiments | ELF loader — I know the format because I wrote it by hand |
| KairosOS | Design the syscall ABI before implementing it |
| KairosOS v2 | Build system as first-class infrastructure |
| Voleta | Naked toolchain, sysroot structure, libc as independent component |
| D exokernel | Capability-based access control |
| IsmenaOS | Don’t depend on external language runtimes |
| AstraeaOS | Understand every byte of the boot sequence |
TerranoxOS isn’t better because I’m smarter. It’s better because it benefits from 6 previous attempts, each of which failed in a specific, instructive way. The architecture is the distillation of those failures.
Building with Claude
The AI pair-programming angle is worth discussing honestly. Claude is useful for kernel development in specific ways:
Good: Syscall table scaffolding, header file boilerplate, documentation strings, test case generation, explaining obscure CPU manual sections, generating linker script templates.
Limited: Architecture decisions (what should the capability revocation model look like?), debugging kernel panics from register dumps, understanding hardware-specific behavior (why does this PCI device not respond to BAR configuration?).
The split is roughly: Claude handles what (the syntax, the boilerplate, the rote implementation) while I handle why (the design, the tradeoffs, the decisions that make TerranoxOS different from “yet another hobby OS”). This division works well because kernel development has a high ratio of design-to-code — the hard parts are deciding what to build, not typing the implementation.
What’s Next
TerranoxOS is an active project. The 91-syscall ABI is specified; maybe 30 syscalls are implemented. The capability system works for basic access control; the revocation tree is incomplete. The ELF loader handles static binaries; dynamic linking is future work.
It will probably never run a desktop environment. But it will have a complete syscall ABI, a working capability system, and a well-tested ELF loader — the three things I’ve been building toward across six kernels and five years.
This is Part 7 of 8 in the OS Kernel Museum series.