This sample project demonstrates how to run a Rust code on bare-metal RISC-V code of the Cvitek/Sophgo MilkV DuoS SBC. The RISC-V cores of this hardware are: C906@1GHz + C906@700MHz.
My adventure with this hardware (and with RISC-V in general) began when I ported my aa-proxy project to the DuoS. The aa-proxy runs on the main RISC-V core, and there was a FreeRTOS instance running on the secondary core. I realized that since I wasn't actually using FreeRTOS, I could repurpose the second core for tinkering with something custom written in Rust.
At the time of writing this README I was unable to find any working example that could be compiled and run on this core. The only clue I found was this Reddit post:
https://www.reddit.com/r/RISCV/comments/1itvhxj/how_to_boot_up_a_custom_os_on_milkv_duo/
I contacted the author, but he told me he no longer had the code since he hadn't uploaded it to GitHub...
So with this repository, I'm filling that gap ;)
Fortunately, after some more searching I came across a blog post by longxiangam:
https://blog.csdn.net/longxiangam/article/details/144477962
The initial commit of this repo is based on that work.
However, his setup targeted the original Duo, and the Rust code was running on the main core only. I had to adjust the base address in order to run the code on the secondary RISC-V core instead of FreeRTOS.
This repository has a main branch that prints "hello world" to UART, and a led_blink branch that blinks the blue LED on the DuoS.
This repo is intended for cross-compiling to a RISC-V target. First, add the target:
rustup target add riscv64gc-unknown-none-elf
cargo build --releaseNext, use the riscv64-unknown-elf-objcopy tool from the MilkV host-tools repo, like this:
riscv64-unknown-elf-objcopy target/riscv64gc-unknown-none-elf/release/longxiangam_example -O binary target/riscv64gc-unknown-none-elf/release/longxiangam_example.binThe final .bin file is what you pass as the BLCP_2ND_PATH= parameter to the FIP builder. After generating a new fip.bin with this binary, you can simply place it on the SD card (replacing the original one) and the Rust bare-metal test application will start at boot :)
I'm using the aa-proxy buildroot infrastructure, so in my case the command inside the container looks like this:
export PATH=/app/host-tools/gcc/riscv64-linux-musl-x86_64/bin:$PATH
ARCH=riscv CHIP_ARCH=CV181X CROSS_COMPILE_GLIBC_RISCV64=riscv64-unknown-linux-musl- DDR_CFG=ddr3_1866_x16 LOG_LEVEL=2 BLCP_2ND_PATH=/app/longxiangam_example.bin LOADER_2ND_PATH=../../images/u-boot.bin make -j$(nproc --all) -C /app/buildroot/output/milkv-duos/build/fsbl O=/app/buildroot/output/milkv-duos/build/fsbl/build