This blog series creates a small operating system in the Rust programming language. Each post is a small tutorial and includes all needed code, so you can follow along if you like. The source code is also available in the corresponding Github repository.
Latest post: Heap Allocation
CPU Exceptions
CPU exceptions occur in various erroneous situations, for example when accessing an invalid memory address or when dividing by zero. To react to them we have to set up an interrupt descriptor table that provides handler functions. At the end of this post, our kernel will be able to catch breakpoint exceptions and to resume normal execution afterwards.
read more…Double Faults
This post explores the double fault exception in detail, which occurs when the CPU fails to invoke an exception handler. By handling this exception we avoid fatal triple faults that cause a system reset. To prevent triple faults in all cases we also set up an Interrupt Stack Table to catch double faults on a separate kernel stack.
read more…Hardware Interrupts
In this post we set up the programmable interrupt controller to correctly forward hardware interrupts to the CPU. To handle these interrupts we add new entries to our interrupt descriptor table, just like we did for our exception handlers. We will learn how to get periodic timer interrupts and how to get input from the keyboard.
read more…Introduction to Paging
This post introduces paging, a very common memory management scheme that we will also use for our operating system. It explains why memory isolation is needed, how segmentation works, what virtual memory is, and how paging solves memory fragmentation issues. It also explores the layout of multilevel page tables on the x86_64 architecture.
read more…Paging Implementation
This post shows how to implement paging support in our kernel. It first explores different techniques to make the physical page table frames accessible to the kernel and discusses their respective advantages and drawbacks. It then implements an address translation function and a function to create a new mapping.
read more…Heap Allocation
This post adds support for heap allocation to our kernel. First, it gives an introduction to dynamic memory and shows how the borrow checker prevents common allocation errors. It then implements the basic allocation interface of Rust, creates a heap memory region, and sets up an allocator crate. At the end of this post all the allocation and collection types of the built-in alloc
crate will be available to our kernel.
Subscribe
Receive notifications about new posts and other major changes! You can either:
- Subscribe to our RSS/Atom Feed,
- Subscribe to this GitHub issue, or
- Subscribe to our email newsletter.
First Edition
You are viewing the second edition of “Writing an OS in Rust”, which is still in progress. The first edition has more content, but is no longer updated. We try our best to incorporate the missing content soon.Extra Content
Status Updates
These posts give a regular overview of the most important changes to the blog and the tools and libraries behind the scenes.
Support Me
While creating this blog and the libraries and tools behind the scenes takes a lot of time, I really enjoy it and I'm committed to keep working on it. By supporting me, you allow me to invest more time into new content, new features, and continuous maintainance.
The best way to support me is to sponsor me on GitHub. GitHub will even match sponsorships until October 2020! If you prefer other platforms, I also have Patreon and Donorbox accounts. The latter is the most flexible as it supports multiple currencies and one-time contributions.
Thank you!