Skip to content

Cptraser/chenlongos

ArceOS

CI CI Docs

An experimental modular operating system (or unikernel) written in Rust.

ArceOS was inspired a lot by Unikraft.

🚧 Working In Progress.

Features & TODOs

  • Architecture: x86_64, riscv64, aarch64
  • Platform: QEMU pc-q35 (x86_64), virt (riscv64/aarch64)
  • Multi-thread
  • FIFO/RR/CFS scheduler
  • VirtIO net/blk/gpu drivers
  • TCP/UDP net stack using smoltcp
  • Synchronization/Mutex
  • SMP scheduling with single run queue
  • File system
  • Compatible with Linux apps
  • Interrupt driven device I/O
  • Async I/O

Example apps

Example applications can be found in the apps/ directory. All applications must at least depend on the following modules, while other modules are optional:

  • axruntime: Bootstrapping from the bare-metal environment, and initialization.
  • axhal: Hardware abstraction layer, provides unified APIs for cross-platform.
  • axconfig: Platform constants and kernel parameters, such as physical memory base, kernel load addresses, stack size, etc.
  • axlog: Multi-level formatted logging.

The currently supported applications (Rust), as well as their dependent modules and features, are shown in the following table:

App Extra modules Enabled features Description
helloworld A minimal app that just prints a string
exception paging Exception handling test
memtest axalloc alloc, paging Dynamic memory allocation test
display axalloc, axdisplay alloc, paging, display Graphic/GUI test
yield axalloc, axtask alloc, paging, multitask, sched_fifo Multi-threaded yielding test
parallel axalloc, axtask alloc, paging, multitask, sched_fifo Parallel computing test (to test synchronization & mutex)
sleep axalloc, axtask alloc, paging, multitask, sched_fifo Thread sleeping test
shell axalloc, axdriver, axfs alloc, paging, fs A simple shell that responds to filesystem operations
httpclient axalloc, axdriver, axnet alloc, paging, net A simple client that sends an HTTP request and then prints the response
echoserver axalloc, axdriver, axnet, axtask alloc, paging, net, multitask A multi-threaded TCP server that reverses messages sent by the client
httpserver axalloc, axdriver, axnet, axtask alloc, paging, net, multitask A multi-threaded HTTP server that serves a static web page

Build & Run

Install build dependencies

Install cargo-binutils to use rust-objcopy and rust-objdump tools:

cargo install cargo-binutils

for build&run C apps

Install libclang-dev:

sudo apt install libclang-dev

Download&Install cross-musl-based toolchains:

# download
wget https://musl.cc/aarch64-linux-musl-cross.tgz
wget https://musl.cc/riscv64-linux-musl-cross.tgz
wget https://musl.cc/x86_64-linux-musl-cross.tgz
# install
tar zxf aarch64-linux-musl-cross.tgz
tar zxf riscv64-linux-musl-cross.tgz
tar zxf x86_64-linux-musl-cross.tgz
# exec below command in bash OR add below info in ~/.bashrc
export PATH=`pwd`/x86_64-linux-musl-cross/bin:`pwd`/aarch64-linux-musl-cross/bin:`pwd`/riscv64-linux-musl-cross/bin:$PATH

Example apps

# in arceos directory
make A=path/to/app ARCH=<arch> LOG=<log>

Where <arch> should be one of riscv64, aarch64,x86_64.

<log> should be one of off, error, warn, info, debug, trace.

path/to/app is the relative path to the example application.

More arguments and targets can be found in Makefile.

For example, to run the httpserver on qemu-system-aarch64 with 4 cores:

make A=apps/net/httpserver ARCH=aarch64 LOG=info SMP=4 run NET=y

Note that the NET=y argument is required to enable the network device in QEMU. These arguments (BLK, GRAPHIC, etc.) only take effect at runtime not build time.

Your custom apps

Rust

  1. Create a new rust package with no_std and no_main environment.

  2. Add axstd dependency and features to enable to Cargo.toml:

    [dependencies]
    axstd = { path = "/path/to/arceos/ulib/axstd", features = ["..."] }
  3. Call library functions from axstd in your code, just like the Rust std library.

  4. Build your application with ArceOS, by running the make command in the application directory:

    # in app directory
    make -C /path/to/arceos A=$(pwd) ARCH=<arch> run
    # more args: LOG=<log> SMP=<smp> NET=[y|n] ...

    All arguments and targets are the same as above.

C

  1. Create axbuild.mk and features.txt in your project:

    app/
    β”œβ”€β”€ foo.c
    β”œβ”€β”€ bar.c
    β”œβ”€β”€ axbuild.mk      # optional, if there is only one `main.c`
    └── features.txt    # optional, if only use default features
  2. Add build targets to axbuild.mk, add features to enable to features.txt (see this example):

    # in axbuild.mk
    app-objs := foo.o bar.o
    # in features.txt
    alloc
    paging
    net
  3. Build your application with ArceOS, by running the make command in the application directory:

    # in app directory
    make -C /path/to/arceos A=$(pwd) ARCH=<arch> run
    # more args: LOG=<log> SMP=<smp> NET=[y|n] ...

How to build ArceOS for specific platforms and devices

Set the PLATFORM variable when run make:

# Build helloworld for raspi4
make PLATFORM=aarch64-raspi4 A=apps/helloworld

You may also need to select the corrsponding device drivers by setting the FEATURES variable:

# Build the shell app for raspi4, and use the SD card driver
make PLATFORM=aarch64-raspi4 A=apps/fs/shell FEATURES=driver-bcm2835-sdhci
# Build Redis for the bare-metal x86_64 platform, and use the ixgbe and ramdisk driver
make PLATFORM=x86_64-pc-oslab A=apps/c/redis FEATURES=driver-ixgbe,driver-ramdisk SMP=4

Design