Rust OSDev Operating System Development in Rust

This Month in Rust OSDev: December 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.

Infrastructure and Tooling

In this section, we collect recent updates to rustc, cargo, and other tooling that are relevant to Rust OS development.

Experimental feature gate proposal interoperable_abi

This Rust language proposal suggests to create a new extern "interop" ABI as a strict superset of the C ABI. The goal of this new ABI is to "define a standard way to make calls across high-level languages, passing high-level data types, without dropping to the lowest common denominator of C". For example, it will define a specific memory representation for strings, tuples, and common standard library types such as Option and Result.

This new ABI would be very useful for operating system development because there are often multiple executables that need to communicate with each other using a stable ABI. For example, user-space programs communicate with the kernel using system calls, and with other programs using different forms of inter-process communication. With new extern "interop" ABI, these communication boundaries could use safe, higher-level types when both sides are written in Rust.

default_alloc_error_handler has been stabilized

On no_std targets, enabling alloc requires providing an OOM (out-of-memory) handler. The usual implementation of this handler just panics, but implementing the handler requires an unstable feature: alloc_error_handler. The newly-stabilized default_alloc_error_handler automatically provides an OOM handler that panics if no custom handler is implemented. This is an important step towards using some targets on the stable channel.

Announcements, News, and Blog Posts

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 last month:

Features

Fixes

Docs

Tooling

Thanks to @veluca93, @phip1611, and @raccog for their contributions!

x86_64

Maintained by @phil-opp, @josephlr, @Freax13, and @rybot666

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

We merged the following changes in December:

Thanks to @TornaxO7 for their contribution!

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!

No tasks were proposed for this section this month.

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.

Theseus OS

(Section written by Kevin Boos (@kevinaboos))

Theseus is a safe-language OS written from scratch in Rust that is in the midst of a shift from academic research to usability and legacy compatibility. Theseus loads and links all components at runtime, and executes everything at a single privilege level in a single address space, relying on Rust safety for isolation and correctness.

As a fully open-source project, we welcome and encourage contributions from everyone!

Since our last update here a few months ago, we have worked on the following things:

  • Introduced dreadnought, a basic async executor that brings Rust's async/await syntax to Theseus
    • Usable by both applications and low-level kernel components
    • Integrated the concept of wakers with Theseus's native task subsystem
    • Currently, there is a 1-to-1 relationship between async dreadnought tasks and native Theseus tasks
  • Rewrote our networking interface to offer better, simpler, and cleaner abstractions
    • It now supports the latest smoltcp version, 0.8
  • Added support for booting Theseus on UEFI
    • Previously, Theseus could boot from only multiboot2-compliant bootloaders using legacy BIOS
    • UEFI on x86_64 now successfully boots after significant redesign of early bootstrap routines
    • New custom uefi_loader tool, loosely based on the rust-osdev org's bootloader project
    • Early graphical display for basic text printing is a work-in-progress
    • UEFI is required to boot Theseus on aarch64; this is also a work-in-progress
  • Almost completed porting core subsystems to aarch64
    • Bootstrap and logging over UART
    • Memory management: page table modification, arch-agnostic PTE flags and basic memory types, etc
    • Basic context switching and task bootstrap
    • SMP multicore, plus identification of CPU cores
    • Interrupt handling via GIC
  • Redesigned the drivers for PS/2 controller, keyboard, and mouse in an intralingual manner that fully leverages Rust's strong type system.
  • Started implementing a brand new graphics stack and window manager, Porthole, from scratch
    • Added support for x86's Page Attribute Table, which allows Theseus to control the caching properties of individual memory pages
    • We now map graphics video memory as write-combining instead of cache-disabled, which significantly improves performance
  • Redesigned task management to give arbitrary tasks fewer privileges
    • Two new types: JoinableTaskRef and ExitableTaskRef
      • JoinableTaskRef is similar to std::task::JoinHandle, but is fully safe
        • Ensures that a task can only be joined by the "parent" task that spawned it
        • Remove distinction between joining a task and obtaining its ExitValue
        • Automatically reaps "orphan" tasks that are no longer joinable
      • ExitableTaskRef statically ensures that only a task itself can mark itself as exited
        • Now, a given task can no longer invalidly mark another arbitrary task as exited
    • Refactored scheduler and task switching to not hold any TaskRefs during a context switch
      • Ensures that exited tasks are dropped and cleaned up expediently
    • Native ELF Thread-Local Storage (TLS) variables are used to store the current task
      • Accessing the current task is much faster, albeit slightly more complicated to initialize
  • Implemented a new shell called hull, plus new terminal, console, and TTY components
    • Theseus can now run headlessly, e.g., interactively over a serial port instead of via a graphical display.
  • Removed usage of owning_ref, a crate with unsoundness, in favor of our own types:
    • BorrowedMappedPages<T>: a pseudo-self-referential type that allows persistent, efficient borrowing of a MappedPages memory region as a specific type T
      • Accepts a Mutability type parameter for either immutable (&T) or mutable (&mut T) borrowing
      • Sister type BorrowedSliceMappedPages also supports dynamically-sized slices, i.e., &[T] and &mut [T]
      • Much more efficient than owning_ref because MappedPages is always pinned in memory, avoiding the need for Box allocation
    • dereffer: a new library crate that provides DerefsTo<T>, a generic wrapper type that allows the enclosed object T to be arbitrarily dereferenced to any inner type reachable from that object T
      • Supports much more arbitrary and complex deref functions than std::ops::Deref
  • Canonicalized the content of Theseus's x86_64-unknown-theseus target spec
    • Codegen flags are now moved into the target spec, making out-of-tree builds easier and more repeatable
    • Target specs are now ready to be upstreamed into rustc as built-in targets
  • owned_borrowed_trait: a new library crate that abstracts over Owned values vs. Borrowed refs
    • Uses traits and marker types instead of the existing enum-based designs (like Cow)
    • Doesn't require Clone or care about any characteristics of the inner type T
    • Allows you to use generics and associated consts to conditionally branch based on whether an owned value or borrowed reference was passed into a function
    • Allows you to return a different (generic) type from a function based on whether an owned value or borrowed reference was passed in

Check out the Theseus OS blog for more.

Andy-Python-Programmer/Aero

(Section written by @Andy-Python-Programmer)

Aero is a new modern, experimental, unix-like operating system following the monolithic kernel design. Supporting modern PC features such as long mode, 5-level paging, and SMP (multicore), to name a few.

This month, Aero successfully managed to get mesa-demos and alacritty running.

Aero

In addition, deps.sh script was added to automate the process of installing the required dependencies on the host to build the sysroot.

phil-opp/blog_os

(Section written by @phil-opp)

We merged the following changes to the Writing an OS in Rust blog in the past two months:

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