Most operating-system tutorials end at the moment things start getting interesting.

They get you to a booting kernel. Maybe you print text to the screen, allocate a few pages of memory. That is pretty cool, but it’s not yet an operating system in the way most people mean it.

There are no programs in it. Yours or… other people’s, ideally. It lacks a scheduler to run them, a filesystem to read them from, an isolated environment that prevents someone’s badly vibecoded app from breaking your PC, and a graphical interface to even display them on.

So how do you run Doom? Or anything useful, for that matter?

This blog is an attempt to cross that gap for you, while AlkOS was our attempt to cross that gap for us.

We built a monolithic, general-purpose x86-64 kernel, with a hardware abstraction lay… blah blah blah.

We built everything that enables you to compile somebody else’s project for our OS and run it inside.

But that list we just omitted right above? It directly shows you that there are a lot of components, and implementing each only drives new questions and new questions:

Once a scheduler runs, what does it schedule? You have memory, cool, but what did you put in it? Do you have files? Do you have a filesystem? Once user programs exist, how do they enter the kernel safely? What if someone runs a while (true) do nothing program? How the f*** do I build complex memory management structures when I can’t even manage my own memory yet?

This blog is about questions we wished someone had answered along the way. It’s also a roadmap for allll of the components that you’ll find yourself at least considering implementing if you wish to make your own OS.

Why this exists

We started AlkOS blind. Not much OS background. Some low-level experience, university coursework, and, ymm, a level of stubbornness clearly too big for our own good.

So the first thing we did was go online: invaluable, and equally as frustrating. OSDev Wiki? Great help. Like, impossible to even start without. But then you go a bit further and further and find that some pages are excellent, others are old. Others are incomplete, or assume you have knowledge you don’t, because you’re not an OS dev (yet?). The further you go along the line, the more stranded you are. Then you go into the deep waters, and then, my friend, you are out of luck.

So you move from the web to textbooks. Or papers. Whatever you can grab. One sentence: Nice theory, bro - how do I implement that? Clearly explained concepts feel nice until you realize you actually have to build them… and your page fault handler just triple-faulted because you used the wrong compiler flag, and you just realized every function call is randomly offset by 4 bytes at the binary code level but invisible in code.

Yeah…

Then there are production kernels. And they’re good. You can learn a ton. You just have to basically reverse engineer decades of coding across millions of lines of code. GLHF. Do you really need to look at all the drivers, architecture ports, compatibility shims, and optimizations to understand the core of it? I’d rather not. It’s unrelated to the core concepts of the kernel, which aren’t that complex, really.

So we learned by pushing forward. Implementing something. Hitting a wall. Pondering the orb like a wizard until the solution was revealed to us in a dream.

The hardest part was not a single mechanism. It was building a stable mental model of the whole machine. Which parts are needed for what. What the whole machine even consists of. Where are we going? The tutorial says create this thing, but what do I even need it for?

And it worked. But it was expensive. And if we knew a better way, we’d use it. Hence this blog.

What you should get from it

Each post will have a clear structure: explain the concept at the OS level, what this component does for you, and what design space exists. Then we narrow it down to the concrete architecture that AlkOS targets, mostly x86-64 (we implemented x86-64). Then we connect the idea to AlkOS code and consider the tradeoffs we made. When a topic runs deeper than a single post, we give you references we found useful.

We don’t want this to be “memorize x86-64 trivia.” Page tables, interrupts, syscalls, timers, etc. exist on every serious architecture, even if perhaps in some slight variations. Anyway. The concept comes first.

AlkOS (obviously) is not a production OS. And when that difference matters, we say it.

I’m not sure what you get out of this. But a cool learning place is a start.

Who we are

We are Jakub Lisowski, Adam Ogieniewski, and Łukasz Kryczka. We started AlkOS as students with almost no kernel experience and finished with a working system that runs Doom, a thesis, and a much better understanding of what is gooooin on in software.

This changes how you read programs. You stop seeing syscalls as magic. You stop seeing threads as something abstract. It becomes real, concrete. You know exactly what’s happening down to the hardware. And that’s when you start thinking about the system state: which CPU, which stack, which address space, which privilege level, which interrupt state?

We would do the hard parts again.

That’s the real value of building a kernel. It doesn’t matter if you ship an OS. You work with it - you get to know it. Then you understand it. And then you come back to every other program with a completely different frame of mind.

Who is this for

You want to understand computers deeply? You’re in.

(Or maybe build an OS?)

You don’t need previous kernel or driver experience. But here’s the knowledge we assume:

  • C or C++: pointers, structs, explicit memory ownership, undefined behavior, and low-level build errors should not be new territory.
  • A Unix-like shell: you know working with one.
  • Build systems: Make/CMake, compiler flags, object files, and a littttttttttle sprinkle of assembly should feel approachable.
  • Basic CS: arrays, queues, trees, hashing, complexity, and concurrency basics will appear often.

The code

It’s open source. Check it out: https://github.com/AlkOS-Dev/AlkOS.

Let’s begin

The first practical problem is getting to a place where kernel code can be compiled, linked, booted, and debugged without accidentally depending on the host operating system.

So the next post starts at the floor: freestanding code, cross-compilers, CMake toolchain files, QEMU, and the development loop you need before the kernel can safely grow.

It’s coming soon, watch out :D