Writing an OS in Rust

This blog series creates a small operating system in the Rust programming language. Each post is a small tutorial and includes all needed code.
https://os.phil-opp.com/ (RSS)
visit blog
Updates in March 2020
1 Apr 2020 | original ↗

This post gives an overview of the recent updates to the Writing an OS in Rust blog and the corresponding libraries and tools. I focused my time this month on finishing the long-planned post about Async/Await. In addition to that, there were a few updates to the crates behind the scenes, including some great contributions and a new vga crate. As...

Async/Await
27 Mar 2020 | original ↗

In this post, we explore cooperative multitasking and the async/await feature of Rust. We take a detailed look at how async/await works in Rust, including the design of the Future trait, the state machine transformation, and pinning. We then add basic support for async/await to our kernel by creating an asynchronous keyboard task and a basic...

Updates in February 2020
2 Mar 2020 | original ↗

This post gives an overview of the recent updates to the Writing an OS in Rust blog and the corresponding libraries and tools. blog_os The repository of the Writing an OS in Rust blog received the following updates: Mention potential bump allocator extensions Don’t panic on overflow in allocator; return null pointer instead Update Allocator...

Updates in January 2020
1 Feb 2020 | original ↗

This post gives an overview of the recent updates to the Writing an OS in Rust blog and the corresponding libraries and tools. blog_os The repository of the Writing an OS in Rust blog received the following updates: Move #[global_allocator] into allocator module Update many_boxes test to scale with heap size New post about allocator designs 🎉...

Allocator Designs
20 Jan 2020 | original ↗

This post explains how to implement heap allocators from scratch. It presents and discusses different allocator designs, including bump allocation, linked list allocation, and fixed-size block allocation. For each of the three designs, we will create a basic implementation that can be used for our kernel. This blog is openly developed on GitHub....

Updates in December 2019
7 Jan 2020 | original ↗

Happy New Year! This post gives an overview of the recent updates to the Writing an OS in Rust blog and the corresponding libraries and tools. blog_os The repository of the Writing an OS in Rust blog received the following updates: Update x86_64 dependency to version 0.8.1. This included the dependency update itself, an update of the frame...

Updates in October and November 2019
2 Dec 2019 | original ↗

This post gives an overview of the recent updates to the Writing an OS in Rust blog and the used libraries and tools. I moved to a new apartment mid-October and had lots of work to do there, so I didn’t have the time for creating the October status update post. Therefore, this post lists the changes from both October and November. I’m slowly...

Updates in September 2019
6 Oct 2019 | original ↗

This post gives an overview of the recent updates to the Writing an OS in Rust blog and the used libraries and tools. I finished my master thesis and got my degree this month, so I only had limited time for my open source work. I still managed to perform a few minor updates, including code simplications for the Paging Implementation post and the...

Updates in August 2019
9 Sept 2019 | original ↗

This post gives an overview of the recent updates to the Writing an OS in Rust blog and the used libraries and tools. I was very busy with finishing my master’s thesis, so I didn’t have any to implement any notable changes myself. Thanks to contributions by @vinaychandra and @64, we were still able to publish new versions of the x86_64, bootimage...

Updates in July 2019
2 Aug 2019 | original ↗

This post gives an overview of the recent updates to the Writing an OS in Rust blog and the used libraries and tools. Since I’m still very busy with my master thesis, I haven’t had the time to work on a new post. But there were quite a few maintenance updates this month and also a few new features such as the new OffsetPageTable type in the...

Updates in June 2019
6 Jul 2019 | original ↗

This post gives an overview of the recent updates to the Writing an OS in Rust blog and the used libraries and tools. My focus this month was to finish the Heap Allocation post, on which I had been working since March. I originally wanted to include a section about different allocator designs (bump, linked list, slab, …) and how to implement...

Heap Allocation
26 Jun 2019 | original ↗

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...

Updates in May 2019
3 Jun 2019 | original ↗

