This Month in Rust OSDev: January 2023
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.
- Stabilize
abi_efiapi
feature - Add checks for the signature of the
start
lang item - default OOM handler: use non-unwinding panic, to match std handler
Announcements, News, and Blog Posts
- A GUI installer for redox is coming soon, written in iced!
- cargo-show-asm 0.2.10
- RustyHermit @ FOSDEM 2023: A Rust-Based, modular Unikernel for MicroVMs
rust-osdev
Projects
In this section, we give an overview of notable changes to the projects hosted under the rust-osdev
organization.
bootloader
Maintained by @phil-opp and @rybot666
The bootloader
crate implements a custom Rust-based bootloader for easy loading of 64-bit ELF executables.
We merged lots of improvements this month:
Features
- Load ramdisk feature
- Add support for a boot configuration file
- Make log level configurable
- Add support for logging to serial port (configurable)
- Add
bios
anduefi
cargo features - Add a
FrameBuffer::into_buffer
method for taking ownership - Implement faster bios builds
- Support higher half position independent kernels
Fixes
- Correctly allocate last frame in memory descriptor
- Fix: treat
kernel_slice_end
as an exclusive bound when checking for overlaps - Map BIOS stage-4 at lower address to avoid conflicts with the kernel
- Correctness fixes for stage2
- Fix loading of boot configuration
Docs
Other
- Fix spelling and add a check
- Check for breaking changes on CI
- Cancel in progress PR builds when a new commit is pushed for that PR
- Remove dependency on
time
crate - [test runner] Print QEMU output directly instead of waiting until it finishes
- Fix warnings from Clippy
- Test framework: Don't inherit
stdin
when spawning QEMU
Thanks to @jasoncouture, @Stary2001, @AlexJMohr, @Freax13, @tsoutsman, and @asensio-project for their contributions!
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 the rest of the TPM v1 interface
- Implement the rest of the TPM v2 interface
- Release uefi-macros-0.10.0, uefi-0.19.0, and uefi-services-0.16.0
- Add PAGE_SIZE constant and update MemoryProtection protocol docs
Fixes
- PXE: Fix BaseCode::discover optional argument
- Fix warnings from
abi_efiapi
stabilization - uefi: Fix protocol functions to work with unsized protocols
- Fix new lints related to derives on a packed struct
Docs
- uefi: Update MSRV in the readme
- book: Fix link to handles page
- changelog: Move some macro-related changes to correct section
Other
- Minor alloc-related cleanups
- uefi: Remove useless padding field
- Move some util code from TCG to a new top-level module
- media/test: add integration test for creating a directory
- ci: Update checkout action to latest version
- test-runner: Simplify and slightly refactor the disk test
- ci: fix book/deploy in forks
Thanks to @nsemmel and @liferooter for their contributions!
volatile
Maintained by @phil-opp
The volatile
crate provides a safe wrapper type for implementing volatile read and write operations. This is useful for accessing memory regions that have side-effects, such as memory-mapped hardware registers or framebuffers.
We merged the following PRs this month:
- Fix UB in slice methods when
Deref
returns different references (published asv0.4.6
) - various improvements for the new design
Thanks to @Freax13 for their contributions!
We are still working on a new, safer design. This month, we opened PR #29 to compare and discuss two alternative designs. The main question is whether the provided VolatilePtr
type should implement Copy
or Send
. Only one of these trait implementations is possible, otherwise there could be data races that lead to undefined behavior. Since both variants have valid use cases, the latest proposal is to implement two different types with conversion methods between them. We haven't reached a decision yet, so if anyone has more input on this, please join the discussion.
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 January:
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.
metta-systems/vesper
(Section written by @berkus)
Vesper is a capability-based single-address-space nanokernel. This means it is aiming to be small, to provide only isolation primitives; at the same time SAS makes it a lot easier to perform cross-process operations (because all addresses are the same across all processes). It uses capabilities to provide security for such operations, so that unauthorized processes will not be able to intervene in legitimate traffic.
The kernel is in very early stages of development...
And for the past few months I've been on and off involved in deciphering a mystical miscompilation problem. I've managed to summarize it in a ticket to rustc.
The most minimal reproduction scenario triggers when I use a format_args!() macro in my code and a nightly version later than 2022-08-12.
Here's a key snippet:
// if you keep this line, it works when compiled
// via rustc 2022-08-12 and breaks on 2022-08-13 and all the versions past that.
// if you comment this line out, on 2022-08-13 everything else starts to work.
uart.write_fmt(format_args_nl!("Lets {}!", "go")).ok();
There's also a QEMU-only reproduction code, which is much smaller, as it reuses armv8a_semihosting
and armv8a_panic_semihosting
crates for pretty much everything.
The behavior is the same though:
// if you don't comment it out, it works on 08-12 and breaks on 08-13.
// if you comment this line out on 08-13 everything else starts to work.
armv8a_semihosting::hprintln!("Lets {}!", "go").ok();
"Working" here means the kernel boots and runs through to the last panic line:
[cargo-make] INFO - Running Task: qemu
🚜 Run QEMU -M raspi3b -semihosting with vesper/target/nucleus.bin
Letsgo!
Lets go!
Lets go 2!
panicked at 'Off you go!', src/main.rs:34:5
And "not working" is the kernel either panicking on boot in arch64, for which I've extracted panic message but I have low confidence this is what actually happens - panic was in once_cell detecting it is initializing a second time, which I discounted as potentially just a bug in linker script layout and not an actual code generation bug. This code is even completely removed in the latest reproduction (no once_cells) but the kernel still crashes before it even can write anything to serial.
In the qemu repro it's even weirder:
🚜 Run QEMU -M raspi3b -semihosting with vesper/target/nucleus.bin
No output - because hstdout_str() function from armv8a_semihosting crate fails to open semihosting stdout handle - syscall returns -1. Why would that happen simply by a compiler version change - is the biggest question.
I'm yet to find what am I missing here - assuming this is my own mistake and not a compiler fault, because it would've been noticed by everybody else then? But who knows, maybe you can spot something - drop me a line if you see anything suspicious, I'm pretty much out of ideas here.
phil-opp/blog_os
(Section written by @phil-opp)
We merged the following changes to the Writing an OS in Rust blog this month:
Thanks a lot to @kennystrawnmusic for this contribution!
We also have an open pull request for a Chinese translation of the Paging Implementation post. We're still looking for a reviewer, so if you're speaking Chinese we would appreciate if you could take a look. Thanks!
Since I mostly worked on the bootloader
crate this month, I haven't made much process on the upcoming third edition of the blog yet.
I'll do my best to have something ready soon!
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.