14 Jul 2025
Writing an Operating System from Scratch
This is a blog-ified version of this technical document.
You have to be all kinds of crazy to build a kernel from scratch. Much less build a kernel, a bootloader, a filesystem, a libc implementation, and a text pager and an image viewer for that kernel, from scratch.
No, for that you have to be both stupid and stupidly naive.
Why?
Technology today is layers and layers of software all folded in on itself. Not really simple, and not really easy to understand the entire stack, top to bottom. So I decided to build my own everything, from bootloader to C Standard Library, just to understand how things work.
What?
BoinkOS, or more formally the Boink Kernel Project, aims to provide a reasonable abstraction for every single layer between user and bare metal –
- filesystem (GLFS)
- bootloader (Boink Interactive Bootloader)
- kernel (BoinkOS)
- text pager (with Included Search Function (tm))
- image viewer
- syscall interface
- custom libc
“Allegedly Good Features” I added that definitely did not start as dumb ideas
Of course, starting from scratch gives you ideas for features that you don’t see often, and Boink has two such features:
- kernel scratchpad
provides 16kb of “scratchpad” space for the kernel to use — avoids page management where it may not be needed. - panic debug shell
provides a way to easily debug programs when a panic state is entered. really helpful when you don’t have gdb.
Milestones
Some (overkill) milestones were (slowly and tediously) achieved on this platform.
- custom 32-bit protected mode bootloader with VESA graphics
- paging and frame allocation
- syscalls + userland mode (ring3) context switching
- ELF binary loading and execution
- basic shell with file viewing, image viewing, and app execution
- interrupt handling with IRQs, ISRs, PIT, and keyboard input
- simple framebuffer-based graphics output
- GLFS — a simple loadable filesystem baked into the boot process
A Wild Filesystem Appears
GLFS (good little (luck) file system) is an extremely simple filesystem spec that Boink uses.
[sector 0] GLFS SUPERBLOCK
----------
- magic GLFS+version identifier
[sector 1+] DIRECTORY TABLE
-----------
[entry 0] filename: string
start sector: int
size: int (bytes)
[entry 1] filename: string
start sector: int
size: int (bytes)
(...)
[end of table marker]
----------
[file data]
(...)
Yes, that’s it. Just a superblock, a directory table, and files. No folders, no journaling, no metadata, no permissions… just data.
Coda
OS dev is one of those weird hobbies where you can go weeks without your system doing anything at all, end up backtracking days of work just to implement everything again, and then you fix a random paging bug and it suddenly boots a shell and you feel like god. I definitely did not spend a day debugging the VESA graphics after writing VESA info to one location and trying to read it from a completely different location. Definitely.
Next up at some unspecified date in the vague future: Boink 2: UNIX Boogaloo
“How did you do it?”
“It’s very simple — you read the protocol and write the code.” — Bill Joy, definitely forgetting the mental spiraling bit
Screenshots
First Steps — printing to the screen in VGA text mode
GLFS disk reads
VGA framebuffer graphics
Less-inspired Text Pager
Panic diagnostic shell
Boink Interactive Bootloader
Bitmap Image Viewer
ring3 context switching
Custom libc with basic I/O support
Read more —
Compiling Textmate 2: Rendering Boogaloo
Getting TextMate to show up right on macOS Tahoe
8 Jun 2025
RIP, Bill Atkinson
21 Apr 2025
Cataloging my books with ISBN barcodes and Google Books
Barcodes are a godsend.
< all blog