This Month in Rust OSDev (September 2020)
Welcome to a new issue of "This Month in Rust OSDev". In these posts, we will 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
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. Lots of work happened this month:
- Support for the
Word Address Space,
DWord Address Space,
QWord Address Space,
DMA Format, and
I/O Port Descriptorresource descriptors were added. These appear in
_CRSobjects - objects that describe the resources allocated to a particular hardware device. This should be enough support to parse the
_CRSobjects of all devices supported by QEMU. Thanks to
@michaelmelansonfor his contribution!
acpicrate was published, after consultation with contributors to the Redox project. This splits the library into two parts - discovering ACPI tables using various methods, and separately, parsing them to discover information about the system. This provides much more flexibility in how tables are parsed, allows support for OS-specific tables, and is important to the Redox project as it allows parsing of the ACPI tables in userspace. We also used this opportunity for breaking changes to clean up a few parts of the library, especially in making our method of mapping physical memory ranges safer.
- A new crate,
rsdp, was split out from
acpi. This new crate provides methods for searching for the first ACPI table (the Root System Description Pointer (RSDP)) on BIOS systems without
allocsupport. This makes it suitable for use from bootloaders and similar applications where heap allocation is not supported. All types are reexported by the
acpicrate, so users can access the same functionality from the main library.
x86_64 crate provides various abstractions for
x86_64 systems, including wrappers for CPU instructions, access to processor-specific registers, and abstraction types for architecture-specific structures such as page tables and descriptor tables.
The crate received the following updates in September:
- Add a function for the
nopinstruction (published as
- Don't rely on promotion of
const fn(published as
- Thanks a lot to @ecstatic-morse and the Rust compiler team for preventing an upcoming breakage in our crate!
- Decouple instructions into a separate feature flag (published as
- See the corresponding changelog entry for a summary of the breaking changes introduced by this pull request.
- Fix build error on latest nightly caused by new
const_mut_refsfeature gate (published as
- Add remaining GDT flags, which also makes our GDT descriptors compatible with the
- Fix another build error on latest nightly, this time caused by the new
const_fn_fn_ptr_basicsfeature gate (published together with #181 as
We would also like to welcome @josephlr to our
x86_64 review and maintenance team!
volatile crate provides safe wrapper types for implementing volatile read and write operations. This month, we published version
0.4.0, which completely rewrites the crate based on reference values. Instead of wrapping the target value directly as e.g.
Volatile<u32>, the new implementation works by wrapping reference types such as
Volatile<&mut u32>. See our completely revamped documentation for more details.
The main advantage of the new reference-based implementation is that it is now possible to work with volatile arrays and slices, at least on nightly Rust. Through the
index_mut methods it is possible to create sub-slices, which can then be read and written efficiently through the
copy_from_slice methods. All these operations perform volatile memory accesses, so that the compiler won't optimize them away.
pci_types is a new library in the Rust OSDev organisation that provides types for accessing and configuring PCI
devices from Rust operating systems. Lots of this code (e.g. identifying devices by class codes) can be shared
between projects, and would benefit from community contributions. This month, work started on some types for
representing PCIe addresses, the layout of the configuration space for endpoints, device types, and a trait that
allows the library to access the PCIe configuration space in whichever way the platform exposes it.
uefi-rs crate provides safe and performant wrappers for UEFI, the successor to the BIOS. In September, the crate was updated to Rust's new inline assembly implemenation. We also published version
0.6.0 of the crate, including all the improvements added in the past two months.
Thanks to @toku-sa-n for their contribution!
bootloader crate implements a custom Rust-based bootloader for easy loading of 64-bit ELF executables. This month, we published versions
0.9.11 to fix build errors on the latest nightlies, caused by the new feature gate names for some
const fn features.
We also made some more progress on the rewrite with UEFI support. It now passes additional framebuffer information and the address of the RSDP structure of ACPI in the boot info. (We later updated the RSDP code to use the new
rsdp crate). The bootloader also gained support for setting up a recursive page table mapping, which makes it almost feature-equivalent with the current implementation. There are still a few things missings, but it should be ready to be published soon.
cargo-xbuild project provides
cargo command wrappers to cross-compile the sysroot crates
alloc. This month, we merged some maintenance updates to increase platform compatibility:
- Remove fs2 dependency for broader platform support (published as
- Fix winapi issues from flock() rework (published as
Thanks to @pfmooney for these contributions!
Even though we still maintain the
cargo-xbuild crate, we recommend switching to cargo's own
build-std feature that is always up-to-date with the latest Rust/Cargo changes. We wrote a short guide on how to switch to it, which is available in our Readme.
uart_16550 crate provides basic support for serial port I/O for 16550-compatible UARTs. Like the
bootloader crates, this crate received some dependency updates this month to fix nightly breakage. In the process, we released versions
0.2.10. Since none of these versions are semver-breaking, a normal
cargo update should suffice to update to the latest version.
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)
A fairly large amount of progress has been made on Pebble over the last two months, and a prototype of Pebble's defining feature (easy message passing between tasks) is now working!
- The first, basic, version of Pebble's wire format, ptah has been completed. This first version is implemented as a Serde format, but libraries could be written for any language that can manipulate a byte stream.
- Two system calls,
get_message, were added that allows a message (a series of bytes, and optionally a number of handles (effectively, permission to access a certain kernel object)) to be sent down a channel, between two tasks.
- Infrastructure for another of Pebble's key features, services, was added. This allows userspace tasks to
advertise their ability to provide some kind of 'service' to other tasks. A task called
echowas built to test this - it provides a service that simply echos any messages sent down it back to the sending task.
- Work started on the Platform Bus, a concept inspired by another hobby OS managarm's
mbus. All hardware devices on the platform will be added to the Platform Bus by Bus Drivers, and described using properties (as an example, a PCI device will have properties such as
pci.class). Device drivers will be able to apply to manage devices by sending a Filter to the Platform Bus, which specifies which devices they are able to handle, based on a device's properties. In the future, Platform Bus will be responsible for handling all PCI, USB, and hardwired devices on all platforms.
- The first Bus Driver was added to manage PCI devices. It uses a new system call,
pci_get_info, to get the raw information about PCI from the kernel, and then creates a Platform Bus device for each function, with the correct properties. It uses the new
pci_typeslibrary in the Rust OSDev organisation to identify each device (in the future, this will be extended to know about specific vendor+device ID combinations, to identify specific devices such as a particular graphics card).
(Section written by @phil-opp)
This month, the "Writing an OS in Rust" blog received a few minor updates:
- Update Zola to 0.11.0
- Use new
- Update to zola v0.12.1
Apart from that, I did a lot of preparation for the upcoming switch to the UEFI bootloader. My prototype implementation of the
blog_os system on top of the new UEFI bootloader has now reached feature parity with the existing implementation:
The output looks different now because we are using a pixel based framebuffer instead of the VGA text mode. This is required because the VGA text mode is no longer supported with UEFI. For the framebuffer implementation I'm using the new version of the
volatile crate and the
font8x8 crate for font rendering.
You can also see some log output related to the APIC interrupt controller (not to be confused with the ACPI standard). I'm using the APIC instead of the legacy PIC because the latter is not supported anymore on most UEFI systems. For that, I started working on a new
apic crate, which will include abstractions for the registers of the local APIC and the IOAPIC.
For the coming month(s), I'm planning to revamp the "Writing an OS in Rust" blog based on this prototype implementation. This will require complete rewrites of the VGA Text Mode and Hardware Interrupts posts, an update of the bootloader build process in A Minimal Rust Kernel, and replacing the QEMU screenshots across all posts. So I expect that it will take some time until the new version is ready.
(Section written by @andre-richter)
1.0.x of the crate has been released!
qemu-exit is a crate that allows you quit a running QEMU session with a user-defined exit code. This is useful for
integration tests of bare-metal software (e.g. OS kernels) that are tested in QEMU.
The crate supports the following architectures:
If you want to see the crate in action, you can have a look at how it is used in the rust-raspberrypi-OS-tutorials project.
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.