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
- Linux 6.1 Released With MGLRU, Initial Rust Code
- Kernel/Boot: Cope with a Relocation by a Bootloader in 32-bit x86 Assembly Code
In this blogpost, @phip1611 shows you how you can cope with a relocation by a bootloader in x86 32-bit assembly code. - How Does the “File Size is Smaller Than Mem Size” Optimization Work in GNU ld for the .bss Section?
In this blogpost, @phip1611 explains what properties bring the GNU linker ld to save disk space, as symbols in the.bss
section do not need to be statically allocated inside the ELF. Symbols in the.bss
segment are expected to be initialized to all zeroes. - GNU ld: Linking .bss into .data to Ensure that Mem Size Equals File Size For Each LOAD Segment (.bss in a PROGBITS Section)
In this blogpost, @phip1611 explains what steps you have to do that the GNU linker put's all symbols of the.bss
section "as they are" into the binary so that they occupy zeroed memory in the ELF. This is relevant for some very rudimentary ELF loaders that are found in some microkernels to bootstrap their initial process. - The Probably Simplest x86 Driver Written in Assembly – Printing to QEMU’s debugcon-Device)
In this blogpost, @phip1611 codes with you probably the simplest driver that one can write in assembly. This blogpost is from September but wasn't mentioned here earlier.
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
- Implement
SIMPLE_NETWORK_PROTOCOL
- Initial support for TCG TPM protocols
- Add
unsafe_protocol
macro and drop use of the unstablenegative_impls
feature UnalignedSlice
: implClone
and improveDebug
- Implement
Error
andDisplay
traits forFromStrError
- Simplification: No longer return "impl Iterator"
- uefi: Add
ptr_meta
dependency - Drop unstable
maybe_uninit_slice
andvec_into_raw_parts
features
Fixes
Docs
- Add list of possible errors to
BootServices::open_protocol
docs - Add list of possible errors to some
BootServices
function docs - Add docs to
BootServices
functions describing error cases - Shortened error documentation for all methods in
BootServices
- Replaced UEFI chapter numbers with function identifiers in the docs
- Add some documentation for media protocols
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:
- Adding
next_higher_level
toPageLevelIndex
- Adding
is_empty
toPageTable
- fix
Page::from_page_table_indices
(for upcomingv0.15
release)
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'sasync
/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
- It now supports the latest
- 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'sbootloader
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
andExitableTaskRef
JoinableTaskRef
is similar tostd::task::JoinHandle
, but is fully safe- Ensures that a task can only be
join
ed by the "parent" task that spawned it - Remove distinction between
join
ing a task and obtaining itsExitValue
- Automatically reaps "orphan" tasks that are no longer joinable
- Ensures that a task can only be
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
TaskRef
s 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
- Two new types:
- 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 aMappedPages
memory region as a specific typeT
- 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
becauseMappedPages
is always pinned in memory, avoiding the need forBox
allocation
- Accepts a
dereffer
: a new library crate that providesDerefsTo<T>
, a generic wrapper type that allows the enclosed objectT
to be arbitrarily dereferenced to any inner type reachable from that objectT
- Supports much more arbitrary and complex deref functions than
std::ops::Deref
- Supports much more arbitrary and complex deref functions than
- 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 typeT
- Allows you to use generics and associated
const
s 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
- Uses traits and marker types instead of the existing enum-based designs (like
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.
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:
- [Chinese] Translate posts 5-8 and improve translation of posts 1-4
- Thanks to @liuyuran for creating this translation.
- Thanks to @JiangengDong and @Byacrya for reviewing.
- [Translation][Korean] post-06 and [Translation][Korean] post-07
- French translation's links fixes (thanks to @alaincao)
- Specify latest 0.9 patch version of
bootloader
(thanks to @seewishnew)
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.