Skip to content

RISC-V 64 Hypervisor (rCore on rCore) Userland #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "vmm"]
path = vmm
url = https://github.com/rcore-os/rcore-vmm.git
[submodule "rust-rvm-vmm"]
path = rust-rvm-vmm
url = https://github.com/rcore-riscv-hypervisor-dev/rust-rvm-vmm.git
31 changes: 28 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
# targets: build, pack
ARCH ?= riscv32
MODE ?= debug
export ARCH
export MODE
EN_RUST ?= y
EN_UCORE ?= y
EN_VMM ?= n
EN_RUST_RVM_VMM ?= n
ifneq ($(shell uname), Darwin)
EN_BISCUIT ?= y
EN_APP ?= y
Expand Down Expand Up @@ -57,7 +60,7 @@ else ifeq ($(MODE), debug)
cmake_build_args += -DCMAKE_BUILD_TYPE=Debug
endif

.PHONY: all clean build rust ucore biscuit app bin busybox nginx redis alpine iperf3 musl-gcc pre make libc-test vmm rust-rvm-vmm
.PHONY: all clean build rust ucore biscuit app bin busybox nginx redis alpine iperf3 musl-gcc pre make libc-test vmm rust-rvm-vmm rcore-guest

all: build

Expand Down Expand Up @@ -221,12 +224,34 @@ vmm: | vmm/*
ifeq ($(EN_VMM), y)
@echo Building rcore-vmm
@mkdir -p $(out_dir)/vmm
@cd vmm && make ARCH=$(ARCH)
@cd vmm && make build-$(ARCH) ARCH=$(ARCH)
@cp vmm/build/$(ARCH)/* $(out_dir)/vmm/
else
@echo rcore-vmm disabled
endif

# rust-rvm-vmm
rust-rvm-vmm: | rust-rvm-vmm/* rcore-guest
ifeq ($(EN_RUST_RVM_VMM), y)
@echo Building rust-rvm-vmm
@cd rust-rvm-vmm && cargo build $(rust_build_args) && make strip
@rm -rf $(out_dir)/rust-rvm-vmm && mkdir -p $(out_dir)/rust-rvm-vmm
@cp rust-rvm-vmm/target/$(ARCH)-rcore/$(MODE)/rust-rvm-vmm-strip $(out_dir)/rust-rvm-vmm/vmm
else
@echo rust-rvm-vmm disabled
endif

# prebuilt rCore guest image

rcore_guest_image := build/$(ARCH)/vmm/rcore
rcore-guest: $(rcore_guest_image)
$(rcore_guest_image):
ifeq ($(ARCH), riscv64)
@mkdir -p build/$(ARCH)/vmm
@wget "https://github.com/rcore-riscv-hypervisor-dev/rcore-guest-image-blob/blob/master/kernel.img?raw=true" -O $@
else
@echo rcore guest image not supported
endif
# prebuilt
prebuilt_version := 0.1.2
prebuilt_tar := build/$(ARCH)_v$(prebuilt_version).tar.gz
Expand All @@ -239,7 +264,7 @@ ifdef PREBUILT
build: $(prebuilt_tar)
@tar -xzf $< -C build
else
build: rcore-fs-fuse pre alpine rust ucore biscuit app busybox nginx redis iperf3 test musl-gcc make libc-test vmm
build: rcore-fs-fuse pre alpine rust ucore biscuit app busybox nginx redis iperf3 test musl-gcc make libc-test vmm rust-rvm-vmm rcore-guest
endif

sfsimg: $(out_qcow2)
Expand Down
84 changes: 70 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@

User programs for [rCore OS](https://github.com/rcore-os/rCore).

Now it has 6 parts:
Now it has 7 parts:

* `ucore`: C-lang, from the original [ucore_os_lab](https://github.com/chyyuu/ucore_os_plus)
* `biscuit`: C/C++, from [Biscuit](https://github.com/mit-pdos/biscuit), based on a `musl` instead of original `litc`.
* `rust`: Simple no_std Rust programs.
* `app`: C-lang, custom test programs based on `musl`.
* `nginx`, `redis`, `busybox`, `alpine`, `gcc`: Real world applications.
* `vmm`: Simple VMM (Virtual Machine Monitor) runs on top of [RVM](https://github.com/rcore-os/RVM), can run the unmodified [ucore_os_lab](https://github.com/chyyuu/os_kernel_lab/tree/master) as a guest OS.
* `rust-rvm-vmm`: VMM (Virtual Machine Monitor) runs on top of [RVM](https://github.com/rcore-os/RVM) written in Rust. Can run unmodified (except drivers) rCore as a guest OS.

## Build

Expand All @@ -45,19 +46,20 @@ A rootfs is created at `build/$(arch)` and converted to `qcow2`.

## Support matrix

| | x86_64 | aarch64 | riscv32 | riscv64 | mipsel |
| ------------------ | ------ | ------- | ------- | ------- | ------ |
| ucore | ✅ | ✅ | ✅ | ✅ | ❗ |
| rust | ✅ | ✅ | ✅ | ✅ | ✅ |
| biscuit | ✅ | ✅ | ✅ | ✅ | ✅ |
| app | ✅ | ✅ | ✅ | ✅ | ✅ |
| nginx (linux only) | ✅ | ✅ | ❗ | ✅ | ❗ |
| redis (linux only) | ✅ | ✅ | ✅ | ✅ | ✅ |
| busybox | ✅ | ✅ | ✅ | ✅ | ✅ |
| alpine rootfs | ✅ | ✅ | ❌ | ❌ | ❌ |
| iperf3 | ✅ | ❌ | ❌ | ❌ | ❌ |
| test | ✅ | ❌ | ❌ | ❌ | ❌ |
| vmm (linux only) | ✅ | ❌ | ❌ | ❌ | ❌ |
| | x86_64 | aarch64 | riscv32 | riscv64 | mipsel |
| --------------------------- | ------ | ------- | ------- | ------- | ------ |
| ucore | ✅ | ✅ | ✅ | ✅ | ❗ |
| rust | ✅ | ✅ | ✅ | ✅ | ✅ |
| biscuit | ✅ | ✅ | ✅ | ✅ | ✅ |
| app | ✅ | ✅ | ✅ | ✅ | ✅ |
| nginx (linux only) | ✅ | ✅ | ❗ | ✅ | ❗ |
| redis (linux only) | ✅ | ✅ | ✅ | ✅ | ✅ |
| busybox | ✅ | ✅ | ✅ | ✅ | ✅ |
| alpine rootfs | ✅ | ✅ | ❌ | ❌ | ❌ |
| iperf3 | ✅ | ❌ | ❌ | ❌ | ❌ |
| test | ✅ | ❌ | ❌ | ❌ | ❌ |
| vmm (linux only) | ✅ | ❌ | ❌ | ❌ | ❌ |
| rust-rvm-vmm (linux only) | ❌ | ❌ | ❌ | ✅ | ❌ |

Note: ❗ means workarounds are used so that they may not work properly. ❌ means failure in compiling or not existed on such platform.

Expand Down Expand Up @@ -228,3 +230,57 @@ vcpu_id = 1
```

Now uCore is booting and your can get uCore's shell soon.


### How to run rCore in rCore
Clone this repo recursively with [rust-rvm-vmm](https://github.com/rcore-riscv-hypervisor-dev/rust-rvm-vmm).

```bash
$ git clone https://github.com/rcore-os/rcore-user.git --recursive
```

Note: Currently guest rCore is provided as blob and will be downloaded while building sfsimg, but you can easily build your own guest rCore image using the flags mentioned in the [blob repo](https://github.com/rcore-riscv-hypervisor-dev/rcore-guest-image-blob).


Build with `EN_RUST_RVM_VMM=y`:

```bash
$ make sfsimg ARCH=riscv64 EN_RUST_RVM_VMM=y
```

Build and run [rCore](https://github.com/rcore-os/rCore) with `HYPERVISOR=on` and second uart `UART2=on`:

```bash
$ cd $(RCORE_ROOT)/kernel
$ make run mode=release ARCH=riscv64 HYPERVISOR=on UART2=on
```

Run the `vmm` app in rCore shell:

```
/ # cd rust-rvm-vmm
/rust-rvm-vmm # ./vmm
rust-rvm-vmm starting
starting

```


And connect to the secondary UART using `nc`:

```bash
$ nc -U /tmp/rcore_uart2
hello, vmm[vmm] Bad ecall eid=4739917 fid=0. Ignore.
[vmm] Bad ecall eid=4739917 fid=0. Ignore.
...
[vmm] Bad ecall eid=4739917 fid=0. Ignore.
/ # /busybox
/busybox
BusyBox v1.30.1 (2019-03-22 15:43:23 CST) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.
...
```

Now you can use rCore shell from the secondary UART.
Binary file added rcore
Binary file not shown.
1 change: 1 addition & 0 deletions rust-rvm-vmm
Submodule rust-rvm-vmm added at 5e51f2
37 changes: 37 additions & 0 deletions rust/src/bin/uart2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#![no_std]
#![no_main]

#[macro_use]
extern crate rcore_user;
use rcore_user::io::{putc, O_RDONLY};
use rcore_user::syscall::sys_open;
use rcore_user::syscall::sys_read;
use rcore_user::syscall::sys_write;
pub fn putc_uart2(fd: usize, c: u8) {
sys_write(fd, &c, 1);
}

pub fn getc_uart2(fd: usize) -> u8 {
let mut c = 0u8;
loop {
let len = sys_read(fd, &mut c, 1);
match len {
1 => return c,
0 => continue,
_ => panic!("read uart2 len = {}", len),
}
}
}
// IMPORTANT: Must define main() like this
#[no_mangle]
pub fn main() {
let fd = sys_open("/dev/ttyS1", O_RDONLY);
if (fd < 0) {
panic!("no /dev/ttyS1");
}
let fd = fd as usize;
println!("Start spinning.");
loop {
putc(getc_uart2(fd));
}
}