Rust OSDev Operating System Development in Rust

This Month in Rust OSDev: August 2022

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 or using our comment form at the bottom of this page.

rust-osdev Projects

In this section, we give an overview of notable changes to the projects hosted under the rust-osdev organization.

uefi-rs

Maintained by @GabrielMajeri, @nicholasbishop, and @phip1611

The uefi crate provides safe and performant wrappers for UEFI, the successor to the BIOS.

We merged the following changes in August:

We also published a subset of the above changes as a new v0.16.1 release:

Thanks to @kendase3, @JonahPlusPlus, and @e820 for their contributions!

bootloader

Maintained by @phil-opp, @rybot666, and @64

The bootloader crate implements a custom Rust-based bootloader for easy loading of 64-bit ELF executables.

This month, we finally finished the new BIOS boot implementation for the upcoming v0.11 release. It's now almost completely written in Rust (instead of assembly), which should make further improvements much easier.

Some selected commits that might be interesting:

All the tests are passing now, so we only need to do some cleanup and write proper documentation, then we should be ready to publish an alpha release for testing.

linked-list-allocator

Maintained by @phil-opp and @jamesmunns

The linked-list-allocator crate provides a basic no_std allocator that builds a linked list from freed memory blocks and thus needs no additional data structures.

In August, Evan Richter discovered a vulnerability in Heap::extend that could lead to out-of-bound writes. The issue occurred when extend was called with a size smaller than size_of::<usize> * 2, i.e., a size too small to store the metadata for the new memory region.

Upon investigating this issue, we found several similar issues:

  • Initializing a heap with a size smaller than size_of::<usize> * 3 could result in an out-of-bounds write too.
  • Calling extend on an uninitialized heap could also result in an out-of-bounds write.
  • Calling extend on a heap whose size is not a multiple of the size of two usizes resulted in unaligned writes.

We created a security advisory with more details and released a fix in v0.10.2, with the following changes:

  • The initialization functions now panic if the given size is not large enough to store the necessary metadata. Depending on the alignment of the heap bottom pointer, the minimum size is between 2 * size_of::<usize> and 3 * size_of::<usize>.
  • The extend method now panics when trying to extend an uninitialized heap.
  • Extend calls with a size smaller than size_of::<usize>() * 2 are now buffered internally and not added to the list directly. The buffered region will be merged with future extend calls.
  • The size() method now returns the usable size of the heap, which might be slightly smaller than the top() - bottom() difference because of alignment constraints.

Thanks to @evanrichter for reporting this vulnerability and working with us on a fix.

xhci

Maintained by @toku-sa-n

The xhci crate provides types of xHCI structures, such as Registers and TRBs.

We merged the following changes this month:

Thanks to @Demindiro for their contribution!

pci_types

Maintained by @IsaacWoods

The pci_types library provides types for accessing and configuring PCI devices from Rust operating systems.

We merged the following change in August:

Thanks to @0Killian for this contribution!

acpi

Maintained by @IsaacWoods, @Restioson, and @Gegy

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.

We merged the following changes this month:

Thanks to @semiviral, and @Freax13 for their contributions!

Call for Participation

Want to contribute to a Rust OSDev project, but don't know where to start? Help with one of these outstanding issues!

If you maintain a Rust project related to operating system development and are looking for contributors, especially for tasks suited to people getting started in this space, please create a PR against the next branch with the tasks you want to include in the next issue.

Other Projects

In this section, we describe updates to Rust OS 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.

cdrzewiecki/celos

(Section written by @drzewiec)

It's been a while since my last project update! That's partly because life has been busy, but also because this update concerns a huge feature. I'm very pleased to report that I have been able to add preemptive multitasking to CelOS.

This was feature that took a good bit of foundation to be able to implement (hence why it took me so long). I had to spend a good bit of time getting memory allocation (both physical and virtual) into a happier place, as well as add support for ACPI and the APIC. And, of course, there were many snags along the way as I learned (at least some of) the traps that are easy to step into when doing something as delicate as context switching.

Now that I have finished this key feature, I plan to work on setting up the other infrastructure needed to begin writing services in userspace (such as message passing and synchronization primitives). And, hopefully soon, finally make the jump into ring 3!

As always, many thanks to @phil-opp for his hard work on supporting the Rust osdev community, and for writing the apic crate which helped serve as a sanity check while I wrote my own driver for the IOAPIC and LAPIC. Thanks as well to the maintainers of the excellent acpi crate, you guys are doing incredible work out there!

Blog Post: GNU ld Discards Section Containing Code – Section Flags in Assembly are Important

(Section written by @phip1611)

In late August/early September, I encountered problems when building my Rust kernel. I faced unintuitive interaction between my global assembly code and the linker. I specified a custom section in assembly with executable code with .section .bootcode. The linker never linked the code where I specified it in my linker script. It's address was not what it is supposed to be. readelf didn't show the section inside the binary either. The section was discarded no matter how hard I tried to modify the linker, thus, KEEP((.bootcode)); also didn't work. An experienced colleague ensured me that my linker script is correct.

Section names such as .init or .text.bootcode worked by the way. Only my custom name was rejected somehow. In the end, I figured out writing .section .bootcode, "ax" does the trick. The difference is small, but the impact to the object file and final executable of those section flags is big. I could find the answer in the ELF specification. A section needs to be allocatable (a-flag) so that it can be properly placed in a LOAD segment/program header. The section names .init and .text.* have this pre-configured but my custom section name .bootcode has not.

I traced it down to a minimal reproducible example that can be found on GitHub. A comprehensive write-up can be found on my website Phip's Blog.

phil-opp/blog_os

(Section written by @phil-opp)

This month, we merged a pull request that fixes numerous grammar and punctuation errors across all posts of the "Writing an OS in Rust" series. Thanks to @hecatia-elegua for this contribution!

We also received multiple pull requests to add and update translations:

We are still looking for reviewers for the last two PRs. If you speak Chinese or Korean, it would be great if you could take a look!

Thanks to @ykomatsu, @liuyuran, and @JOE1994 for contributing these translations!

Join Us?

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

Comments