This Month in Rust OSDev: March 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.
Announcements, News, and Blog Posts
Here we collect news, blog posts, etc. related to OS development in Rust.
- Klint: Compile-time Detection of Atomic Context Violations for Kernel Rust Code
- Writing a Linux Driver for QEMU’s Debugcon Device
In this blogpost, @phip1611 shows you can write a Linux driver for the QEMU debugcon device. Although, the driver still uses C, it is a wonderful example to demonstrate a minimal yet useful driver. Additionally, it is a good starting point for a rewrite in Rust, once the Rust tooling and API bindings in the kernel are more mature. Perhaps, the rewrite in Rust is your next learning project?
rust-osdev
Projects
In this section, we give an overview of notable changes to the projects hosted under the rust-osdev
organization.
multiboot2
Maintained by @IsaacWoods, @phip1611, @robert-w-gries, @ahmedcharles, and @Caduser2020
The multiboot2
crate provides abstraction types for the multiboot information
structure (MBI) of multiboot2 bootloaders. The latest release of the
multiboot2
-crate is now v0.15.0
(was v0.14.0
), which fixed a
bug. Furthermore, the
documentation was improved. However, the biggest change is that the library now
allows the parsing of custom multiboot tags, which are not prohibited by the
spec. For a full changelog, please refer to the
GitHub repo.
CI Refactoring
In the CI, we want to run many tests that cover a big portion of the cartesian product of the following properties:
- rust version: stable, nightly, msrv
- type: build, test, style check
- target: default, no_std
As I (@phip1611) was annoyed by all the boilerplate configuration and repetition, I've investigated new ways to improve that situation and created a reusable workflow can be used like that:
jobs:
build_msrv:
name: build (msrv)
uses: ./.github/workflows/_build-rust.yml
with:
rust-version: 1.56.1
do-style-check: false
style_nightly:
name: style (nightly)
needs: build_nightly
uses: ./.github/workflows/_build-rust.yml
with:
rust-version: nightly
do-style-check: true
do-test: false
The ./.github/workflows/_build-rust.yml
workflow abstracts setting up the
toolchain, setting up a cargo cache for a faster CI, and, depending on the
configuration, running cargo test|clippy|doc|build|fmt
. I think that the
outcome is quite nice and might also help others. Feel free to check out the
corresponding PR.
uefi-rs
Maintained by @GabrielMajeri, @nicholasbishop, and @phip1611
Features
- debug: add debug implementation for file-related structs
- uefi: Add
delete_variable()
helper - uefi: Drop
'boot
lifetime from Output protocol - error: enable
core::error::Error
for all error payloads - Remove some more protocol lifetime parameters
- uefi: Implement
Borrow
/ToOwned
forCString16
/CStr16
- drop deprecations that are at least in one release
- Add Sorted Iterator for the UEFI Memory Map (Issue#661)
- Switch to the stable channel :tada:
- Merge changes from the 0.20 release
- Rename
global_allocator
module and change scope ofglobal_allocator
feature - debug everywhere
- cfg: Add ESRT GUID
Other Improvements
- uefi-macros: Use a more precise error span
- build(deps): update syn requirement from 1.0.74 to 2.0.4
- Update pull request template
- uefi: Remove static references from
SystemTable
implementation - Set rust-version = 1.68 in all public packages
- uefi: Fill in some more RuntimeServices fn pointers
- uefi: Add opaque_type macro
- uefi: Consistently set
repr(transparent)
on bitflags
Docs
- uefi-macros: Make
entry
example more compatible with stable - uefi: Update package docstring
- Rework "Building UEFI programs" sections in the readmes
- uefi: Improve clarity of global_allocator
CI & Testing
show changes
- xtask: Add
--unstable
option tocargo xtask doc
- ci: Increase Windows job timeout
- xtask: Enable strict provenance checks in Miri
- ci: Add a nightly_channel job
- xtask: Add option to skip uefi-macros tests
- ci: add spellcheck with "typos"
- xtask: Add OVMF_CODE/OVMF_VARS env vars
- OVMF: enable "cargo xtask run" under NixOS
- add Cargo.lock
- ci: MSRV fixes
- ci: Enable caching
- ci: Drop test_latest_release job
- xtask: Turn off some unnecessary dep features
- Add uefi to workspace members
- dependabot: Ignore patch updates
- dependabot: Fix config syntax
- dependabot: Fix config syntax
- ci: Increase Windows timeout to 10 minutes
- Format
use
consistently - test-runner: Speculative fix for Windows CI timeout
Dependencies
show changes
Thanks to @hughsie, @nicholasbishop, @JohnAZoidberg, @phip1611, @JarlEvanson, and @dependabot[bot] for their contributions!
x86_64
Maintained by @phil-opp, @josephlr, and @Freax13
- Remove unused
doc_cfg
feature - Enable
doc_auto_cfg
ondocs.rs
builds - run xtest bash shell
- seal off the
PageSize
trait - Add
Descriptor::dpl
const method and use it in GDT construction - Set permissions to github workflows
- Create a Security Policy
Thanks to @joycebrum for their contributions!
acpi
Maintained by @IsaacWoods
- acpi: Improve memory mapping usage
- aml: Add
l_and
parser and opcode - acpi: Add missing and new fields to GIC CPU interface structure
- Add hack to get
aml
compiling on 32-bit platforms - aml: Do not require unstable features from rustc that are not used
- acpi: Fix compile error when allocator_api is not enabled
Thanks to @A0lson, @rcerc, and @rw-vanc for their contributions!
pci_types
Maintained by @IsaacWoods
Thanks to @devsnek for their contributions!
bootloader
Maintained by @phil-opp
- Run cargo update
- Minor improvements to
BootConfig
- Simplified disk builder
- Release version
0.11.1
- Release
v0.11.2
- Fix docs.rs build
- Release
v0.11.3
Thanks to @jasoncouture for their contributions!
vga
Maintained by @RKennedy9064
Thanks to @bendudson for their contributions!
pic8259
Maintained by @phil-opp
Thanks to @Virux for their contributions!
volatile
Maintained by @phil-opp
Thanks to @joycebrum for their contributions!
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.
phip1611/paging-calculator
(Section written by @phip1611)
In the November newsletter, I announced the initial release of my
paging-calculator
CLI utility. Recently, I released a new version, which now
covers page table indices for x86, x86 with physical address extension (PAE),
x86_64, and x86_64 with 5 levels. For example, just type $ paging-calculator 0xdeadbeef x86
and $ paging-calculator 0xdeadbeef x86 --pae
and compare the result. You can
install it from crates.io or with
the pkgs.paging-calculator
attribute,
if you are a Nix user.
xiaoyang-sde/rust-kernel-riscv
(Section written by @xiaoyang-sde)
rust-kernel-riscv
is an experimental operating system kernel built using Rust's asynchronous programming model to schedule threads in both kernel and user space. This approach allows for more efficient context switching and eliminates the need for allocating a separate kernel stack for each user process. In its current iteration, the kernel provides a basic shell capable of running several executables that demonstrate various kernel mechanisms.
The kernel provides a built-in executor, which manages the scheduling and execution of threads. Threads are executed for a time slice before an exception or interrupt occurs, and then the executor switches to another thread. To give you a better understanding, I included the async
function that represents the lifetime of a user thread below, and I wrote a detailed design document.
async fn thread_loop(thread: Arc<Thread>) {
loop {
let trap_context = thread.state().lock().user_trap_context_mut();
_enter_user_space(trap_context, thread.satp());
// Invokes related methods to handle the exception or interrupt,
// which returns a variant of the `ControlFlow` enum
match control_flow {
ControlFlow::Continue => continue,
ControlFlow::Yield => yield_now().await,
ControlFlow::Exit(exit_code) => {
thread.exit(exit_code);
break;
}
}
}
}
The idea behind rust-kernel-riscv
was inspired by Phil's recent blog post on using async/await
in the kernel. Thanks Phil for his invaluable support to the Rust community!
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.