Open-source project
thepowersgang/rust_os avatar
thepowersgang/rust_os

rust_os: a deliberately experimental Rust kernel with a window manager

An OS kernel written in rust. Non POSIX

817 stars51 forksRustNOASSERTION

At a glance

What is it?
The rust_os project, nicknamed Tifflin, is a non-POSIX operating system kernel written in Rust that includes an object-based syscall API, a kernel provided window manager and its own init format, and it covers ISO9660, FAT, PATA, SATA, AHCI, VirtIO and PS2 drivers. It suits systems programmers studying kernel design in Rust, and it is a poor fit if you need a Unix compatible kernel or a production operating system.
Who is it for?
rust_os suits a systems programmer who wants to read a kernel written in Rust rather than in C, and who is interested in the parts a conventional kernel abstracts away, because the object-based syscall API, the custom init format and the kernel owned window manager are all deliberate departures from the Unix model and all readable in a single tree.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 14 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

An experiment, and the README says so first

The project opens with its own framing. The title is Tifflin, an Experimental Kernel, and eventually Operating System, and the first line of the README calls it an experiment in writing an OS Kernel in Rust.

The second line is the design statement, and it is unusually candid. Mostly the architecture is being designed as I go along, but it will be written to be architecture independent, with the current version being x86_64 or amd64.

So the honest description is a kernel that is being written, with an architecture independence goal rather than an architecture independence guarantee. The progress list in the README backs that up, ending with a two-line entry for the architectures: amd64, which boots to the limit of implementation, and armv7, which loads userland and then crashes.

That last line is the most useful sentence in the document for anyone deciding whether to spend time here. A port that loads userland and then crashes is a port that has not been brought up, and no amount of reading will change that.

The licence is a custom one that GitHub cannot classify, with a COPYING file in the repository root, the primary language is Rust, the last push to the repository was on 2026-10-11, and there are no published releases, so this is a tree you build yourself rather than a version you install.

Userland owns the ELF loader, the kernel owns its own init

The design features list is short, and the second item is the one with the most architectural consequence.

Runtime module initialisation with dependencies is the first, and it is the kind of thing that sounds like a detail until you try to work without it. Modules in the kernel are initialised at runtime in dependency order, which means the system can be extended without recompiling a fixed initialisation sequence.

The second is clear user-kernel separation of duties, with the detail that userland owns the ELF loader and the kernel uses a custom format for init.

That last clause is the interesting one. In a Unix system, init is an ordinary ELF binary loaded by the kernel's own ELF loader, and that loader is part of the kernel. Here the roles are reversed. The kernel cannot load an ELF file, so init is in a custom format, and the ELF loader lives in userland where it belongs conceptually but where the kernel has to hand over control in an unusual way.

The trade-off is a real one. You gain a kernel that does not have to carry an ELF parser, which is a meaningful reduction in the size and attack surface of the most privileged code in the system. You pay with a boot process that does not look like any other operating system, and with the fact that the first userland program has to be a custom binary.

For a reader studying kernel architecture, that is a genuinely instructive arrangement rather than a quirk, because it makes visible a decision that most kernels hide.

An object-based syscall API and a window manager inside the kernel

Two more design features complete the picture, and both are counter to what you would expect from a small kernel.

The first is an object-based syscall API. Rather than a flat table of system call numbers with a switch, the interface is organised around objects. The connection to the other design decision is not stated in the README, but an object oriented syscall interface is what lets a kernel expose a window manager and a filesystem with a single consistent calling convention, rather than growing a bespoke interface for each subsystem.

The second is a kernel-provided window manager, with the README adding the parenthetical that old windows did this. It is a joke and a design statement at once.

The progress list shows what that window manager is used for. Under GUI apps there is a Login application, with the credentials given as root and password, a GUI Shell with a background, a Text Terminal app with a basic set of commands, and a Filesystem viewer.

So this kernel is not a headless research prototype. It boots, it starts a login, it has a shell, a terminal and a file browser, and it draws a desktop. That is a much more complete artefact than most hobby kernels, and it is also the source of the project's complexity.

The graphics support is listed as Multiboot only, which is a narrow constraint. Multiboot is the boot protocol, and the graphics implementation is tied to that path rather than to a general framebuffer driver, so the graphics output you get is the one the Multiboot loader can set up.

Filesystems, storage and input drivers

The progress list is organised by subsystem, and it is the clearest picture of what the kernel can actually talk to.

On filesystems there is ISO9660 and FAT12, FAT16 and FAT32. ISO9660 is the read-only filesystem of the CD era, and FAT is the one every USB stick and camera uses, so between them the kernel can read almost anything you are likely to have on a stick.

On storage there is PATA, which is the old parallel interface, SATA with AHCI, ATAPI CDROM, and VirtIO Block. VirtIO Block is the important one for anyone running this in QEMU, because it is the paravirtualised disk interface that a virtual machine exposes, and a kernel that can drive VirtIO can be tested without emulating a real controller.

On input there is PS2 keyboard and mouse, which is again the QEMU friendly choice, since a PS2 keyboard and mouse are what a PC has had since the nineties and what QEMU emulates by default.

Taken together, the driver set is coherent for its purpose: this is a kernel built to boot in QEMU on x86 and to have a graphical desktop. It is not a kernel with a broad hardware story, and the repository layout matches, with a Bootloaders directory, a Graphics directory, a Kernel directory, a Usermode directory, a Shared directory, a NativeKernel directory, an acpica directory for the ACPI implementation, externals for vendored crates, a rundir directory that is the run directory, and a SystemTest directory.

