Skip to content

Commit

Permalink
Merge pull request #82 from Alignof/develop
Browse files Browse the repository at this point in the history
Ver 1.2.0
  • Loading branch information
Alignof authored Feb 11, 2025
2 parents 7f488aa + 87b830d commit 68a9531
Show file tree
Hide file tree
Showing 59 changed files with 2,942 additions and 2,144 deletions.
27 changes: 19 additions & 8 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,37 @@ runner = """
qemu-system-riscv64
-cpu rv64,smstateen=true
-machine virt
-bios none
-bios default
-nographic
-m 2G
-initrd vmlinux_debug
-drive file=rootfs.ext2,format=raw,id=hd0,if=none
-device virtio-blk-pci,drive=hd0,iommu_platform=true,disable-legacy=on
-netdev user,id=n1
-device virtio-net-pci,netdev=n1,iommu_platform=true,disable-legacy=on
-append root=/dev/vda,rw,console=ttyS0
-device riscv-iommu-pci
-device ich9-ahci,id=ahci -device ide-hd,drive=hd0,bus=ahci.0
-kernel
"""

# With IOMMU
# runner = """
# qemu-system-riscv64
# -cpu rv64,smstateen=true
# -machine virt
# -bios default
# -nographic
# -m 2G
# -drive file=rootfs.ext2,format=raw,id=hd0,if=none
# -device virtio-blk-pci,drive=hd0,iommu_platform=true,disable-legacy=on
# -netdev user,id=n1
# -device virtio-net-pci,netdev=n1,iommu_platform=true,disable-legacy=on
# -append root=/dev/vda,rw,console=ttyS0
# -device riscv-iommu-pci
# -kernel
# """

# for debug
# runner = "../../qemu/build/qemu-system-riscv64 -S -gdb tcp::10000 -d int,in_asm,cpu_reset,mmu,page,guest_errors -machine virt -bios none -nographic -m 2G -initrd vmlinux_debug -drive file=rootfs.img,format=raw,id=hd0,if=none -device virtio-blk-pci,drive=hd0,iommu_platform=true,disable-legacy=on -append root=/dev/vda,rw,console=ttyS0 -device riscv-iommu-pci -kernel"
# memo: maintenance packet Qqemu.PhyMemMode:1

rustflags = [
"-C", "link-arg=-Tmemory.x",
"-C", "link-arg=-Tlink.x",
"-C", "target-feature=+h",
]

Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ jobs:
- name: install clippy
uses: dsherret/rust-toolchain-file@v1

- name: create dummy file
run: |
touch guest_image/vmlinux
touch guest_image/initrd
touch guest_image/guest.dtb
echo '#!/bin/sh' > dtc && chmod +x dtc && mv dtc /usr/local/bin/dtc
- uses: sksat/[email protected]
if: github.event_name == 'push'
with:
Expand Down
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Cargo.lock

# Added by me
.gdb_history
vmlinux
vmlinux_debug
*.dtb
vmlinux*
rootfs.*
initrd
16 changes: 9 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "hikami"
version = "1.1.1"
version = "1.2.0"
edition = "2021"

[lints.clippy]
Expand All @@ -13,19 +13,21 @@ missing_docs = "warn"
[lints.rustdoc]
missing_crate_level_docs = "warn"

[profile.release]
panic = 'abort'
codegen-units = 1

[features]
# for real device
embedded_host_dtb = []
# debug log
debug_log = []

