Why this exists — and why it isn’t AI slop
The goal was never “how to build an OS.” It was turning abstractions you’ve only ever trusted into mechanisms you can hold in your head: a task is a saved stack pointer; a file is a header’s lie about flat bytes; a directory is that same lie one level down; preemption is the switch a task would make voluntarily, forced by a timer it can’t refuse — and a proof that validation terminates is not a proof that it’s safe.
Fair question in 2026: is this just a model that emitted a plausible-looking kernel? No — and here is the case, as three claims you can check yourself, not take on faith.
Every milestone ships a deterministic self-test, asserted by CI on boot: a freed frame handed back out, a file’s exact bytes round-tripped, ten malformed disk images rejected — a directory cycle among them — with no hang.
Every milestone gets an adversarial multi-agent code review that found real latent bugs before shipping: a deadlock that only fires when the timer preempts a task mid-lock; a tree validator a crafted image could hang or stack-overflow.
Every write-up documents what broke, what was deferred, and the checks left un-done. The dead ends are in the build log on purpose — not sanded off after the fact.
Think → Plan → Build → Review → Reflect loop; the AI does the mechanical work inside that harness; and the whole trail — plans, reviews, self-tests, retros — is public, so the rigor is checkable, not asserted.
Slop is what you get when you skip the harness. This is the harness.
A faithful reconstruction of the real kernel’s boot output.
How this works — the technical bit
Guided tour
Everything the kernel prints, and what it means
This is the exact output above — but each line you can open is a small window into the layer that produced it. Nothing here is decorative; it’s what the machine actually did.
Where this is going
Run the real thing yourself
The whole point is to build it, not just watch. Clone it and boot the actual kernel under QEMU:
make # assemble + compile + link
make run # boot it in a QEMU window
make debug # boot frozen, attach GDB
Then read the source and the concept docs, and follow the milestone build-log. Each milestone is one working state and one honest write-up — including what broke.
A plain-language glossary
This page uses a lot of words that only mean something once you’ve written kernel code — and that’s a chicken-and-egg problem. So here’s a friendly dictionary and a few honest answers. You don’t need any of it to enjoy the tour; open whatever’s puzzling you and read just that.
What am I actually looking at?
Two things side by side. On the left is a little pretend computer with a green screen — an operating system booting up. On the right is a guided tour that asks you to guess what happens next, then explains why it happened.
The “operating system” here is hand-written from scratch: there is no Windows, macOS, or Linux underneath it. Every line it prints, someone wrote the code that makes it appear — and the tour walks you through that, one layer at a time.
Is this a real operating system?
It’s a real kernel — the innermost, hardware-facing core of an OS — and it genuinely works: it boots itself, prints to the screen, catches errors, reads your keystrokes, and figures out how much memory the machine has. All from nothing.
It is not yet something you’d install and use, though. It can’t run programs, doesn’t have files, and has no windows or apps. Those are the later milestones on the roadmap above. Think “the engine and chassis, being built in the open,” not “a finished car.”
Is it really running inside my browser?
Honest answer: what you see is a faithful reconstruction — every line on that green screen is exactly what the real kernel prints, replayed here. It is not a mock-up or marketing text; it’s the true output, character for character.
The genuinely-live 64-bit kernel runs under QEMU (a full PC emulator) on a real computer — see “Run the real thing yourself” above. The in-browser emulator this page uses, v86, only emulates a 32-bit PC and can’t switch into the 64-bit mode our kernel needs, so it can’t run the real kernel yet. Rather than fake it, the page is upfront that this is a reconstruction.
Why build an operating system from scratch at all?
To understand every layer instead of trusting it as magic. An OS isn’t one big mysterious thing — it’s a stack of small, knowable mechanisms, and each one is something a person can hand-write and reason about.
The goal of this project isn’t to ship a product; it’s understanding, with a public trail of how it was built — including the dead ends and the bugs. This page exists so that trail is something you can boot and poke at, not just read.
Where do I go to learn more?
The plain-language explainers this glossary is drawn from — written for people who’ve never done kernel work — live in the repo:
interrupts.md · keyboard-and-pic.md · physical-memory.md · the build log
Every claim on this page also links straight to the real source code — look for the ↗ links in the tour and the line-by-line log above.
The words, grouped by when they show up
01The big picture
- Operating system
- The software layer between the hardware and the programs you run. It shares out the processor, memory, and devices so each app doesn’t have to know the raw machine. Ziran OS is one being built from zero.
- Kernel
- The core of an operating system — the part that actually talks to the hardware and stays in control of the machine. Right now Ziran OS is almost entirely kernel.
- Bare metal
- Running directly on the (here, virtual) hardware with nothing underneath — no OS to borrow services from. Anything you’d normally ask an OS for, you build yourself.
- Rust / no_std
- Rust is the language the kernel is written in.
no_stdmeans “without the standard library” — that library assumes an OS is there to call, so a kernel opts out and uses only the bare language plus the machine. No garbage collector, no runtime, nothing beneath it. - Emulator (v86)
- A program that pretends to be a whole PC in software, so an OS can run inside an ordinary window or browser tab.
v86is the specific one this page uses; it emulates a 32-bit PC.QEMU, used for the real kernel, emulates a full 64-bit one.
02Turning the machine on
- BIOS
- The tiny firmware baked into a PC that runs first at power-on, does basic setup, and then loads a bootloader. (In the browser these are the
seabios/vgabiosfiles.) - Bootloader / GRUB
- The program that loads the kernel into memory and jumps into it. GRUB is a common one; it also surveys the machine beforehand and hands the kernel a map of the memory it found.
- Multiboot
- A shared agreement — a header format — between bootloaders and kernels, so any Multiboot-aware loader like GRUB can start the kernel and pass it standard information (like that memory map).
- Protected mode / long mode (32-bit vs 64-bit)
- Modes the processor can run in. A PC powers on in a primitive 16/32-bit mode; long mode is modern 64-bit mode. Getting there is a deliberate ritual — check the CPU can do it, build the first memory tables, then flip the switch. The line
reached 64-bit long modeis that ritual finishing.
03Talking to the world
- VGA text buffer
- A special block of memory (at address
0xb8000) that literally is the text screen. Store a character byte and a colour byte there and the letter appears — no driver, no library. That’s the whole “graphics stack” at this stage. - Serial output
- A simple, one-character-at-a-time output line (a virtual serial port) the kernel uses for detailed logs, kept separate from the visible screen. The verbose memory dump goes here; the screen gets the one-line headline.
- Interrupt
- A signal that makes the processor stop what it’s doing, handle an event, and (usually) resume as if nothing happened. It’s how a machine reacts to the outside world — a key, a timer — without constantly checking. The single most important idea in how an OS stays in control.
- Exception
- An interrupt the processor raises against itself because the current instruction went wrong — dividing by zero, touching memory that isn’t there. Same machinery as a hardware interrupt, but caused by the code.
- IRQ
- “Interrupt request” — a hardware interrupt raised by a device. It can arrive at any moment. The keyboard is
IRQ1; the timer is IRQ0. - IDT (interrupt descriptor table)
- An array of 256 entries that maps each interrupt number to the function that handles it. When something interrupts the CPU, it looks up the number here and jumps. Without a valid entry, the fault escalates instead of being handled.
- PIC (programmable interrupt controller)
- The chip that collects devices’ interrupt lines and hands them to the CPU one at a time. It has to be “remapped” at startup so its signals don’t collide with the CPU’s own exception numbers — and acknowledged after each one, or the keyboard goes silent after a single press.
- Breakpoint / int3
- A special, recoverable interrupt (number 3) that’s meant to be caught and resumed. The kernel fires
int3on purpose: surviving it proves the entire interrupt path works end to end. - Scancode / PS/2 keyboard
- The keyboard doesn’t send letters — it sends scancodes, small numbers identifying physical keys, which the kernel reads and translates into characters (with a lookup table, one per layout). Pressing a key and releasing it are two separate events.
- Triple fault
- What happens when a fault fires, the handler for it also faults, and that fault faults too. The processor gives up and resets the machine — a silent reboot with no message. Avoiding these is exactly why the IDT above matters; it’s the most disorienting thing in early OS work.
04Managing memory
- Physical memory / RAM
- The actual memory chips, named by physical address. Surprisingly, it’s a patchwork — some of it is real writable RAM, some is reserved by firmware, some is devices in disguise, and some is just gaps. The kernel starts out blind to how much it even has.
- Frame / frame allocator
- Usable RAM is chopped into fixed 4 KiB chunks called frames. The frame allocator is the bookkeeper that hands a free frame out, takes it back when done, and — the part that makes it real — can hand out that same frame again later. It’s the bottom stone of the memory stack.
- Virtual memory / paging / page tables
- A hardware trick where every address a program uses (a virtual address) is translated to a real physical one through lookup tables called page tables. It lets memory be protected, relocated, and handed out flexibly. This is now built: the kernel constructs its own page tables from frames and switches the CPU onto them, so it manages its own memory map. The heap (the next milestone) grows on top of it.
- TLB
- A small cache inside the processor that remembers recent virtual→physical translations, so paging stays fast instead of walking the page tables on every single memory access.
- Heap / allocator
- The heap is a pool of memory set aside for data whose size isn’t known until the program actually runs — anything that grows. The allocator is the bookkeeper that hands out pieces of it on request and reclaims them when you’re done, so the space can be reused. It’s what makes
Vec,Box, andStringwork; the kernel wrote its own and backed it with pages it mapped itself.