A language that doesn't affect the way you think about programming is not worth knowing. –Alan J. Perlis
For the last 40 years, the C programming language has dominated operating system (OS) development. Today, however, C's long-standing dominance is being challenged by Rust[1], a modern system programming language that promises speed, safety, and productivity. Rust is fundamentally different from C in ways that provide OS researchers and developers with new tools and perspectives for addressing long-standing challenges such as kernel memory safety. This shift invites us to revisit the traditional wisdom established during the C era.
This mindset led us to ask a series of questions: What is the ideal architecture for Rust-based OSes? How can one build a feature-rich, general-purpose, Rust-based OS kernel with a minimal and sound TCB for memory safety? In other words, if we were to rework a Linux-like kernel from the ground up in Rust, what would it look like?
Over the past three years, we have explored these questions in depth, and we are now ready to share our answers: a novel OS architecture we call a framekernel and a new Linux ABI-compatible framekernel written in Rust, named Asterinas.
This article provides an overview of the framekernel architecture and the Asterinas kernel. For technical details, refer to our USENIX ATC'25 paper[2]; a preprint is also available on arXiv[3]. Asterinas is open-source, and you can explore the project on GitHub[4].
On July 19, 2024, millions of Windows systems suddenly crashed with the infamous "blue screen of death." This global incident—now known as the CrowdStrike outage[5]—was caused by a memory safety bug in a Windows driver: an out-of-bounds memory access. This incident serves as a sobering reminder that even mature, commercial OSes like Windows and Linux remain vulnerable to memory safety flaws. Studies estimate that 60–70% of critical security vulnerabilities in C-based system software, including Linux, stem from memory safety bugs[6][7].
As Rust has matured and gained popularity, Rust-based OSes have attracted growing attention. Rust provides memory safety guarantees through innovative features such as ownership, borrowing, and lifetimes, enabling safe memory management without garbage collection. Many now regard Rust as a leading candidate to succeed C and C++ as the dominant systems programming language. The Rust for Linux (RFL) project[8] has been integrated into Linux to facilitate writing "leaf" kernel modules in Rust. New OS kernels like Tock[9], RedLeaf[10], and Theseus[11] are built from the ground up using Rust.
While adopting Rust is a significant step toward kernel memory safety, it is not sufficient on its own, because Rust-based OSes must include unsafe
Rust code. The Rust type system, although powerful and expressive, cannot determine whether low-level, machine-oriented operations in kernel programming—such as accessing CPU registers, manipulating page tables, or writing to physical memory—are safe, unless explicitly marked so by the programmer with the unsafe
keyword. It is the programmer's responsibility to use the unsafe
keyword correctly and discreetly; failing to do so can lead to undefined behaviors (UBs) and undermine Rust’s memory safety guarantees. Despite the Rust team authoring the Rustonomicon[12], a book dedicated to the “dark arts” of unsafe Rust, developers remain prone to misusing unsafe
, as evidenced by hundreds of related bugs recorded in the RustSec Advisory Database[13].
Rust kernel developers generally view unsafe
as a “necessary evil”, though the extent of its necessity is open to debate. We have observed that unsafe Rust code permeates a significant portion of a Rust-based OS: unsafe
-utilizing crates make up 55%, 93%, 62%, and 32% of all crates in Rust for Linux, Tock, RedLeaf, and Theseus, respectively. We question whether such widespread use of unsafe
is truly necessary. In particular, we challenge the necessity of unsafe
in device drivers (as seen in all existing Rust-based OSes), which account for the majority of the codebase of a mature OS (70% in Linux[14]).