The auxiliary scripts in the root are also telling: CheckSubrepos.sh, UpdateSubrepos.sh, FullTestCompile.sh, LineCount.sh, UnsafeAudit.sh, PushScreenshots and a gdb_helpers directory.

The build pulls a pinned rustc and vendored crates

Building an operating system in Rust means building the compiler's standard library from source, and the Makefile shows how this project does it.

The UPDATE target installs rustup into a local prefix directory and then updates the toolchain to a specific version.

bash
	mkdir -p .prefix
	curl https://static.rust-lang.org/rustup/rustup-init.sh -sSf | RUSTUP_HOME=$(abspath .prefix) CARGO_HOME=$(abspath .prefix) sh -s -- --default-toolchain none --no-modify-path -y
	$(call fn_rustcmd,rustup) update $(RUSTUP_VER) --force
	$(call fn_rustcmd,rustup) default $(RUSTUP_VER)
	$(call fn_rustcmd,rustup) component add rust-src

Two details are worth noting. The rust-src component is added because the kernel needs to rebuild the standard library, which is what the libcore_nofp.patch file in the repository root is about, a patch to make the core library work for a kernel that has no floating point in the ordinary sense. And the toolchain is pinned by version and installed into a local prefix rather than into your home directory, so the build does not disturb the Rust installation on your machine.

The EXTERNALS target checks out vendored crates into externals/crates.io, and the fn_checkout macro it uses clones a repository only if the directory is not already present, reading the URL from a .repo file next to it. The three crates it pulls are cmdline_words_parser, utf16_literal and va_list.

The build dependencies for the whole project are nasm for the assembly parts, GNU Binutils cross compiled, and GCC for ACPICA. The ACPICA dependency is what the acpica directory in the tree is for, and it is worth knowing about before you start, because building an ACPI implementation is not a small task.

The top level targets are simple enough to describe in full. The run target depends on all, and delegates to make in the rundir directory. The all target builds Graphics, then Usermode, then Kernel, in that order. And there is a clean target for both Usermode and Kernel.

Running it means a QEMU PXE boot

The testing section is a single line, and it tells you the expected workflow.

With the required dependencies installed, run make -C rundir ENABLE_VIDEO=1 to do a standard QEMU PXE boot with display output enabled.

So the default mode of operation is a PXE boot in QEMU, which is the pre boot eXecution Environment, the network boot mechanism. Booting over the network rather than from a disk image means the kernel image is served to the virtual machine by a PXE server, and the tools the README lists for running include pxelinux for doing PXE boots, described as the default, plus grub-mkrescue for ISO boots and OVMF firmware for EFI boots.

The other running dependencies are qemu-system-amd64 or another qemu-system binary, mtools for making FAT volumes, and libguestfs-tools for creating generic disk images.

The ENABLE_VIDEO=1 switch is the interesting one, because it is how you see the window manager. Without it you get a text console, and with it the graphical desktop with the login, the shell and the terminal. Given that a kernel provided window manager is one of the headline design features, the fact that the graphical mode is a flag on the QEMU invocation is a small but telling detail about how the project expects to be used.

The repository root also has a Makefile.common, a common.mk, a rust_os.code-workspace file for Visual Studio Code, a .vscode directory and a .travis.yml, which dates the continuous integration setup to the Travis era.

Editorial conclusion

rust_os suits a systems programmer who wants to read a kernel written in Rust rather than in C, and who is interested in the parts a conventional kernel abstracts away, because the object-based syscall API, the custom init format and the kernel owned window manager are all deliberate departures from the Unix model and all readable in a single tree. It does not suit anyone needing POSIX compatibility, a stable userland contract, or a machine that is not a PC, since the graphics support is Multiboot only and the armv7 port loads userland and then crashes. Before you build it, install the build dependencies, nasm, cross compiled GNU Binutils, GCC for ACPICA and a pinned rustc toolchain, and expect the amd64 port to be the only one that reaches a usable state, with the README's own summary of the armv7 port as the honest baseline.

Frequently asked questions

What is the rust_os or Tifflin project?

It is an experiment in writing an operating system kernel in Rust, and it is not POSIX. Its design features include runtime module initialisation with dependencies, a clear user-kernel separation where userland owns the ELF loader and the kernel uses a custom format for init, an object-based syscall API and a kernel-provided window manager.

How do I build and run the rust_os kernel?

The build needs nasm, cross compiled GNU Binutils and GCC for ACPICA, and the Makefile installs a pinned rustc toolchain with the rust-src component into a local prefix. Running is make -C rundir ENABLE_VIDEO=1, which does a QEMU PXE boot with display output enabled.

Which architectures does the rust_os kernel support?

The current version is x86_64 or amd64, which the README says boots to the limit of implementation. The armv7 port loads userland and then crashes, and graphics support is Multiboot only.

What drivers and filesystems does the rust_os kernel include?

Filesystems cover ISO9660 and FAT12, FAT16 and FAT32. Storage covers PATA, SATA with AHCI, ATAPI CDROM and VirtIO Block, input is PS2 keyboard and mouse, and the GUI side includes a Login app with root and password credentials, a GUI shell, a text terminal and a filesystem viewer.

Is the rust_os kernel suitable for production use?

The README describes it as an experiment whose architecture is still being designed as it goes along, with the armv7 port loading userland and then crashing, and the project publishes no releases. It is a research and learning codebase rather than a deployable operating system.

Official sources

  1. Issues
  2. README
  3. thepowersgang/rust_os on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/thepowersgang-rust-os.svg)](https://hysenlabs.com/projects/thepowersgang-rust-os)

Was this useful?