This Month in Rust OSDev (July 2020)
Welcome to a new issue of "This Month in Rust OSDev". In these posts, we give a regular overview of notable changes in the Rust operating system development ecosystem.
This series is openly developed on GitHub. Feel free to open pull requests there with content you would like to see in the next issue. If you find some issues on this page, please report them by creating an issue.
In this section, we give an overview of notable changes to the projects hosted under the
bootimage tool allows the creation of bootable disk images for
bootloader-based kernels. It also provides a runner executable for
cargo to make
cargo run and
cargo test work using QEMU. In July, the crate was updated to work with cargo's own
build-std feature instead of relying on the
- Add support for building bootloaders using
cargo buildinstead of
cargo xbuild(published as
bootloader crate implements a custom Rust-based bootloader for easy loading of 64-bit ELF executables. In July, we switched the crate from
cargo-xbuild to the
build-std feature of cargo and fixed a bug that prevented booting in VirtualBox:
- Change 1st stage int 13h addressing (published as
- Make bootloader buildable with
- Enable rlibc dependency only with
binaryfeature (published as
Thanks to @rsribeiro for their contribution!
We also made some progress on adding UEFI support to the bootloader. Our prototype is now able to set up a pixel-based framebuffer, map a given kernel ELF file into virtual memory, and then pass control to its entry point. The next steps are the construction of the boot information structure, including a memory map. You can find a link to the code and the build instructions in this comment.
acpi repository contains crates for parsing the ACPI tables – data structures that the firmware of modern computers use to relay information about the hardware to the OS. This month saw some substantial improvements to our AML handling:
- Objects defined by AML tables exist within a namespace, with objects referred to by paths such as
\_SB.PCI0.ISA.COM1. Until now, we represented this namespace using a
BTreeMapbetween the path (allocated on the heap) and a handle to the object, meaning that there was both a heap-allocated container, and a heap allocation for every single path within the namespace. In this PR, we moved the library to use a new representation that has a
BTreeMapfor each level of the namespace. Because each level of the path can only be 4 characters long (
COM1are the name segments in the example above), storing the path of each level no longer requires a heap allocation per object, which reduces the heap-burden of the library significantly.
- Some more opcodes were implemented:
DefAnd. These all appear in QEMU's tables.
- A fairly large PR was merged that provides the ability to traverse the namespace and initialize devices - this is a mechanism that ACPI provides that allows an OS to initialize hardware that it does not have drivers for, and is a compulsory step in getting modern chipsets to function properly. This required us to build up a lot of functionality, including namespace traversal, reading and writing from operation regions, recursively invoking control methods, and asking the OS to perform hardware configuration for us (such as reading and writing to IO ports and PCI configuration space). There is still a lot of work in getting all of this working robustly, but this is a great start.
uefi-rs crate provides safe and performant wrappers for UEFI, the successor to the BIOS.
The major changes which happened in this month are:
- We've tested out support for AArch64. No updates to the code are needed, just add a custom target file for 64-bit ARM UEFI and then compile your project with it.
LoadedImageprotocol now exposes the handle for the device where the binary is stored.
- Our CI is now green again! There is only one test which breaks QEMU, and it's going to stay disabled until it gets fixed.
- Building the repository no longer requires cargo-xbuild, we've switched to nightly Cargo's build-std feature.
- Updated documentation in various places.
spinning_top crate provides a simple spinlock implementation based on the abstractions of the
lock_api crate. We created the crate to provide an alternative to the no-longer maintained
spin crate. In July, the crate received the following updates:
try_lock_weakfor use in
lockloop (published as
lock_apito 0.4.0 (published as
const_spinlockconvenience function (published as
Thanks to @akiekintveld for their contributions!
volatile crate provides safe wrapper types for implementing volatile read and write operations. The crate received the following changes this month:
- Derive Default for Volatile, WriteOnly and ReadOnly (published as
Thanks to @Freax13 for their contributions!
We are also considering a complete rewrite of the crate to wrap references instead of values directly. The main advantage of this is that it makes working with slices possible. See the pull request for details.
multiboot2 crate provides abstraction types for the boot information of multiboot2 bootloaders. In July, we merged a change that makes the checksum field of the RSDP tag more useful:
- Add a
validate_checksummethod to rsdp (published as
Thanks to @dlrobertson for this contribution!
cargo-xbuild project provides
cargo command wrappers to cross-compile the sysroot crates
alloc. While there were no updates to the crate itself in July, we added a guide on how to switch from
cargo-xbuild to cargo's own
build-std feature to the Readme. You can read it here.
In this section, we describe updates to personal projects that are not directly related to the
rust-osdev organization. Feel free to create a pull request with the updates of your OS project for the next post.
(Section written by @IsaacWoods)
Between my work on
acpi and university commitments, I have not had much time to work on Pebble this month, but
some small clean-ups were made:
- The migration from Travis CI to Github Actions was completed, allowing Pebble to be emulated on CI.
- Pebble uses a HAL (hardware abstraction layer) to separate hardware access from kernel logic. Various parts of the
x86_64implementation of the HAL were made common to support code-reuse across architectures.
- Some tests were added to the buddy allocator (Pebble's physical memory manager). This was to rule out physical memory allocation as the cause of a bug where user stacks are occasionally corrupted at the userspace-kernel boundary, which unfortunately has still not been fixed.
- Our algorithm for efficiently mapping arbitrary areas was rewritten and extended to support 1GiB pages.
- Work has started on a topology layer - data structures that represent features of the platform such as processors, caches, NUMA nodes, and microarchitectural information. This will help in allowing Pebble to make more intelligent decisions about scheduling and resource usage in the future.
(Section written by @phil-opp)
The main change this month was the migration from
cargo-xbuild to the
build-std feature of cargo. This means that we can now use the normal
cargo test commands for our kernel 🎉.
The full list of notable changes is:
- Migrate code from cargo-xbuild to
- Link 'This Month in Rust OSDev' posts in status updates section
There were also some contributions this month that fixed typos and updated links. Thanks a lot to all contributors!
For the next weeks/months, my plan is to finish the UEFI bootloader implementation and then adjust the blog to work with both the BIOS and UEFI bootloaders. Among other things, this will require that we switch from the VGA text buffer to a pixel-based framebuffer because the VGA text mode is not available with UEFI. While this makes things more complicated (we need to do some simple font rendering and add slice support to
volatile crate), it will allow us to create our own graphical user interface, render a mouse pointer, or display images.
Are you interested in Rust-based operating system development? Our
rust-osdev organization is always open to new members and new projects. Just let us know if you want to join! A good way for getting in touch is our gitter channel.