This OS is for the RISCV processor on the SiFive "HiFive1 Rev B", which has the "Freedom E310" processor implementing RV32IMAC
ISA
From https://www.sifive.com/boards/hifive1-rev-b and https://www.sifive.com/chip-designer#fe310
NOTE: I did not end up using the following setup for the currently existing state of the project!
git clone --recursive https://github.com/sifive/freedom-e-sdk.git
- Download "GNU Embedded Toolchain — v2020.12.8" and "OpenOCD — v2020.12.1" from https://www.sifive.com/software
- Unzip in a known directory
export RISCV_OPENOCD_PATH=</path/to/OpenOCD>
in freedom-e-sdk directoryexport RISCV_PATH=</path/to/toolchain>
in freedom-e-sdk
Setup RISC-V qemu (https://risc-v-getting-started-guide.readthedocs.io/en/latest/linux-qemu.html)
mkdir riscv64-linux
cd riscv64-linux
git clone https://github.com/qemu/qemu
cd qemu
git checkout v5.0.0
./configure --target-list=riscv64-softmmu
make -j 4
sudo make install
./configure --target-list=riscv32-softmmu
make -j 4
sudo make install
-
Download and unzip RISC-V GNU Toolchain
Set environment variable for
RISCV_PATH
to unzipped directlyls $RISCV_PATH/bin
should show many gnu tool executables targeted for RISC-V -
Download and install the latest version of the SEGGER JLink tool (bottom of the page).
This is what we will use to connect to the hifive board
From http://osblog.stephenmarz.com/ch0.html
rustup override set nightly
in directoryrustup target add riscv32imac-unknown-none-elf
- Trying (from https://github.com/riscv-rust/riscv-rust-quickstart):
cargo install cargo-generate
cargo generate --git https://github.com/riscv-rust/riscv-rust-quickstart
A note,
qemu-system-riscv32 -nographic -machine sifive_e -kernel path/to/program.elf
Using the quickstart above, we have generated this current project layout.
I modified the .cargo/config to run emulation on hifive revb board.
I downloaded and installed QEMU 6.0.0 from source from https://www.qemu.org/download/#source. This contains the specific hifive board that this project is currently targeted at. Once qemu 6.0.0 is in your path, you can emulate code using:
qemu-system-riscv32 -nographic -machine sifive_e,revb=true -m 128M -drive if=none,format=raw,file=hdd.dsk,id=foo -serial 'mon:stdio' -bios none -kernel path/to/code
This is what is setup in the cargo config currently, so when cargo run
is invoked, this qemu emulation is used.
Follow the instructions in the Hifive1 "Getting Started" to setup the board.
-
Plugging in the board with a USB to a computer will power on the device, with the preloaded bootloader and sifive welcome program. The host computer should recognize that a USB device was just plugged in.
Additionally, with
ls -l /dev/tty*
you should see at least two tty devices named/dev/ttyACM0
(with some suffix integer value) -
Follow the instructions on page 14 of the the above "Getting Started" guide to modify the jlink udev rules adding the "plugdev" group.
-
Add your user to the plugdev group:
sudo usermod -a -G plugdev <user_name>
This will add your user to the "plugdev" group, giving you non-sudo access to the hifive tty which is how you can view and interact with device in a terminal emulator.
-
Use terminal emulator like GNU Screen (suggested from the "Getting Started" guide) to interface with the hifive1 board:
sudo screen /dev/ttyACM0 115200
Resetting the device at this point should show the built-in SiFive Welcome program.
Generate with fallocate -x -l 32M hdd.dsk
Apparently the way I configured and built my qemu 6.0.0 may not be as full featured as what is presented in the blog. When I added the various -device
options that are present in his blog in chapter 0, qemu could not find the devices properly giving:
No 'virtio-bus' bus found for device 'virtio-keyboard-device'
And etc. So I removed them for now at least so the src/main.rs or the hello_world examples will compile and run.
- https://github.com/tock/tock/blob/master/boards/hifive1/README.md
- https://github.com/sifive/freedom-e-sdk.git
- http://osblog.stephenmarz.com/ch0.html
- https://github.com/riscv-rust/riscv-rust-quickstart
cargo run
or
cargo run --example hello_world
Press CTRL-A
, x
to break out of the qemu emulation.
By default code is run in the qemu emulator.
Programs are uploaded using the scripts/upload
bash script. It takes a parameter for the program with --hex <path>
and the name of the JLink executable used to connect to the board with --jlink JLinkExe
(JLinkExe should be in your path from step 2 of Prerequisites above).
The board requires hex versions of executables rather than direct elf executables. We perform this conversion with the $RISCV_PATH/bin/riscv64-unknown-elf-objcopy
tool, and this is made easier in the Makefile .hex
target. This hex file is what is ultimately uploaded into the device.
Ensure all prerequisites are done in order to upload programs to the board The environment variable
RISCV_PATH
should be set in the environmnet (see Prerequisites above)
To build and upload main
to the board, use the provided makefile:
make build upload
There are a few examples that can be emulated with:
cargo run --example <example name>
But to run these on the board required a couple steps. In the following steps we will use the color_type
example program:
cargo build --example color_type
make target/riscv32imac-unknown-none-elf/debug/examples/color_type.hex
./scripts/upload --hex target/riscv32imac-unknown-none-elf/debug/examples/color_type.hex --jlink JLinkExe