redox kernel: a Rust microkernel where a panic is a system failure
Mirror of https://gitlab.redox-os.org/redox-os/kernel
At a glance
- What is it?
- The Redox OS kernel is a microkernel written in Rust, and its defining constraint is that kernel code must never panic, because a panic in kernel space stops the whole system. The repository also shows the build and debugging machinery, from a Makefile that drives cargo rustc with a custom target spec to a QEMU and GDB loop on port 1234.
- Who is it for?
- The Redox kernel is worth reading if you are working on microkernel design, Rust in kernel space, or the specific question of how to keep a kernel free of panics, and its clippy configuration and get instead of index convention are concrete examples. It is the wrong starting point for anyone who needs a supported general purpose operating system today, and it is not where you build a Redox system anyway, since the Redox build system cross compiles to a Redox virtual machine.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 25 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 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A mirror of the real kernel repository, not the source of truth
The description of this repository is a mirror of the Redox kernel hosted on GitLab at gitlab.redox-os.org. That single line changes how you should treat everything else here. The code is Rust, the topic tags list linux, microkernel, plan9, redox, sel4 and syscall, and the README calls it the Redox OS Microkernel. But commits land on the GitLab side first, and this GitHub copy is a reflection of that history, so a pull request opened here is not necessarily where the change should land. The README's own contribution note points at a CONTRIBUTING.md in the Redox repository on GitLab rather than in this tree, and the development documentation points at the Redox build system reference and the coding and building pages on doc.redox-os.org. The audience for this repository is therefore twofold: people who want to read how a Rust microkernel is put together, and contributors who need to find their way to the real workflow. The source itself is a Cargo workspace with the kernel package at version 0.5.12, edition 2024, using resolver 3.
The rule that shapes every line: no panics in kernel space
The Notes section of the project documentation carries the single most important engineering constraint in the project, and it is stated bluntly. Always use foo.get(n) instead of foo[n], and cover the possibility of Option::None, because the regular way may work for applications but must never be used in the kernel. No possible panics should exist in kernel space, because then the whole operating system would stop working. This is a Rust specific version of the classic kernel rule that a fault in kernel space brings down the machine, and it has a visible footprint in the code. The clippy configuration in the manifest turns on the lints that catch panic paths: indexing_slicing is set to warn, with a comment that indexing a slice can cause panics and that the project always wants to avoid it, and cast_ptr_alignment is warned for the same reason. Both carry a TODO to address the occurrences and then deny them. arithmetic_side_effects is warned with a note that overflows are very bad in kernel code because they may provide an attack vector for userspace applications, and that the overflow check only happens in debug builds.
Clippy configuration as a policy document
The lint table in Cargo.toml is more than a style choice, it encodes what the project considers unacceptable in kernel code. The lints that are allowed rather than warned are instructive too. identity_op is allowed to permit expressions such as 1 << 0 or 1 * 1024 * 1024, if_same_then_else is allowed so that branches can carry comments explaining why they differ, and many_single_char_names is allowed because the syscall function needs short names. module_inception is allowed for the context::context case, where a module and a function share a name. Other lints are set to allow for a stated cost reason, the pattern being that a construct with a meaningful runtime cost is sometimes worth writing out. For a reader trying to learn how a Rust kernel handles safety, this table is a compact statement of the trade-offs the maintainers are making. The list ends with a truncated section, so the full policy is longer than what is visible here, but the visible part is enough to show the direction: the default is to warn on anything that can panic or overflow, and to allow the exceptions explicitly.
The Makefile drives cargo rustc against a custom target spec
Building the kernel is not a plain cargo build, because the kernel is compiled for a target that no stock toolchain knows about. The Makefile sets RUST_TARGET_PATH to the targets directory in the source tree, derives the architecture from the TARGET variable or from uname -m, and maps a few architecture names onto the ones the toolchain uses, with riscv64gc becoming riscv64 and i686 becoming i586, then forms the GNU target triple from that. The linker script, lock file, manifest and target specification are all resolved from the source directory.
LD_SCRIPT=$(SOURCE)/linkers/$(ARCH).ld
LOCKFILE=$(SOURCE)/Cargo.lock
MANIFEST=$(SOURCE)/Cargo.toml
TARGET_SPEC=$(RUST_TARGET_PATH)/$(ARCH)-unknown-kernel.jsonThe actual compile step is a cargo rustc invocation with a nightly-only set of flags, building core and alloc from source with build-std, using the JSON target specification, and passing the linker script and the maximum page size through link arguments. The output is then split by objcopy into a stripped kernel and a separate symbol file.
$(BUILD)/kernel.sym: $(BUILD)/kernel.all
$(OBJCOPY) \
--only-keep-debug \
"$(BUILD)/kernel.all" \
"$(BUILD)/kernel.sym"The debug loop: QEMU, port 1234, and a separate symbol file
Debugging a microkernel is where the real learning happens, and the documentation describes the loop in detail. Running QEMU with the -s flag makes it listen on port 1234 for a GDB client, and the make target wires that up.
make qemu gdb=yesWith GDB, you load the debug symbols from the file the Makefile produced and then attach to the running machine.
(gdb) symbol-file build/kernel.sym
(gdb) target remote localhost:1234LLDB users get the same session with a different pair of commands, creating the target from the symbol file and the kernel binary together.
(lldb) target create -s build/kernel.sym build/kernel
(lldb) gdb-remote localhost:1234The split between kernel and kernel.sym is the reason the objcopy step exists, and it is what makes a remote session possible at all, since the debugger needs the debug information that is stripped out of the running image. The documentation also gives the recovery command for the moment a panic wedges the virtual machine, where the QEMU process has to be killed by hand.
pkill qemu-systemThe Redox build system is the only supported path to a system
If you want to produce a Redox system rather than read the code, this repository is not the place to start. The How To Build section says you need to download the Redox build system, with a link to the podman build page, and explains why: the components only work with cross compilation to a Redox virtual machine, although some testing can be done from Linux. The debug loop with QEMU described earlier is therefore an inner loop for kernel work, not a way to assemble an operating system. The toolchain also has an external requirement that catches people out, nasm has to be available on the PATH at build time. For documentation, the build script can generate and open the API docs for the syscall interface, and a docs badge at the top of the file points at the published redox_syscall documentation on docs.rs, which is where the user facing syscall contract is written down rather than in this repository.
Reading the tree: syscall, rmm, targets, linkers
The top level layout shows how the kernel is decomposed. The src directory holds the kernel sources, and the syscall subdirectory is a separate crate in the workspace, wired in as a path dependency, which is what publishes the syscall interface to user space. The rmm directory is another path dependency, a Rust memory manager, built with default features off. The targets directory holds the custom JSON target specifications that the Makefile points at, the linkers directory holds the per architecture linker scripts, and res holds resources. There is a build.rs, a config.toml.example, a clippy.sh helper, rustfmt.toml and rust-toolchain.toml for pinning the toolchain, plus an ARM-AARCH64-PORT-OUTLINE.md document describing work on an AArch64 port. The dependency list in the manifest gives a good sense of the engineering style: arrayvec, smallvec and slab for allocation in a context where the general purpose allocator is awkward, bitflags and bitfield for register and structure layout, hashbrown for hashing, spin for locking, an fdt crate pinned to a specific git revision for device trees, and the object crate for ELF handling. The build dependencies are just cc and toml.
Licence, funding and the pace of the mirror
The licence is MIT, which for a kernel means that anyone can take the code and ship it, subject to keeping the notice, and the licence file sits at the root of the repository. The repository is not archived and the last push was on 2026-09-27, so the mirror is receiving updates, but there are no GitHub releases at all, so there is no version tag to pin a build to. The version that matters is the one in Cargo.toml, where the kernel package reads 0.5.12 with edition 2024. A note in the README records that a specific workstream, Unix-style signals and process management, is funded through NGI Zero Core, a fund established by NLnet with financial support from the European Commission's Next Generation Internet program. That is a useful signal about where the project's near term effort goes, and it is the kind of detail you only find in the repository itself rather than in a press release.
Editorial conclusion
The Redox kernel is worth reading if you are working on microkernel design, Rust in kernel space, or the specific question of how to keep a kernel free of panics, and its clippy configuration and get instead of index convention are concrete examples. It is the wrong starting point for anyone who needs a supported general purpose operating system today, and it is not where you build a Redox system anyway, since the Redox build system cross compiles to a Redox virtual machine. Before you rely on it, remember that the GitHub repository is a mirror of the GitLab origin at gitlab.redox-os.org, so the authoritative history and any contribution process live on GitLab, and the kernel crate version in Cargo.toml is 0.5.12.
Frequently asked questions
What is the relationship between the Redox kernel GitHub repository and GitLab?
The repository description states that it is a mirror of the kernel hosted at gitlab.redox-os.org. The README points contributors at the CONTRIBUTING.md in the Redox repository on GitLab, so the authoritative history and contribution process live on GitLab.
How do I build the Redox kernel?
The kernel crate is built through the Makefile in the repository, which drives cargo rustc with a custom target specification from the targets directory and produces both a kernel and a kernel.sym file. Producing a full Redox system instead requires the separate Redox build system and cross compilation to a Redox virtual machine.
How do I debug the Redox kernel with GDB?
Start the machine with the make qemu gdb=yes target so QEMU listens on port 1234, then load the symbols and attach: symbol-file build/kernel.sym followed by target remote localhost:1234. LLDB uses target create -s build/kernel.sym build/kernel and gdb-remote localhost:1234.
Why does the Redox kernel avoid slice indexing?
The README states that no possible panics should ever exist in kernel space, because a panic would stop the whole operating system from working. The convention is to use foo.get(n) instead of foo[n] and to handle the possibility of Option::None, with the clippy indexing_slicing lint set to warn for the same reason.
What extra tools does building the Redox kernel require?
The README lists one requirement, nasm needing to be available on the PATH at build time. The debug workflow additionally expects QEMU, and either GDB or LLDB on the host to attach to the virtual machine.
Official sources
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.
[](https://hysenlabs.com/projects/redox-os-kernel)Was this useful?