In RFL, the primary reason for using unsafe
is the interaction between Rust and C. By design, RFL has to offer safe Rust abstractions over Linux’s extensive legacy C API. A recent study[15] notes that RFL already has 19K lines of Rust code upstream, with an additional 112K lines staged for inclusion. A significant portion of RFL is devoted to unsafe Rust code that interacts with the legacy C APIs. As RFL expands to cover more subsystems and their C APIs, codebase will grow to hundreds of thousands of lines. Therefore, the memory-safety TCB size of RFL is substantial, even without considering Linux's huge C core and the countless C kernel modules around it.
Lesson learned: Constructing safe Rust abstractions in a legacy monolithic kernel inevitably requires a substantial use of unsafe Rust.
In addition to the inflated TCB size, the burden of a huge legacy codebase—its status quo and established philosophies—constrains the effectiveness of Rust and the soundness of RFL. For example, forgetting RFL’s mutex guards (memory leakage) can trigger use-after-free vulnerabilities[16] and sleep-in-atomic-context bugs may cause data races in RCU-protected memory accesses[17]. These known soundness issues remain unresolved because of the Linux community’s traditional value of "pragmatism over safety", which is in conflict with Rust’s safety-first paradigm.
Lesson learned: Achieving sound memory safety requires a clean-slate OS that prioritizes safety above all else.
Prior clean-slate Rust OSes like Tock[9], RedLeaf[10], and Theseus[11] strive to fully leverage Rust’s features to improve OS safety and reliability. However, they face a notable limitation: inadequate support for safe driver development. Device drivers in these systems frequently rely on unsafe code to manage low-level resources, such as raw data buffers, MMIO, I/O ports, and DMA regions. The unsafe coding patterns in their device drivers are summarized in Table 2.

Given that drivers typically constitute the largest portion of an OS codebase, extensive use of unsafe
significantly heightens the risk of memory safety vulnerabilities.
Lesson learned: Safe driver development requires safe abstractions for acquiring and accessing low-level system resources.
In light of the limitations of prior Rust-based OSes and the lessons learned from them, we propose the framekernel architecture, a novel OS design aimed at achieving a minimal and sound TCB for a Rust-based OS. In the framekernel architecture, an entire Rust-written OS kernel runs in a single address space (similar to a monolithic kernel) but is logically divided into two parts: the privileged OS framework (akin to a microkernel) and the de-privileged OS services.
The OS framework is privileged in that it is the only component permitted to use unsafe
. Conversely, the OS services are de-privileged, restricted to safe Rust only. The privileged framework encapsulates all low-level, hardware-oriented unsafe
operations behind safe APIs. Using these APIs, the de-privileged OS services can implement all high-level OS functionality, e.g., process management, task scheduling, file systems, network stacks, and device drivers.
This language-based, intra-kernel privilege separation means that memory safety depends solely on the correctness of the privileged OS framework—a small TCB comparable to a microkernel. Meanwhile, different OS components can communicate through efficient mechanisms—such as function calls and shared memory—a hallmark of monolithic kernels. In this sense, the framekernel architecture combines the performance of a monolithic kernel with the security benefits of a microkernel, making it an ideal architecture for memory-safe OSes in Rust.

To realize the vision of framekernels, we have developed OSTD, the privileged OS framework that forms the foundation of a framekernel-based OS. We named it OSTD to reflect our goal of making it Rust’s (unofficial) standard library for OS development. It is publicly available on crates.io[18]. OSTD offers a small set of powerful abstractions, whose safe APIs are used by OSTD clients—safe kernel components that build on top of OSTD. These APIs are expressive enough to meet the three primary needs of safe OS development: (1) safe user-kernel interactions, (2) safe kernel logic, and (3) safe kernel-peripheral interactions.
To illustrate how OSTD enables safe OS development, consider a minimal “Hello World” framekernel built around a basic system call loop, as shown by the figure below.

