Unix-like OS in Rust inspired by xv6-riscv
#+title: octox #+author: Hayato Ohhashi #+email: o8@vmm.dev
octox is a Unix-like operating system inspired by xv6-riscv. octox loosely follows the structure and style of xv6, but is implemented in pure Rust.
[[https://vhs.charm.sh/vhs-6MQBIyAo3DpBrARBxHxL35.gif]]
- Everything from kernel, userland, mkfs, to build system is written in safe
- There are no dependencies on external crates.
- The userland has a library similar to Rustβs std with K&R malloc.
- Multi-core support, buddy allocator as kernel-side memory allocator, file
- Getting Started
- Install the rust toolchain to have cargo installed by following
- Install ~qemu-system-riscv~
- (option) Install ~gdb-multiarch~
- Clone this project & enter: ~git clone ... && cd octox~
- Build: ~cargo build --target riscv64gc-unknown-none-elf~.
- Run: ~cargo run --target riscv64gc-unknown-none-elf~, then qemu will boot
** Play with the Shell
A very simple shell is implemented. In addition to executing commands, you can only do the following things.
- Pipe: ~cat file | head | grep test~
- Dump processes: ~Ctrl + P~
- End of line: ~Ctrl + D~
- Redirect output: ~>~, ~>>~
- Development
The userland comes with a user library called ulib (located at src/user/lib) that is similar to Rustβs std, so you can use it to develop your favorite commands. If you create a bin crate named ~_command~ in src/user/bin, the build.rs and mkfs.rs will place a file named ~command~ in the file system and make it available for use.
- In src/user/Cargo.toml, define a bin crate with the name of the command you
- userland is also nostd, so donβt forget to add ~#[nostd]~. Use ulib to
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() } } #+end_src
- Then, ~cargo run --target riscv64gc-unknown-none-elf~ in the root of octox.
- To use ~Vec~ and ~String~, etc, do the following:
** Kernel
Developing in src/kernel. Here is an example of adding a system call. If you want to add a new system call, you only need to add a definition to the system call table in libkernel, and the userland library will be automatically generated by build.rs.
- Add a variant and Syscall Number to ~enum SysCalls~ in src/kernel/syscall.rs.
- Define the function signature of the system call in the ~TABLE~ of
- With just these steps, the dup2 system call is implemented in both kernel and
- License
- [[http://www.apache.org/licenses/LICENSE-2.0][Apache License, Version 2.0]]
- [[http://opensource.org/licenses/MIT][MIT license]]
- Acknowledgments
I'm also grateful for the bug reports and discussion about the implementation contributed by Takahiro Itazuri and Kuniyuki Iwashima.
- Contribution