If there ever was a true sandbox project that would top my first "game engine", this would be it. One man cannot simply write an entire
operating system. But what if he tried anyway? Turns out, it's no surprise I'm not going to replace my daily driver tomorrow, but if
you're a fan of very low-level programming and want to learn how OSes really work, that's for you.
There is just so much to learn and so much to do. There are many hardware standards in the PC world today (keyboard, Microsoft PS/2 mouse,
PCI, ACPI, USB, VGA, ...), and writing drivers for all of them is quite the exercise. Not only that, but there are also many processor
architectures out there. Intel's x86 is a good starting point, ARM is next if you own a Raspberry Pi.
kdOS is a very tiny 32-bits hobby operating system, featuring a monolithic kernel.
It supports booting from a legacy BIOS and UEFI, multitasking, various common file systems, and provides a terminal as its main shell.
The boot process
Again, for practice and study purposes, I decided not to go with GRUB and instead roll out my own boot manager.
I did say boot "manager" and not bootloader. That is, I want to make a versatile bootloader that can recognize multiple installed kdOS
instances, and maybe other OSes.
The boot process is different depending on the environment. If you're not familiar with how PCs boot at all, let me explain :
BIOS / CSM : If your motherboard's firmware contains a legacy BIOS (or UEFI with a Compatbility Support Module), then congrats,
you're going to have a bad time. The BIOS looks in order for a bootable drive, by reading the contents of the first sector. A sector
on a disk is usually standardized to 512 bytes. The first sector is called the MBR (Master Boot Record) and is what contains
the code for the bootloader. That's right, 512 bytes to kick off the entire system. Moreover, at this stage, the CPU is still
in 16-bits mode (called "real mode"). You can only access 1 MiB of memory, and need to transition to 32-bits "protected" mode
(or 64-bits "long" mode) manually.
MBR systems usually use the first bootloader as a "stage 1" whose purpose is to load and execute a stage 2, which has more space
to initialize the required stuff.
UEFI : Starting 2009, it's possible your motherboard supports the new stuff, and it's the best. The CPU is already in
protected or long mode, the boot services are much more powerful, and the firmware can even understand file systems. Even
better, EFI executables are not bounded to 512 bytes, and you don't have to write them in assembly. Heck, an executable could
even serve as your kernel, no bootloader required.
However, this does make UEFI images significantly larger and more complex, which means you do have to pay attention to which
memory sections are used by it, as to not corrupt the booting environment.
Either way, regardless of the boot process that starts the system, we want the same kernel, because it's easier, and having a single
install disc that works for any type of machine is a lot better for the end user and more flexible for us. Therefore, the bootloader's
main task is to prepare the CPU and memory in a way that the kernel expects. That includes passing parameters, retrieving the memory
layout (hardware-mapped, reserved, free, total amount of RAM...), the current video mode, and more.
What's missing?
Calling kdOS an "operating system" is definitely an overstatement. This is a hobby project and will likely never become usable as a
daily driver. It does not support many technologies that are crucial today, and it would have to be updated once a new tech comes out.
For example, here are some major capabilities it does not support :