This example uses four key safe abstractions from OSTD: (1) Task
handles context switching and kernel stacks; (2) UserMode
allows the CPU to execute in the user mode until an event occurs; (3) UserContext
enables safe access and manipulation of the user-mode CPU state such as general-purpose registers; (4) VmSpace
allows access to and management of user-space virtual memory. Each of these abstractions encapsulates underlying unsafe Rust code behind well-defined, safe APIs. With OSTD, developing a Rust kernel can be done as safely as doing Rust applications. For a fully working example, check out our sample project "Write a Hello World kernel in around 100 lines of safe Rust"[19].
One key design goal of OSTD is soundness, i.e., the absence of undefined behaviors (UBs). UBs are operations that compromise Rust's correctness and safety guarantees. The Rust Reference book enumerates common UBs[20], e.g., data races, memory access based on dangling or misaligned pointers, out-of-bound memory access, violations of the pointer aliasing rules, and mutation of immutable memory. In kernel space, UBs may also arise from the kernel’s control over its own execution environment—when the code, stack, or heap is corrupted. UBs can also originate at the hardware level, due to incorrect usage of CPU features or peripheral devices—for instance, misconfigured page tables, improperly saved CPU registers, or memory corruption caused by unchecked DMA.
Achieving soundness is challenging because OSTD has to do so despite buggy safe clients, malicious user programs, or faulty peripheral devices. To ensure soundness, we utilize a combination of software-based (e.g., Rust's type system) and hardware-based (e.g., MMU and IOMMU) protections to enforce a set of key safety invariants. We also extend Miri[21], Rust’s official UB detection tool, to systematically identify potential safety issues within OSTD. See our ATC’25 paper for technical details.
One ongoing effort is to formally verify critical unsafe components in OSTD (e.g., page tables) using Verus[22]. Our current progress is documented in a blog post on the Asterinas website[23].
We have developd Asterinas, a Linux ABI-compatible OS written entirely in safe Rust using OSTD APIs. Together with OSTD, Asterinas constitutes a complete implementation of a framekernel. An overview of its architecture is shown in Figure 3.

Asterinas supports a substantial subset of Linux features—including virtual memory, user processes, preemptive scheduling, IPC, a page cache, virtual file systems, and sockets—implementing over 210 system calls. It includes support for multiple file systems (e.g., Ext2, exFAT32, OverlayFS, RamFS, ProcFS, and SysFS), socket types (e.g., TCP, UDP, Unix, and Netlink), and devices (e.g., Virtio Block, Virtio Network, Virtio Vsock, USB controllers, and USB HID). Two CPU architectures are supported: x86-64 (tier-1) and RISC-V (tier-2). All of this functionality is implemented in safe Rust using OSTD’s APIs. Asterinas has been under active development for three years. The combined repositories of Asterinas and OSTD are open source[4] and now contain over 100K lines of Rust, contributed by more than 50 individuals[24].
To minimize the TCB, Asterinas—rather than OSTD—implements much of the OS infrastructure traditionally considered part of Linux’s core, leveraging the privilege boundary defined by the framekernel design. For instance, Asterinas manages all interrupt bottom halves, such as softirq, tasklets, and work queues, by using an interrupt handling hook provided by OSTD. OSTD enforces “atomic mode” to prevent client-provided callbacks from sleeping in interrupt context. Asterinas also manages system time, monotonic time, and wall clocks by registering timer interrupts and reading the timestamp counter (TSC) via OSTD.
We conducted a thorough evaluation of Asterinas and OSTD. Asterinas delivers performance on par with Linux. On LMbench, a syscall-intensive microbenchmark, it achieves a mean normalized performance score of 1.08 (relative to Linux; higher is better). For three I/O-intensive applications—Nginx, Redis, and SQLite—it delivers normalized scores of 1.17, 1.31, and 0.85, respectively. The framekernel design also yields a lean TCB: Asterinas’s TCB accounts for just 14.0% of its codebase, versus 43.8% in Tock, 62.4% in Theseus, and 66.1% in RedLeaf. These results highlight the practicality and benefits of the framekernel architecture.
This article presents Asterinas, a Linux ABI-compatible OS kernel based on the novel framekernel architecture. Our work demonstrates that an OS kernel written in Rust can be simultaneously feature-rich, general-purpose, high-performance, and memory-safe.
With memory safety effectively addressed, we can now shift our focus to bugs beyond memory safety, such as logic errors and concurrency issues. For example, Converos—a companion project from the Asterinas community, also appearing at USENIX ATC 2025[25]—demonstrates how model checking can uncover subtle concurrency bugs in the Asterinas kernel. Looking ahead, we envision leveraging Rust’s strong, expressive type system to prevent logic errors and enable lightweight formal verification of critical OS properties.
As a relatively new kernel, Asterinas is still under active development and not yet production-ready. In 2025, we will add support for Linux namespaces and cgroups—key features for server applications. We are also working on a graphics subsystem to enable desktop scenarios. By the end of this year, we will complete a comprehensive device driver model. Support for the ARM architecture is planned as well.
The road ahead is long, but the foundation is solid. Built on OSTD, Asterinas reimagines what an OS kernel can be in the Rust era. We invite the community to join us in building a new OS—one that remains compatible with the past, yet boldly ready for the future.