I wrote a GameBoy emulator for my hobby OS (2022)
Hi HN, author here! The GameBoy emulator written up in this post runs on axle, which is a message-passing microkernel-based OS I’ve been working on for a very long time. dang suggested that I put together a Show HN for axle, which I’d love to do once I have a bit more time to get things into a working-out-of-the-box state!axle is a really fun project for me, and serves as the testing grounds for all kinds of technical experiments. The bore-you-with-features spiel goes something like: x86_64, SMP, UEFI bootloader, TTF rendering, compositing window manager, TCP/IP stack, AHCI driver, custom assembler/linker, and, of course, a GameBoy Emulator!When working on axle, the level of yak shaving can get pretty extreme. For example, when I got around to writing axle’s first network card driver, I was puzzled when my driver could transmit packets fine, but failed to receive any packets. I dug around for quite a while before considering that it might be a QEMU bug, and tracked it all the way to macOS’s incomplete implementation of poll(), which QEMU was relying on! I ended up writing a patch for QEMU to work around it, and, several layers up, was finally able to progress on the network card driver and network stack. This was back in 2021, but I wrote up the journey recently here: https://axleos.com/adding-vmnet-support-to-qemu/axle was mostly C-based for a lot of its history, which can get pretty gnarly both in kernel-space and when trying to write higher-level productivity software in userspace. Recently, I’ve been writing a lot more of in Rust, but for the past couple of years that’s been confined to userspace only. When adding SMP support to the kernel, though, I added Rust to the kernel too. It’s really nice.One other fun thing I’ve been working on semi-recently is a homegrown IDE with an assembler/ELF-linker that runs under axle. I found the linker pretty difficult to get right, because a lot of the ELF data need to know the size and locations of other bits of data in the binary, and it’s tough to shake everything into place in a way that has serial data dependencies! It’s immensely gratifying, though, to write some assembly, generate an ELF at runtime, and execute it. I also added some process-monitoring hooks into the kernel while working on this, so the IDE application can monitor the output of the assembler/linker, and show the output of the generated program, all within the GUI. I uploaded a quick demo video of this IDE here: https://www.youtube.com/watch?v=YG9XyzSBUNg. This whole shebang (IDE + assembler + linker/ELF binary-packer) is written in Rust.Thanks for reading — I hope you enjoy the post, and let me know if you have any questions!