Library / SDK
o8vm/octox avatar
o8vm/octox

octox: a Rust Unix-like operating system for RISC-V development

Unix-like OS in Rust inspired by xv6-riscv

1,906 stars78 forksRustApache-2.0

At a glance

What is it?
octox is an educational Unix-like operating system inspired by xv6-riscv and implemented in pure Rust without external crates. It targets RISC-V developers who want a compact environment for studying kernel, userland, build-system, and system-call implementation.
Who is it for?
Adopt octox for learning OS implementation or experimenting with Rust system code on RISC-V, rather than as a production operating system. Do not choose it when you need a documented production platform, stable driver model, or established user environment.
Can I use it commercially?
Yes. Apache-2.0 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 26 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 23, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • o8vm/octox1,906 ★ · +2
Star history
Repository2026-10-162026-10-23
o8vm/octox1.9k1.9k

2 Stars in the last 7 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

octox's Rust and RISC-V foundation

octox addresses a specific educational problem: it gives developers a compact Unix-like system in which the kernel, user applications, filesystem image generator, and build process can be studied as one Rust workspace. It follows the structure and style of xv6-riscv, but the README states that its implementation is pure Rust and has no dependencies on external crates. The repository root configures `riscv64gc-unknown-none-elf` as the forced target, while the workspace contains `src/kernel`, `src/mkfs`, and `src/user`.

That scope is appropriate for someone learning how an operating system connects privileged kernel code to a restricted userland. It is also relevant to developers who prefer to understand a small system by changing its syscall table, allocator, shell, or filesystem rather than adopting an existing kernel. The design does not try to conceal that lineage. The README explicitly identifies xv6-riscv as its inspiration.

The central trade-off is pedagogical compactness. octox provides Unix-like ideas and selected mechanisms, but it is described as a hobby learning project. Its shell supports only a few operations beyond command execution, and its userland is `no_std`. That makes the source more suitable for an operating systems exercise than for a general-purpose desktop, server, or embedded product. The repository offers a place to inspect implementation decisions, not a claim that octox is ready to replace an established OS.

Kernel, userland, and filesystem image flow

The documented build starts from a Cargo workspace, but octox extends Cargo with Rust source files that participate in operating-system construction. A user command is a bin crate under `src/user/bin`. The README states that `build.rs` and `mkfs.rs` place a file named after that command into octox's filesystem. In other words, adding a user command affects both compilation and the filesystem image rather than requiring a separately described installation procedure.

The userland library is `ulib`, located at `src/user/lib`, and is described as similar to Rust's `std`. User programs can import `env` and `fs`, parse arguments, and remove files. The library is intended to provide the narrow runtime surface needed in this environment. For collection types, programs import Rust's allocation modules directly.

The kernel side uses a syscall table defined in `src/kernel/syscall.rs`. Adding a variant and syscall number is followed by adding the corresponding entry to `TABLE` and implementing the kernel method. According to the README, `build.rs` then generates the userland library side automatically. This makes the boundary between kernel and user programs explicit: a syscall has a numeric identity, a typed table signature, and a kernel implementation, while its user-facing wrapper is generated.

octox also documents multicore support, a buddy allocator, a logging-capable filesystem, and a K&R-style `malloc` in its userland. These features show that the system is broader than a single-process demonstration, although the README does not provide performance figures, supported hardware matrices, production storage guarantees, or a detailed compatibility list.

Building octox and reaching its shell under QEMU

The README lists a Rust toolchain with Cargo, `qemu-system-riscv`, and optionally `gdb-multiarch` as requirements. After obtaining the repository and entering its root directory, the documented build command is:

bash
cargo build --target riscv64gc-unknown-none-elf

The target is also the package's forced target in `Cargo.toml`, so this command is central to producing the RISC-V bare-metal build. The README does not provide a separate installation script or publish a release package. It points developers to the repository's build process.

After building, run the system from the repository root:

bash
cargo run --target riscv64gc-unknown-none-elf

The documented result is that QEMU boots octox. Exit QEMU with the key sequence `Ctrl+a`, then `x`. A real first use at the shell can exercise the documented pipe and grep functionality:

bash
cat file | head | grep test

The shell can also inspect processes with `Ctrl+P`, signal end of input with `Ctrl+D`, and redirect output with `>` or `>>`. These examples describe expected command forms from the README. They do not establish the full set of commands, regular-expression behavior, quoting rules, or error messages, so the shell should be treated as intentionally minimal.

Adding a no_std user command to octox

The documented userland extension point is the `[[bin]]` entry in `src/user/Cargo.toml`. Registering the crate makes the build and filesystem generator place the corresponding executable into octox's filesystem. This naming convention removes the underscore used for Cargo's internal bin identity before the file is made available to the shell.

For example, a command configured as follows:

toml
[[bin]]
name = "_rm"
path = "bin/rm.rs"

can be implemented as a `no_std` Rust program:

rust
#![no_std]
use ulib::{env, fs};

fn main() {
    let mut args = env::args().skip(1).peekable();

    if args.peek().is_none() {
        panic!("Usage: rm files...")
    }
    for arg in args {
        fs::remove_file(arg).unwrap()
    }
}

The program then becomes part of the build described by `cargo run --target riscv64gc-unknown-none-elf`. If it needs `Vec` or `String`, the README directs the developer to import them from `alloc`:

