- Notifications
You must be signed in to change notification settings - Fork64
Unix-like OS in Rust inspired by xv6-riscv
License
Apache-2.0, MIT licenses found
Licenses found
o8vm/octox
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
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.
- Everything from kernel, userland, mkfs, to build system is written in safe Rust as much as possible.
- 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 system with logging support, etc.
- Install the rust toolchain to have cargo installed by followingthis guide.
- 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 octox. To exit, pressCtrl+a
andx
.
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:
>
,>>
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 namedcommand
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 want to create with a
_
prefix[[bin]]name ="_rm"path ="bin/rm.rs"
- userland is also no_std, so don’t forget to add
#[no_std]
. Use ulib to develop any command you like. Here is an example of the rm command.#![no_std]use ulib::{env, fs};fnmain(){letmut args = env::args().skip(1).peekable();if args.peek().is_none(){panic!("Usage: rm files...")}for argin args{ fs::remove_file(arg).unwrap()}}
- Then,
cargo run --target riscv64gc-unknown-none-elf
in the root of octox. - To use
Vec
andString
, etc, do the following:externcrate alloc;use alloc::{string::String, vec::Vec};
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. Here isDup2
as an example:pubenumSysCalls{Fork =1, ...,Dup2 =23,Invalid =0,}
- Define the function signature of the system call in the
TABLE
ofSysCalls
. Use the enum typeFn
to describe the return type(U
(Unit),I
(Integer),N
(never)) and use&str
to represent arguments. then, define kernel-side implementation as a method onSysCalls
.cfg
flag is used to control the compilation target for kernel and the rest. Here is an example ofdup2
:implSysCalls{pubconstTABLE:[(fn,&'staticstr);variant_count::<Self>()] =[(Fn::N(Self::Invalid),""),(Fn::I(Self::fork),"()"),(Fn::N(Self::exit),"(xstatus: i32)"), ...,(Fn::I(Self::dup2),"(src: usize, dst: usize)"),];pubfndup2() ->Result<usize>{#[cfg(not(all(target_os ="none", feature ="kernel")))]returnOk(0);#[cfg(all(target_os ="none", feature ="kernel"))]{let p =Cpus::myproc().unwrap().data_mut();let src_fd =argraw(0);let dst_fd =argraw(1);if src_fd != dst_fd{letmut src = p.ofile.get_mut(src_fd).unwrap().take().unwrap(); src.clear_cloexec(); p.ofile.get_mut(dst_fd).ok_or(FileDescriptorTooLarge)?.replace(src);}Ok(dst_fd)}}
- With just these steps, the dup2 system call is implemented in both kernel and userland.
Licensed under either of
at your option.
octox is inspired byxv6-riscv.
I’m also grateful for the bug reports and discussion about the implementation contributed by Takahiro Itazuri and Kuniyuki Iwashima.
This is a learning project for me, and I will not be accepting pull requests until I consider the implementation complete. However, discussions and advice are welcome.
About
Unix-like OS in Rust inspired by xv6-riscv