← Back to writing

Why I Keep Writing Kernels

I've written six operating system kernels. None of them run anything useful. Here's why I keep doing it — and what each one taught that the last one couldn't.

I’ve written six operating system kernels. None of them run a desktop environment, serve a web page, or do anything a normal person would call useful. The most complete one — TerranoxOS — has 91 syscalls, a capability token system, and an ELF loader. It still can’t run ls.

I keep doing it anyway. Not because I’m trying to build Linux. Because every kernel I’ve written has taught me something about how computers actually work that no amount of reading, tutorial-following, or production application development could replicate.

The Lineage

YearKernelLanguageWhat I learned
~2020Assembly experimentsASMWhat a computer actually executes
~2020KairosOS v1CYou need a libc before you need features
~2020KairosOS v2CBuild systems matter more than you think
2021VoletaCThe toolchain IS the project
2021D ExokernelDLanguage runtimes assume an OS exists
2021IsmenaOSC/ASMDon’t couple your kernel to a runtime you don’t control
2022AstraeaOSASM17 files of assembly teaches what 500 files of C didn’t
CurrentTerranoxOSC/ASMEverything from the first six, applied

Each kernel wasn’t a failure — it was a prerequisite. KairosOS couldn’t exist without the assembly experiments that taught me what the CPU actually does at boot. Voleta couldn’t exist without KairosOS teaching me that the cross-compiler is more important than the kernel features. TerranoxOS couldn’t exist without all of them showing me what to prioritize and what to defer.

Why Kernels, Specifically

There’s a gap between “I use Linux” and “I understand what Linux does.” Most developers live their entire careers on one side of that gap. They know that malloc gives them memory and open gives them a file descriptor and fork gives them a process. They don’t know how those things actually work — what the kernel does between the syscall instruction and the result.

I wanted to know. Not abstractly, from an OS textbook. Concretely, from writing the code that handles int 0x80 and deciding what happens next.

Writing a kernel forces you to answer questions that application development never asks:

  • What happens before main? The bootloader loads your code, switches the CPU to protected mode, sets up a stack, and jumps to your entry point. There is no runtime, no standard library, no heap. You are alone with the hardware.

  • Where does memory come from? Not from malloc. From the physical memory map that the BIOS gives you, which you parse, organize into a frame allocator, map through page tables, and then — only then — can you give memory to anything else.

  • What is a process? A saved register state, a page table, and a scheduling decision. That’s it. Everything else — file descriptors, environment variables, signal handlers — is bookkeeping you choose to add.

  • What is a syscall? A controlled entry point from userspace to kernel space. An interrupt or syscall instruction that switches privilege levels, saves context, dispatches to a handler based on a number in a register, does something, and returns. I designed 91 of them for TerranoxOS, and designing them taught me more about the POSIX API than 10 years of using it.

What This Series Covers

Eight posts, one per kernel era, plus a lessons-learned retrospective. Each post is a narrative — what I built, what broke, what carried forward. Not a tutorial. I don’t think “build your own OS” tutorials work, because the interesting parts aren’t the code — they’re the decisions.

The code for every kernel except TerranoxOS is in the OS Kernel Museum repo, organized by era. Each directory has the original source, a README explaining what it is, and QEMU boot scripts where possible.

The series progresses from the simplest possible executable (a hex-encoded ELF binary) to a kernel with 91 syscalls and capability-based security. Along the way: two custom C libraries, a GCC cross-compiler built from source, an experiment in the D programming language, a Swift runtime that never worked, and a pure assembly kernel that taught me more in 17 files than KairosOS did in 500.

If you’ve ever thought about writing a kernel — or if you just want to understand what happens between power-on and your terminal prompt — this is that story.


This is Part 1 of 8 in the OS Kernel Museum series.