[dependencies]
elf = { version = "0.7.2", default-features = false }
fdt = "0.1.5"
linked_list_allocator = "0.10.5"
raki = "1.2.0"
raki = "1.3.1"
riscv = "0.11.1"
riscv-rt = { git = "https://github.com/Alignof/riscv", branch = "fix/link_error_on_latest_rust" }
rustsbi = { version = "0.4.0", features = ["machine"] }
rustsbi = "0.4.0"
sbi-rt = "0.0.3"
sbi-spec = { version = "0.0.7", features = [ "legacy" ] }
sbi-spec = { version = "0.0.8", features = [ "legacy" ] }
spin = "0.9.8"
129 changes: 67 additions & 62 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,85 +1,90 @@
# hikami
[![Rust](https://github.com/Alignof/hikami/actions/workflows/rust.yml/badge.svg)](https://github.com/Alignof/hikami/actions/workflows/rust.yml)
Light weight type-1 hypervisor for RISC-V H-extension.
A lightweight Type-1 hypervisor for RISC-V H-extension, featuring **RISC-V extension emulation**.

This project aims not only to realize a lightweight hypervisor that can be used on RISC-V H extensions, but also to easily reproduce and manage the "extension" on the hypervisor. (currently in progress)
Poster in RISC-V Days Tokyo 2024 Summer: [PDF](https://riscv.or.jp/wp-content/uploads/RV-Days_Tokyo_2024_Summer_paper_9.pdf)
This project aims not only to realize a lightweight hypervisor that can be used on RISC-V H extensions, but also to easily reproduce and manage the "extension" on the hypervisor.
Poster in RISC-V Days Tokyo 2024 Summer: [PDF](https://riscv.or.jp/wp-content/uploads/RV-Days_Tokyo_2024_Summer_paper_9.pdf)
Paper in ComSys2024(ja): [link](https://ipsj.ixsq.nii.ac.jp/records/241051)

## Run Linux
### Build QEMU
We need to build manually the QEMU to support IOMMU.
## Related projects
- [ozora](https://github.com/Alignof/ozora): Generator for hypervisor(hikami) module and decoder (raki).
- [raki](https://github.com/Alignof/raki): RISC-V instruction decoder.
- [wild-screen-alloc](https://github.com/Alignof/wild-screen-alloc): Slab allocator for bare-metal Rust.

## Documents
```sh
$ git clone https://github.com/qemu/qemu.git -b staging
$ cd qemu/
# https://patchwork.ozlabs.org/project/qemu-devel/list/?series=417654
$ wget https://patchwork.ozlabs.org/series/417654/mbox/ --output-document riscv-QEMU-RISC-V-IOMMU-Support.patch
$ git apply riscv-QEMU-RISC-V-IOMMU-Support.patch
$ ./configure --target-list=riscv64-softmmu
$ make -j $(nproc)
# $ sudo make install
$ cargo doc --open
```
Ver. 9.2 or later should officially support IOMMU, so it should no longer be necessary to apply patches.

### Build Linux
## Getting Started
### Setup
```sh
$ git clone https://github.com/torvalds/linux -b v6.9

$ cd /path/to/this/repository
$ cp ./guest_image/.config /path/to/linux

$ cd /path/to/linux
$ make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- defconfig
$ make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- -j$(nproc)
$ mv vmlinux /path/to/this/repository
$ git clone https://github.com/buildroot/buildroot.git
$ cd buildroot/
$ make qemu_riscv64_virt_defconfig
$ make -j$(nproc)
$ ln -s output/images/rootfs.ext2 path/to/hikami/rootfs.ext2
$ ln -s output/build/linux-x.x.x/vmlinux path/to/hikami/guest_image/vmlinux
# optional
$ ln -s path/to/initrd path/to/hikami/guest_image/initrd

# copy host dts and edit to change user memory config
# QEMU's dtb can be obtained by adding the option `-machine dumpdtb=qemu.dtb`.
$ vim guest_image/guest.dts
```
See also for custom guest image: `guest_image/README.md`.

### Create rootfs
### Run on QEMU
```sh
$ git clone https://gitee.com/mirrors/busyboxsource.git
$ cd busyboxsource

# Select: Settings -> Build Options -> Build static binary
$ CROSS_COMPILE=riscv64-unknown-linux-gnu- make menuconfig

$ CROSS_COMPILE=riscv64-unknown-linux-gnu- make -j8
$ CROSS_COMPILE=riscv64-unknown-linux-gnu- make install

$ cd ../
$ qemu-img create rootfs.img 1g
$ mkfs.ext4 rootfs.img

$ mkdir rootfs
$ mount -o loop rootfs.img rootfs
$ cd rootfs
$ cp -r ../busyboxsource/_install/* .
$ mkdir proc dev tec etc/init.d

$ cd etc/init.d/
$ cat << EOS > rcS
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/sbin/mdev -s
EOS

$ chmod +x rcS
# The actual command to be executed is written in .cargo/config.toml.
$ cargo r
```

$ umount rootfs
$ mv rootfs.img /path/to/this/repository
### Run on FPGA
The target FPGAs are as the following. (boards supported by vivado-riscv repository)
```
- AMD VC707
- AMD KC705
- Digilent Genesys 2
- Digilent Nexys Video
- Digilent Nexys A7 100T
- Digilent Arty A7 100T
```

### Run
#### Building the FPGA environment
```sh
# The actual command to be executed is written in .cargo/config.toml.
$ cargo r
# set environment
$ git clone https://github.com/Alignof/vivado-risc-v -b feature/hikami
$ cd vivado-risc-v
$ make update-submodules

# Build FPGA bitstream
# Connect a micro-B cable to `PROG`
$ source /opt/Xilinx/Vivado/2024.2/settings64.sh
$ make CONFIG=rocket64b1 BOARD=nexys-video bitstream

# Prepare the SD card
$ ./mk-sd-card

# Program the FPGA flash memory
$ Xilinx/Vivado/2023.2/bin/hw_server
$ env HW_SERVER_URL=tcp:localhost:3121 xsdb -quiet board/jtag-freq.tcl
$ make CONFIG=rocket64b2 BOARD=nexys-video flash
```

## Documents
See also for an environment information: [https://github.com/Alignof/vivado-risc-v/blob/master/README.md](https://github.com/Alignof/vivado-risc-v/blob/master/README.md)

#### Boot
```sh
$ cargo doc --open
# Connect a micro-B cable to `UART`
$ sudo picocom -b 115200 /dev/ttyUSB2 # <- select the corresponding serial port

# login: debian
# password: debian
```

### Run on Milk-V Megrez
Coming soon...

## References
- [The RISC-V Instruction Set Manual: Volume I Version 20240411](https://github.com/riscv/riscv-isa-manual/releases/download/20240411/unpriv-isa-asciidoc.pdf)
- [The RISC-V Instruction Set Manual: Volume II Version 20240411](https://github.com/riscv/riscv-isa-manual/releases/download/20240411/priv-isa-asciidoc.pdf)
Expand Down
14 changes: 14 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,29 @@
use std::env;
use std::fs;
use std::path::PathBuf;
use std::process::Command;

/// Build script for cargo project
#[allow(clippy::similar_names)]
fn main() {
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());

let dts_file = "guest_image/guest.dts";
let dtb_file = "guest_image/guest.dtb";

let status = Command::new("dtc")
.args(["-I", "dts", "-O", "dtb", "-o", dtb_file, dts_file])
.status()
.expect("Failed to execute dtc");

assert!(status.success(), "dtc failed with exit status: {status}");

// Put the linker script somewhere the linker can find it.
fs::write(out_dir.join("memory.x"), include_bytes!("memory.x")).unwrap();
println!("cargo:rustc-link-search={}", out_dir.display());
println!("cargo:rerun-if-changed=memory.x");

println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed={dts_file}");
println!("cargo:rerun-if-changed={dtb_file}");
}
Binary file removed guest.dtb
Binary file not shown.
60 changes: 22 additions & 38 deletions guest_image/README.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,28 @@
# Build guest image
# Prepare guest image

## device tree
```sh
$ ./build_dtb.sh create
$ vim guest.dts # edit dts
$ ./build_dtb.sh build
# guest.dtb is created to repository root.
```
## Device tree
Place `guest.dts` to be given to the guest.
It should require a change in memory layout etc.
Build is done automatically by cargo build.

## Linux (with debug info)
```sh
$ git clone https://github.com/torvalds/linux -b v6.9
## Initrd
Place the symbolic link to the initrd.
It is automatically embedded in the binary.
Or copy directly to `.guest_initrd` section with a bootloader such as u-boot.

$ cd /path/to/this/repository
$ cp ./guest_image/.config /path/to/linux
## Linux
Place the symbolic link to the vmlinux.
It is automatically embedded in the binary.

$ cd /path/to/linux
$ make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- defconfig
$ make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- menuconfig
$ DEBUG_KERNEL [=y], DEBUG_INFO [=y], EFI [=n], RELOCATABLE [=n]
$ make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- -j$(nproc)
$ mv vmlinux /path/to/linux/vmlinx_debug
```

## Linux (For Zicfiss)
See [https://lwn.net/Articles/992578/](https://lwn.net/Articles/992578/).
## Example
```sh
# Toolchain
$ git clone [email protected]:sifive/riscv-gnu-toolchain.git -b cfi-dev
$ riscv-gnu-toolchain/configure --prefix=<path-to-where-to-build> --with-arch=rv64gc_zicfilp_zicfiss --enable-linux --disable-gdb --with-extra-multilib-test="rv64gc_zicfilp_zicfiss-lp64d:-static"
$ make -j$(nproc)

# Opensbi
$ git clone [email protected]:deepak0414/opensbi.git -b v6_cfi_spec_split_opensbi
$ make CROSS_COMPILE=<your riscv toolchain> -j$(nproc) PLATFORM=generic

# Linux
$ git clone https://github.com/torvalds/linux -b v6.12-rc1
$ wget https://patchwork.kernel.org/series/896898/mbox/ --output-document riscv-control-flow-integrity-for-usermode.patch
$ git am riscv-control-flow-integrity-for-usermode.patch
$ make ARCH=riscv CROSS_COMPILE=<path-to-cfi-riscv-gnu-toolchain>/build/bin/riscv64-unknown-linux-gnu- -j$(nproc) defconfig
$ make ARCH=riscv CROSS_COMPILE=<path-to-cfi-riscv-gnu-toolchain>/build/bin/riscv64-unknown-linux-gnu- -j$(nproc)
$ cd guest_image/
$ ls -l
total 28
-rw-r--r-- 1 takana takana 4262 Feb 4 17:01 fpga.dts
-rw-r--r-- 1 takana takana 4865 Feb 4 17:12 guest.dtb
-rw-r--r-- 1 takana takana 5834 Feb 4 17:01 guest.dts
lrwxrwxrwx 1 takana takana 41 Feb 4 17:09 initrd -> ../../vivado-risc-v/debian-riscv64/initrd
-rw-r--r-- 1 takana takana 453 Feb 4 17:27 README.md
lrwxrwxrwx 1 takana takana 40 Feb 4 17:09 vmlinux -> ../../vivado-risc-v/linux-stable/vmlinux
```
Loading

0 comments on commit 68a9531

Please sign in to comment.