Writing an OS in Rust

Philipp Oppermann's blog

Writing an OS in pure Rust

Over the past six months we've been working on a second edition of this blog. Our goals for this new version are numerous and we are still not done yet, but today we reached a major milestone: It is now possible to build the OS natively on Windows, macOS, and Linux without any non-Rust dependendencies.

The first edition required several C-tools for building:

We got lots of feedback that this setup was difficult to get to run under macOS and Windows. As a workaround, we added support for docker, but that still required users to install and understand an additional dependency. So when we decided to create a second edition of the blog, originally because the order of posts led to jumps in difficulty, we thought about how we could avoid these C-dependencies.

There are lots of alternatives to make, including some Rust tools such as just and cargo-make. Avoiding nasm is also possible by using Rust's global_asm feature instead. So there are only two problems left: the bootloader and the linker.

A custom Bootloader

To avoid the dependency on GRUB and to make things more ergonomic, we decided to write our own bootloader using Rust's global_asm feature. This way, the kernel can be significantly simplified, since the switch to long mode and the initial page table layout can already be done in the bootloader. Thus, we can avoid the initial assembly level blog posts in the second edition and directly start with high level Rust code.

The bootloader is still an early prototype, but it is already capable of switching to long mode and loading the kernel in form of an 64-bit ELF binary. It also performs the correct page table mapping (with the correct read/write/execute permissions) as it's specified in the ELF file and creates an initial physical memory map.

The plan for the future is to make the bootloader more stable, add documentation, and ultimately add a “Writing a Bootloader” series to the blog, which explains in detail how the bootloader works.

Linking with LLD

With our custom bootloader in place, the last remaining problem is platform independent linking. Fortunately there is LLD, the cross-platform linker from the LLVM project, which is already very stable for the x86 architecture. As a bonus, LLD is now shipped with Rust, which means that it can be used without any extra installation.

The new Posts

The second edition is already live at https://os.phil-opp.com/second-edition. Please tell us if you have any feedback on the new posts! We're planning to move over the content from the first edition iteratively, in a different order and with various other improvements.

Many thanks to everyone who helped to make Rust an even better language for OS development!


Comments