This post gives an overview of the recent updates to the Writing an OS in Rust blog and to the used tools. I was quite busy with my master thesis this month, so I didn’t have the time to create new content or major new features. However, there were quite a few minor updates. x86_64 Use cast crate instead of usize_conversions crate (released as...

Updates in April 2019
1 May 2019 | original ↗

Lot’s of things changed in the Writing an OS in Rust series in the past month, both on the blog itself and in the tools behind the scenes. This post gives an overview of the most important updates. This post is an experiment inspired by This Week in Rust and similar series. The goal is to provide a resource that allows following the project more...

Testing
27 Apr 2019 | original ↗

This post explores unit and integration testing in no_std executables. We will use Rust’s support for custom test frameworks to execute test functions inside our kernel. To report the results out of QEMU, we will use different features of QEMU and the bootimage tool. This blog is openly developed on GitHub. If you have any problems or questions,...

Paging Implementation
14 Mar 2019 | original ↗

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. This blog is openly developed on...

Advanced Paging
28 Jan 2019 | original ↗

This post explains techniques to make the physical page table frames accessible to our kernel. It then uses such a technique to implement a function that translates virtual to physical addresses. It also explains how to create new mappings in the page tables. This blog is openly developed on GitHub. If you have any problems or questions, please...

Introduction to Paging
14 Jan 2019 | original ↗

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. This...

Hardware Interrupts
22 Oct 2018 | original ↗

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. This blog is...

Double Faults
18 Jun 2018 | original ↗

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. This blog is...

CPU Exceptions
17 Jun 2018 | original ↗

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 resume normal execution...

Integration Tests
15 Jun 2018 | original ↗

To complete the testing picture we implement a basic integration test framework, which allows us to run tests on the target system. The idea is to run tests inside QEMU and report the results back to the host through the serial port. This blog is openly developed on GitHub. If you have any problems or questions, please open an issue there. You...

Unit Testing
29 Apr 2018 | original ↗

This post explores unit testing in no_std executables using Rust’s built-in test framework. We will adjust our code so that cargo test works and add some basic unit tests to our VGA buffer module. This blog is openly developed on GitHub. If you have any problems or questions, please open an issue there. You can also leave comments at the bottom....

Writing an OS in pure Rust
9 Mar 2018 | original ↗

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...

VGA Text Mode
26 Feb 2018 | original ↗

The VGA text mode is a simple way to print text to the screen. In this post, we create an interface that makes its usage safe and simple by encapsulating all unsafety in a separate module. We also implement support for Rust’s formatting macros. This blog is openly developed on GitHub. If you have any problems or questions, please open an issue...

A Minimal Rust Kernel
10 Feb 2018 | original ↗

In this post, we create a minimal 64-bit Rust kernel for the x86 architecture. We build upon the freestanding Rust binary from the previous post to create a bootable disk image that prints something to the screen. This blog is openly developed on GitHub. If you have any problems or questions, please open an issue there. You can also leave...

A Freestanding Rust Binary
10 Feb 2018 | original ↗

The first step in creating our own operating system kernel is to create a Rust executable that does not link the standard library. This makes it possible to run Rust code on the bare metal without an underlying operating system. This blog is openly developed on GitHub. If you have any problems or questions, please open an issue there. You can...

Handling Exceptions
26 Mar 2017 | original ↗

In this post, we start exploring CPU exceptions. Exceptions occur in various erroneous situations, for example when accessing an invalid memory address or when dividing by zero. To catch 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...

Double Faults
2 Jan 2017 | original ↗

In this post we explore double faults in detail. We also set up an Interrupt Stack Table to catch double faults on a separate kernel stack. This way, we can completely prevent triple faults, even on kernel stack overflow. As always, the complete source code is available on GitHub. Please file issues for any problems, questions, or improvement...

Returning from Exceptions
21 Sept 2016 | original ↗

In this post, we learn how to return from exceptions correctly. In the course of this, we will explore the iretq instruction, the C calling convention, multimedia registers, and the red zone. As always, the complete source code is on GitHub. Please file issues for any problems, questions, or improvement suggestions. There is also a gitter chat...

Better Exception Messages
3 Aug 2016 | original ↗

In this post, we explore exceptions in more detail. Our goal is to print additional information when an exception occurs, for example the values of the instruction and stack pointer. In the course of this, we will explore inline assembly and naked functions. We will also add a handler function for page faults and read the associated error code....

Catching Exceptions
28 May 2016 | original ↗

In this post, we start exploring exceptions. We set up an interrupt descriptor table and add handler functions. At the end of this post, our kernel will be able to catch divide-by-zero faults. As always, the complete source code is on GitHub. Please file issues for any problems, questions, or improvement suggestions. There is also a comment...

Kernel Heap
11 Apr 2016 | original ↗

In the previous posts we created a frame allocator and a page table module. Now we are ready to create a kernel heap and a memory allocator. Thus, we will unlock Box, Vec, BTreeMap, and the rest of the alloc crate. As always, you can find the complete source code on GitHub. Please file issues for any problems, questions, or improvement...

Remap the Kernel
1 Jan 2016 | original ↗

In this post we will create a new page table to map the kernel sections correctly. Therefore we will extend the paging module to support modifications of inactive page tables as well. Then we will switch to the new table and secure our kernel stack by creating a guard page. As always, you can find the source code on GitHub. Don’t hesitate to file...

Page Tables
9 Dec 2015 | original ↗

In this post we will create a paging module, which allows us to access and modify the 4-level page table. We will explore recursive page table mapping and use some Rust features to make it safe. Finally we will create functions to translate virtual addresses and to map and unmap pages. You can find the source code and this post itself on GitHub....

Allocating Frames
15 Nov 2015 | original ↗

In this post we create an allocator that provides free physical frames for a future paging module. To get the required information about available and used memory we use the Multiboot information structure. Additionally, we improve the panic handler to print the corresponding message and source line. The full source code is available on GitHub....

Printing to Screen
23 Oct 2015 | original ↗

In the previous post we switched from assembly to Rust, a systems programming language that provides great safety. But so far we are using unsafe features like raw pointers whenever we want to print to screen. In this post we will create a Rust module that provides a safe and easy-to-use interface for the VGA text buffer. It will support Rust’s...

Set Up Rust
2 Sept 2015 | original ↗

In the previous posts we created a minimal Multiboot kernel and switched to Long Mode. Now we can finally switch to Rust code. Rust is a high-level language without runtime. It allows us to not link the standard library and write bare metal code. Unfortunately the setup is not quite hassle-free yet. This blog post tries to set up Rust...

Entering Long Mode
25 Aug 2015 | original ↗

In the previous post we created a minimal multiboot kernel. It just prints OK and hangs. The goal is to extend it and call 64-bit Rust code. But the CPU is currently in protected mode and allows only 32-bit instructions and up to 4GiB memory. So we need to set up Paging and switch to the 64-bit long mode first. I tried to explain everything in...

A minimal Multiboot Kernel
18 Aug 2015 | original ↗

This post explains how to create a minimal x86 operating system kernel using the Multiboot standard. In fact, it will just boot and print OK to the screen. In subsequent blog posts we will extend it using the Rust programming language. I tried to explain everything in detail and to keep the code as simple as possible. If you have any questions,...

↑ these items are from RSS. Visit the blog itself at https://os.phil-opp.com/ to find other articles and to appreciate the author's digital home.