This blog series creates a small operating system in the Rust programming language. Each post is a small tutorial and includes all needed code.| os.phil-opp.com
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 mentioned in the Async/Await post, I’m currently looking for job in Karlsruhe (Germany) or remote, so please let me know if you’re interested. bl...| Writing an OS in Rust
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 insteadUpdate Allocator Designs post to signal OOM instead of panicking on overflow Update to Zola 0.10 Experimental Support for Community TranslationsAdd translations from rust...| Writing an OS in Rust
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 🎉 Provide multiple implementations of align_up and mention performance Refactor Simplified Chinese translation of post 3 by @Rustin-Liu Use checked add...| Writing an OS in Rust
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 allocation code, and an update of the blog. License the blog/content folder under CC BY-NC Reword sentence in first post by @pamolloy Further, we’re stil...| Writing an OS in Rust
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 picking up speed again, but I still have a lot of mails in my backlog. Sorry if you haven’t received an answer yet! blog_os The blog itself receive...| Writing an OS in Rust
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 evaluation of GitHub Actions as a CI service. blog_os Improve Paging Implementation Post: Improves and simplifies the code in multiple places Use Git...| Writing an OS in Rust
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 and bootloader crates. blog_os Apart from rewriting the section about no-harness tests of the Testing post, there were no notable changes to the...| Writing an OS in Rust
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 x86_64 crate. We also had some great contributions this month. Thanks to the efforts of @64, we were able to considerably lower the compile times of t...| Writing an OS in Rust
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 them, but I decided to split it out into a separate post because it became much too long. I try to release this half-done post soon. Apart from the new...| Writing an OS in Rust
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. This blog is openly developed on GitHub. If you have any problems or quest...| Writing an OS in Rust
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 version 0.5.5). Make FrameAllocator an unsafe trait (released as version 0.6.0). Change Port::read and PortReadOnly::read to take &mut self (released...| Writing an OS in Rust
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 closely and staying up-to-date with the changes in the tools/libraries behind the scenes. If enough people find this useful, I will try to turn thi...| Writing an OS in Rust
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, please open an issue there. You can also leave comments at the bottom. The complete source code for this post can be found in the post-04 branch. ...| Writing an OS in Rust
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 GitHub. If you have any problems or questions, please open an issue there. You can also leave comments at the bottom. The complete source code for thi...| Writing an OS in Rust
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 open an issue there. You can also leave comments at the bottom. The complete source code for this post can be found here. 🔗Introduction In the prev...| Writing an OS in Rust
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 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. The c...| Writing an OS in Rust
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 openly developed on GitHub. If you have any problems or questions, please open an issue there. You can also leave comments at the bottom. The complete ...| Writing an OS in Rust
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 openly developed on GitHub. If you have any problems or questions, please open an issue there. You can also leave comments at the bottom. The complet...| Writing an OS in Rust
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 afterward. 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 bo...| Writing an OS in Rust
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 can also leave comments at the bottom. The complete source code for this post can be found in the post-05 branch. 🔗Requirements This post builds upo...| Writing an OS in Rust
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. The complete source code for this post can be found in the post-04 branch. 🔗Requirements In this post we explore how to execute cargo test on th...| Writing an OS in 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 used the GRUB bootloader for booting our kernel. To create a bootable disk/CD image we used the grub-mkrescue tool, which is very d...| Writing an OS in Rust
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 there. You can also leave comments at the bottom. The complete source code for this post can be found in the post-03 branch. 🔗The VGA Text Buffer ...| Writing an OS in Rust
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 comments at the bottom. The complete source code for this post can be found in the post-02 branch. 🔗The Boot Process When you turn on a computer, it begi...| Writing an OS in Rust
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 exceptions and to resume normal execution afterwards. As always, the complete source code is available on GitHub. Please file issues for any problems, que...| Writing an OS in Rust
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 suggestions. There is also a gitter chat and a comment section at the end of this page. 🔗What is a Double Fault? In simplified terms, a double fault ...| Writing an OS in Rust
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 and a comment section at the end of this page. Note: This post describes how to handle exceptions using naked functions (see “Handling Exceptions wit...| Writing an OS in Rust
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. As always, the complete source code is on GitHub. Please file issues for any problems, questions, or improvement suggestions. There is also a gitter c...| Writing an OS in Rust
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 section at the end of this page. Note: This post describes how to handle exceptions using naked functions (see “Handling Exceptions with Naked Functions...| Writing an OS in Rust
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 suggestions. There is also a comment section at the end of this page. 🔗Introduction The heap is the memory area for long-lived allocations. The programmer c...| Writing an OS in Rust
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 issues there if you have any problems or improvement suggestions. There is also a comment section at the end of this page. Note that this post req...| Writing an OS in Rust
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. Please file an issue there if you have any problems or improvement suggestions. There is also a comment section at the end of this page. Note that th...| Writing an OS in Rust
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. Feel free to open issues there if you have any problems or improvements. You can also leave a comment at the bottom. 🔗Preparation We still have a r...| Writing an OS in Rust
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 formatting macros, too. This post uses recent unstable features, so you need an up-to-date nighly compiler. If you have any questions, problems, or ...| Writing an OS in Rust
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 step-by-step and point out the different problems. If you have any questions, problems, or suggestions please file an issue or create a comment at the bottom. T...| Writing an OS in Rust
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 detail and to keep the code as simple as possible. If you have any questions, suggestions, or issues, please leave a comment or create an issue on Gith...| 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.| os.phil-opp.com
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, inclu…| os.phil-opp.com
This post explains how to implement heap allocators from scratch. It presents and discusses different allocator designs, including bump allocation, li…| os.phil-opp.com
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 possi…| os.phil-opp.com