xv6-riscv for HiFive Unmatched
This is a port of xv6-riscv to the SiFive HiFive Unmatched board (FU740). See notes for the implementation details.
Highlights
- Stability on actual hardware:
usertestspassed, resolving hardware-specific issues. - Direct M-mode boot via U-Boot SPL: Replaced the standard OpenSBI with xv6 kernel, leveraging SPL for hardware initialization and minimizing kernel modifications.
- SD card driver: Ported the SPI mode SD card driver (from SiFive sources) to replace VirtIO.
Status
- Boot setup
- UART output
- SD card driver
- Pass
usertests - Validate via 6.1810 labs (local validation only; solutions will not …
xv6-riscv for HiFive Unmatched
This is a port of xv6-riscv to the SiFive HiFive Unmatched board (FU740). See notes for the implementation details.
Highlights
- Stability on actual hardware:
usertestspassed, resolving hardware-specific issues. - Direct M-mode boot via U-Boot SPL: Replaced the standard OpenSBI with xv6 kernel, leveraging SPL for hardware initialization and minimizing kernel modifications.
- SD card driver: Ported the SPI mode SD card driver (from SiFive sources) to replace VirtIO.
Status
- Boot setup
- UART output
- SD card driver
- Pass
usertests - Validate via 6.1810 labs (local validation only; solutions will not be published)
Running on HiFive Unmatched
Prerequisites
Host environment: Ubuntu 24.04
Install the required packages:
sudo apt update
sudo apt install git build-essential gdb-multiarch qemu-system-misc \
gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu
sudo apt install flex bison libssl-dev python3-setuptools python3-dev \
swig device-tree-compiler u-boot-tools
Building
- Build xv6 kernel
Compile the xv6 kernel for the Unmatched target:
git clone https://github.com/eyengin/xv6-riscv-unmatched
cd xv6-riscv-unmatched
make unmatched
The unmatched target automatically converts the kernel ELF to a raw binary and packages it into a FIT image (xv6-unmatched.itb) using mkimage. This image includes the necessary metadata for U-Boot SPL to recognize it as a bootable firmware.
- Build U-Boot SPL
This port uses U-Boot SPL to load the xv6 kernel directly (replacing OpenSBI in the standard flow).
Clone and build v2023.01 (Note: newer versions failed to initialize CPU clocks correctly in the SPL phase):
git clone https://github.com/u-boot/u-boot.git
cd u-boot
git checkout v2023.01
make sifive_unmatched_defconfig
# Build SPL (only u-boot-spl.bin is needed for this project)
make CROSS_COMPILE=riscv64-linux-gnu- spl/u-boot-spl.bin
SD card setup
Prepare a microSD card (SDHC; tested with SanDisk Ultra 32GB UHS-I A1).
Warning: Replace /dev/sdX with your actual SD card device. Double-check the device name to avoid overwriting the wrong disk.
Use sgdisk to partition the SD card:
sudo sgdisk -g --clear -a 1 \
--new=1:34:2081 --change-name=1:spl --typecode=1:5B193300-FC78-40CD-8002-E86C45580B47 \
--new=2:2082:10273 --change-name=2:xv6 --typecode=2:2E54B353-1271-4842-806F-E436D6AF6985 \
--new=3:16384:+128M --change-name=3:root --typecode=3:0x0700 \
/dev/sdX
Write the generated images to the SD card partitions:
sudo dd if=<U-Boot-dir>/spl/u-boot-spl.bin of=/dev/sdX1 bs=1M
sudo dd if=<xv6-riscv-dir>/xv6-unmatched.itb of=/dev/sdX2 bs=1M
sudo dd if=<xv6-riscv-dir>/fs.img of=/dev/sdX3 bs=1M
Booting
Insert the microSD card into the HiFive Unmatched. 1.
Ensure the Boot Mode Select (MSEL) switches are set to SD Boot (1011). 1.
Connect via UART (Baud rate: 115200). 1.
Power on the board. You should see the following output:
U-Boot SPL 2023.01 (Jan 07 2026 - 23:26:31 +0900)
Trying to boot from MMC1
xv6 kernel is booting
hart 2 starting
hart 4 starting
hart 3 starting
init: starting sh
$
Running on QEMU sifive_u
You can also run the kernel on QEMU using the sifive_u machine. Make sure to clean the build artifacts when switching between the Unmatched board and QEMU targets.
make clean
make qemu