Serenity on Bare Metal
Jun 2, 2019
3 minutes read

While you're reading this, keep in mind that I'm available for hire! If you've got a JavaScript project getting out of hand, or a Golang program that's more "stop" than "go," feel free to get in touch with me. I might be able to help you. You can find my resume here.


Serenity is an open source operating system created by Andreas Kling. Halfway between Windows 98 and early 2000’s UNIX, it’s described as “a love letter to ‘90s user interfaces, with a custom Unix-like core”. I’ve been poking around at it a little bit, and I’ve decided to take a great big bite and try to run it on actual hardware.

I’ll update this post with more details as I go.


The first thing I had to do was get something to load Serenity outside of qemu’s kernel support mode.

I modified to create a disk image with a partition map using a loopback device and parted, wrote a minimal grub config to load the kernel, and put it all together. This got the kernel running, but it immediately failed trying to mount the root filesystem. This is because the disk driver expects the filesystem to start on the first block of the disk. With an MBR partition header in place, this is not true.

To get the root filesystem mounted, I wrote a DiskDevice implementation that simply translates the read/write indexes by a static offset, and called it OffsetDiskDevice. I’ve hardcoded that to 62 right now, as that’s where I’ve chosen to put the first partition. Later on I’ll write an MBR driver that can read the partition table and create an OffsetDiskDevice according to its contents. We can expose some functions from that MBR loader to the kernel too, so the system can mount additional partitions after boot.

2019-06-02 7:52PM - we’ve decided to rename OffsetDiskDevice to DiskPartition, to prepare for MBR loading support.

2019-06-02 11:02PM - MBRPartitionTable has landed - no more hardcoded offets!

2019-06-03 2:04PM - I sure wish I had an easier way to boot this on real hardware. Right now I have to boot from a USB drive running linux, image the hard drive, then reboot. If I have to go through this too many more times, I’ll set something up on the hard drive to load linux from a different partition and pull the Serenity filesystem image down over the network or something.

Photo Log

2019-06-02 4:33PM - this image is from the first partial boot. The root filesystem was still on a USB drive, so the kernel couldn’t read it.

2019-06-02 5:16PM - this is the second partial boot. The root filesystem is now on the machine’s hard drive, but something is not quite right. The kernel stops while it’s trying to load itself into memory.

2019-06-03 1:36PM - we can see that it’s reading some stuff from the disk correctly.

2019-06-03 1:54PM - apparently we didn’t dump enough content out to the screen. Some of the ksym entries are corrupted, and my guess is that the hex parsing failure is related.

Back to posts