Handmade Hero has been an inspiration to a new generation of programmers. One idea I’ve seen thrown around is to create a new OS. Although I initially dismissed the idea due to the complexity of hardware support, I have decided to provide some of my more constructive musings on what I feel a Handmade OS should look like.
First of all, we have to step back and ask ourselves the most fundamental question: what is an OS for? An OS serves exactly one purpose: To coordinate everything needed to run software on your machine. As such, I feel we can establish some basic tenets that such a project should follow. If we are hogging system resources that the user applications could be making use of, we have failed our job as an OS. This implies:
- High Performance
Language choice within the kernel
It would make sense to build this using a language like Jai. To get high performance, we are going to want to be writing code close to the metal. For this reason, our options are limited to Assembly, and C-like languages.
Lessons from the past
A lot of wisdom can be gained from looking at *nix systems. However, I will not go so far as to say that the system should be a *nix itself.
The system should be modular. Rather than a single project, there should be many projects providing components to the larger whole. An “official” distro could be made, but nothing should stop users from making their own distros. It is vital that components should be able to be swapped out for alternatives.
There are a variety of good filesystems today such as btrfs, ext4, and reiser4. That said, we might want to get away from the HFS model entirely.
I don’t care what people make for desktop environments. I personally would only use a tiling window manager such as an i3 clone.
The shell I feel a bit more strongly about. Shell languages are horrid, and text as a universal interface is undoubtedly dated. I feel that the shell should be a REPL for a real language such as Jai. However, we also must be able to spawn processes, redirect output, etc. with no syntactic overhead. To me, the solution seems obvious. A programs binary should provide a special function signature. The shell can dynamically load these symbols found from the binaries in $PATH, allowing you to invoke processes as if they were regular functions. The output of the function can in many cases be easily piped or redirected with UFCS, or a special composition operator.
A package manager is necessary. There should be packages available in both binary and source forms. Binary packages are convenient the vast majority of the time, but if the user wants to specify custom compile time options or patch a piece of software, a source package system like what gentoo has is ideal. The nix package manager is worth looking at for ideas as well.
Finally, it is important to have good community support and documentation. The Arch wiki is the golden standard here.