frostbyte

A hobby x86_64 OS kernel in C and assembly. It boots via Multiboot2, switches to 64-bit mode with its own page tables, has a preemptive scheduler and runs ring-3 programs - it genuinely boots in QEMU.

frostbyte
TL;DR

An operating system kernel written from scratch - from the bootloader all the way to running your own programs in user mode. It genuinely boots, in QEMU.

Overview

frostbyte is a hobby x86_64 kernel written in C and assembly. The goal was not to write an "operating system" in the everyday sense, but to walk the whole path that is usually hidden: from the moment firmware hands over control, to executing your own program in user mode, isolated from the kernel.

It is one of the most unforgiving kinds of project you can set yourself. There are no libraries handling anything for you, and no layer that will catch a bug. There is a bare CPU, the architecture manual, and you. That is exactly why it is such a good school.

In an ordinary program a bug is local: an exception fires, you get a stack trace, you fix a line. In a kernel none of those comforts exist. One wrong bit in a page table and the machine just resets - no message, no log, nothing. Debugging turns into reading registers and guessing which of your last three moves was the fatal one.

That harshness forces a different way of working. Every step has to be closed off and checked in isolation before the next one goes in, because otherwise you cannot tell which of ten changes crashed the whole machine. Discipline here is not a virtue but a condition for moving forward at all.

From firmware to ring 3

The whole path is a sequence of transitions between ever higher levels of control. Firmware loads the kernel via Multiboot2 and hands over a memory map. Then 64-bit mode has to be enabled, which requires some early paging first. Next the kernel takes over virtual memory on its own page tables, starts a scheduler that switches tasks on a timer interrupt, and only at the end jumps to ring 3.

1
Multiboot2 boot

the bootloader loads the kernel and hands over a memory map.

2
Switch to 64-bit mode

enabling long mode requires some early paging first.

3
Own page tables

the kernel takes over virtual memory management.

4
A preemptive scheduler

a timer interrupt switches tasks, without their consent.

5
Ring 3

a jump into user mode and running the first program of our own.

The path from power-on to your own program

StageWhat happensMode
Multiboot2firmware hands over control, a memory map existsring 0
Long modeentering 64-bit modering 0
Page tablesthe kernel takes over virtual memoryring 0
Schedulerthe timer switches tasks without consentring 0
Ring 3the first program, cut off from the kernelring 3

Debugging when the machine just vanishes

Since a bug leaves no trace, we needed a way for the kernel to say anything before it has a screen driver. The answer is QEMU with output on the serial port: the kernel writes logs as text to serial, and that goes straight to the terminal. This way you see the last line before the reset instead of a black screen.

run.sh · bash
qemu-system-x86_64 \
  -cdrom frostbyte.iso \
  -m 512M \
  -serial stdio \
  -no-reboot -no-shutdown
!
Warning

In kernel mode there is no "almost works". A bug in a memory mapping does not crash a function - it crashes the whole machine. That is why every step was tested on its own in the emulator before the next one went in, and the no-reboot and no-shutdown flags keep the machine frozen on a fault instead of vanishing into a restart loop.

The result: a system that genuinely boots

What comes out is a kernel that really boots in QEMU and gets to running its own program in ring 3 - it does not stop at printing "hello" but walks the whole way to user mode. It is a project built to understand the computer down to the very bottom, taken to the point where that understanding is proven by running, not declared.

More projects

More work from the same category - see how we tackle similar challenges.

Have a similar project?

Get in touch - a quote is free and comes back within an hour.