rust
extern crate alloc;
use alloc::{string::String, vec::Vec};

This workflow is useful for experimentation because the location and registration mechanism are concrete. Its limitations are equally important. The example uses `unwrap()` without defining an application-level error policy, and the README does not document `ulib`'s complete API surface. A command can be structurally added without receiving the safety guarantees or compatibility expectations of a mature standard library.

Extending the kernel through octox's syscall table

octox reduces some of the code generation involved in adding a syscall. The developer first adds a variant and number to `SysCalls`, then describes the call in `TABLE`. The table uses `Fn` to classify a return type as `U` for unit, `I` for integer, or `N` for never. Arguments are represented as a string signature, which the README associates with automatic userland generation through `build.rs`.

The documented `Dup2` addition illustrates the relevant shapes. Its table entry can use an integer result and the argument string `(src: usize, dst: usize)`. The kernel implementation reads raw argument positions, obtains the current process, accesses its open-file collection, and moves the source descriptor into the destination when they differ. It also clears the close-on-execute flag on the source descriptor before replacement.

This table-driven design reduces duplicated knowledge about the call boundary, but it also concentrates changes in a central registry. Adding or changing a signature requires coordination among the enum, table, implementation, and generated userland wrapper. The README does not explain versioning of the syscall ABI, compatibility with prior user programs, audit requirements, or a stable API policy. That is acceptable for a learning OS, but it is a boundary for any project expecting a durable kernel interface.

The conditional compilation shown for `dup2` also makes clear that source is shared across kernel and non-kernel builds. A contributor must understand feature and target conditions rather than treating the Rust file as ordinary host-side application code.

octox's maintenance boundary and dual licensing

The repository is not archived, and its last push was on 2026-09-27. That is recent relative to the current date, but the repository has no GitHub releases. Recent repository activity therefore does not provide tagged operating-system images, a published release cadence, or an explicit upgrade policy. The README calls octox a hobby learning project and warns that contribution reviews may take considerable time. Those statements matter when judging maintenance expectations more than activity alone.

The repository metadata at the root identifies the workspace license as `MIT/Apache-2.0`. The README gives users a choice between the Apache License, Version 2.0 and the MIT license, and the repository contains both `LICENSE-APACHE` and `LICENSE-MIT`. This differs from a repository that offers only one license. Code selection, third-party material, and distribution conditions should be checked against the applicable license files, but this review does not provide legal advice.

For upgrades, the concrete boundary is the workspace itself: package version `0.1.0`, the pinned RISC-V target, Cargo workspace members, and the repository's Rust source. The README does not publish compatibility tables, a migration guide, release notes, or instructions for upgrading an existing filesystem image. Developers should therefore treat repository changes as source-level changes and avoid assuming that a stable update path exists.

When octox is useful and where its scope stops

octox is a reasonable choice for an individual learning how Unix-like kernels are assembled from Rust components. It offers a documented route from Cargo workspace to QEMU boot, a small shell, a filesystem image generator, a buddy allocator, multicore support, and a syscall generation path. It is also a useful alternative for developers who want to read a system modeled on xv6-riscv without following a C implementation.

It is the wrong choice for a production deployment. The project identifies itself as a hobby learning project, publishes no GitHub releases, offers no homepage or product support statement, and documents only a very small shell. The absence of external crates reduces dependency concerns within the stated implementation, but it does not establish production readiness, hardware coverage, security certification, or operational support.

Compared with xv6-riscv, octox keeps the same broad inspiration but changes the implementation language and adds a Rust-oriented workspace, `ulib`, and syscall wrapper generation. Compared with a conventional hosted Unix system, octox lacks the documented breadth of a production userland. Its value lies in inspectability and a constrained target: developers can follow the path from a user crate to a filesystem entry, or from a table declaration to a kernel method, without first navigating a large general-purpose platform.

Editorial conclusion

Adopt octox for learning OS implementation or experimenting with Rust system code on RISC-V, rather than as a production operating system. Do not choose it when you need a documented production platform, stable driver model, or established user environment. Verify first that your installed Rust toolchain and QEMU RISC-V setup can build and boot the repository, and inspect the target-specific source because the documented userland is no_std and intentionally small.

Frequently asked questions

How do you build and boot octox on RISC-V?

Install Cargo and `qemu-system-riscv`, then run `cargo build --target riscv64gc-unknown-none-elf` followed by `cargo run --target riscv64gc-unknown-none-elf`. The README states that QEMU boots octox and can be exited with `Ctrl+a`, then `x`.

Does octox depend on external Rust crates?

No. The README states that everything from the kernel and userland to `mkfs` and the build system is written in safe Rust as much as possible, with no dependencies on external crates.

How do I add a command to octox's userland?

Add a bin crate under `src/user/bin`, register it in `src/user/Cargo.toml` with an underscore-prefixed name, and use `ulib` plus `#![no_std]` in the Rust source. The README states that `build.rs` and `mkfs.rs` place the command in octox's filesystem and make it available to the shell.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. o8vm/octox on GitHub
  4. README
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/o8vm-octox.svg)](https://hysenlabs.com/projects/o8vm-octox)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/o8vm-octox.svg)](https://hysenlabs.com/projects/o8vm-octox)

Was this useful?