Writing an OS kernel using a tutorial from OSDev.org

Saturday, April 23, 2022

Check this out! 😉

Kernel screenshot

It’s my first kernel! 😃

It’s a 32-bit x86 kernel which can only output things to the screen, so it’s nothing exciting yet. No memory management, no inputs; just output to the screen.

It was written by following the guides provided in OSDev.org. In particular, following the Bare Bones tutorial. It starts off with preparing a GCC cross-compiler (for C and C++) for i686-ELF, the proceeds to introducing the bootstrap assembly, the kernel itself and linker script to prepare the kernel image. The booting process is simplified by just using GRUB instead of writing a bootloader from scratch, so aside from the bootstrap assembly, we aren’t programming very close to the metal.

Noteworthy is that at this point, we have no C standard libraries, so we’re poking directly at the memory for all interactions. The kernel source is mostly functions to interact with the memory to display things on the screen. (Well, after all that is all it really does.)

I went through and hand-typed the tutorial code in vim, to understand it as I go along. For example, leaving some comments like this one, snickering at parts of the implementation:

void term_putchar(char c) {
    term_putcharat(c, term_color, term_col, term_row);

    /* advance a character, go to next line if at end of row */
    if (++term_col == VGA_WIDTH) {
        term_col = 0;
        if (++term_row == VGA_HEIGHT) {
            /* LOL wrap to top of screen, hehe. */
            term_row = 0;

By the end of the tutorial, we get a kernel that print “Hello World” and halts the machine. In fact, the printing routines didn’t support newlines so I immediately implemented it, to find out that was the first “next thing to do” suggested by the tutorial 🤣 Next up was implementing terminal scrolling when reaching the bottom of the terminal, rather than wrapping to the top, as seen in the above code snippet.

Once the scrolling was implemented, I wrote a “demo” to show an asterisk fly back and forth on the screen:

And that’s basically as far as I got. I started around 3 AM and kept tinkering until 6 in the morning, so I had to call it a night morning.

Nice part of this tutorial is that we start off with preparing the GCC cross-compiler. (Aside from well-utilizing my multiple cores when building the compiler with make -j<N>, which actually wasn’t mentioned in the tutorial 🤔) This means we’re using a modern compiler that supports modern dialects of C which is a lot nicer than using something like C89. Just a bit of peace of mind of not having to fight with tools.

Speaking of tools, using an IDE just to make life easier than pecking at code in vim. Eclipse CDT (which I haven’t used in a while) is free, but perhaps I should consider shelling out cash to use Jetbrains CLion? First I should try the demo version 😉

Anyway, now that I’ve written up my thoughts so far, back to kernel hacking 📝