Update RISC-V Qemu Virt GCC Readme + Makefile (#873)

Update Readme instructions  and add troubleshooting
tips for issues seen on Ubuntu and include a description
of where to find various crosstools-ng flags.
pull/875/head
Kody Stribrny 2 years ago committed by GitHub
parent dc2c031c45
commit d266eba137
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -14,16 +14,17 @@ CPPFLAGS = \
-I $(RTOS_SOURCE_DIR)/include \ -I $(RTOS_SOURCE_DIR)/include \
-I $(RTOS_SOURCE_DIR)/portable/GCC/RISC-V \ -I $(RTOS_SOURCE_DIR)/portable/GCC/RISC-V \
-I $(RTOS_SOURCE_DIR)/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions -I $(RTOS_SOURCE_DIR)/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions
CFLAGS = -march=rv32ima -mabi=ilp32 -mcmodel=medany \ CFLAGS = -march=rv32imac -mabi=ilp32 -mcmodel=medany \
-Wall \ -Wall \
-fmessage-length=0 \ -fmessage-length=0 \
-ffunction-sections \ -ffunction-sections \
-fdata-sections \ -fdata-sections \
-fno-builtin-printf -fno-builtin-printf
LDFLAGS = -nostartfiles -Tfake_rom.lds \ LDFLAGS = -nostartfiles -Tfake_rom.lds \
-march=rv32ima -mabi=ilp32 -mcmodel=medany \ -march=rv32imac -mabi=ilp32 -mcmodel=medany \
-Xlinker --gc-sections \ -Xlinker --gc-sections \
-Xlinker --defsym=__stack_size=300 -Xlinker --defsym=__stack_size=300 \
-Xlinker -Map=RTOSDemo.map
ifeq ($(DEBUG), 1) ifeq ($(DEBUG), 1)
CFLAGS += -Og -ggdb3 CFLAGS += -Og -ggdb3

@ -1,107 +1,154 @@
# Emulating generic RISC-V 32bit machine on QEMU
There is an updated version of this original submission from Katsuhiro Suzuki There is an updated version of this original submission from Katsuhiro Suzuki
in the FreeRTOS/Demo/RISC-V_RV32_QEMU_VIRT_GCC directory. in the FreeRTOS/Demo/RISC-V_RV32_QEMU_VIRT_GCC directory.
# Emulating generic RISC-V 32bit machine on QEMU ## Demo Summary
This demo prints Tx/Rx message of queue to serial port, using no
other hardware and usinh only the primary core (currently hart 0).
Other cores are simply going to wfi state and execute nothing else.
## Requirements ## Requirements
1. GNU RISC-V toolchains (tested on Crosstool-NG) 1. GNU RISC-V toolchains (tested on [SiFive](https://www.sifive.com/software) + [Crosstool-NG](https://github.com/crosstool-ng/crosstool-ng) toolchains)
1. qemu-riscv32-system (tested on Debian 10 package) 1. qemu-riscv32-system (tested on Debian 10 package)
1. Linux OS (tested on Debian 10) 1. Linux OS (tested on Debian 10/Ubuntu)
## How to build toolchain ## Prerequisites
### QEMU installation
This is OS specific. For Debian, some general instructions can be found [here](https://wiki.debian.org/RISC-V/32).
Clone the Crosstool-NG and build. ### RISC-V Toolchain Setup
You can download a RISC-V toolchain from SiFive at [this url](https://www.sifive.com/software). You'll need to extract this somewhere you'll remember as you need to add it to your PATH.
You can add the toolchain to you path with the following command
``` ```
$ git clone https://github.com/crosstool-ng/crosstool-ng export PATH=<your-toolchain-path>/<your-toolchain>/bin:$PATH
$ ./configure --enable-local
$ make
$ ./ct-ng menuconfig
``` ```
Change the following configs: For example, if you install the SiFive v2020.12.8 toolchain on an Ubuntu machine in your user home directory, it would be something like
``` ```
CT_EXPERIMENTAL=y export PATH=~/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14/bin:$PATH
CT_ARCH_RISCV=y
CT_ARCH_64=y
CT_ARCH_ARCH=rv32ima
CT_ARCH_ABI=ilp32
CT_MULTILIB=y
CT_DEBUG_GDB=y
``` ```
Build the GNU toolchain for RISC-V. ___________
## Building and Running the Demo
The demo is built using a makefile, so the command to build the demo is simply...
``` ```
$ ./ct-ng build make
``` ```
This file can become important if you want to change your RISC-V microarchitecture or Application Binary Interface (ABI).
A toolchain is installed at ~/x-tools/riscv64-unknown-elf directory. To run the demo in Qemu...
```
qemu-system-riscv32 -nographic -machine virt -net none \
## How to build -chardev stdio,id=con,mux=on -serial chardev:con \
-mon chardev=con,mode=readline -bios none \
-smp 4 -kernel ./build/RTOSDemo.axf
```
Add path of toolchain that is described above section. This command is quite lengthy but essentially spins up an emulated 32-bit RISC-V procressor without any display running the demo you just built as the kernel on 4 simulated cores. Textual output of this simulation will be directed to standard I/O.
## Building and Debugging the Demo
The debuggable demo is also built using a makefile, so the command to build the demo is simply...
``` ```
$ export PATH=~/x-tools/riscv64-unknown-elf:$PATH make DEBUG=1
``` ```
Notice the addition of the `DEBUG=1` parameter. This is what tells the makefile to include debugging information when building the demo.
For release build: To run the demo in Qemu...
``` ```
$ make qemu-system-riscv32 -nographic -machine virt -net none \
-chardev stdio,id=con,mux=on -serial chardev:con \
-mon chardev=con,mode=readline -bios none \
-smp 4 -kernel ./build/RTOSDemo.axf \
-s -S
``` ```
This command is nearly identical to the one above with the exception of the `-s` and `-S` flags. The `-s` flag attaches Qemu to port 1234 for GDB to connect to. The `-S` flag starts the simulation halted and waits for GDB to connect.
For debug build: At this point you'll need to attach GDB before the demo runs. To do so you'll need to run a RISC-V compatible GDB. This should be provided in the toolchain you've downloaded. The command to start GDB will be...
``` ```
$ make DEBUG=1 riscv64-unknown-elf-gdb build/RTOSDemo.axf
``` ```
Note - You'll need to run this command from the same directory as this readme.
If success to build, executable file RTOSDemo.axf in ./build directory. From here, there are three GDB commands you'll want to run
```
target remote localhost:1234
## How to run break main
``` continue
$ qemu-system-riscv32 -nographic -machine virt -net none \
-chardev stdio,id=con,mux=on -serial chardev:con \
-mon chardev=con,mode=readline -bios none \
-smp 4 -kernel ./build/RTOSDemo.axf
``` ```
The first attaches GDB to the port Qemu is running against. The second sets a breakpoint at the main function. The third runs the program until the breakpoint. You can run `continue` or `c` again to continue the program after the breakpoint.
## How to debug with gdb ## Building Your Own Toolchain
This section should be viewed as experimental. Take these steps as more of a starting off point than a dead set way to build a toolchain for your demo.
Append -s and -S options to the previous qemu command. ### CrossTools-NG
- -s: enable to attach gdb to QEMU at port 1234 Clone the Crosstool-NG and build.
- -S: start and halted CPU (wait for attach from gdb)
This is just recommend to use 'debug build' for more efficient debugging. ```
Run these commands after starting the QEMU with above options: $ git clone https://github.com/crosstool-ng/crosstool-ng
$ ./bootstrap
$ ./configure --enable-local
$ make
$ ./ct-ng menuconfig
``` ```
$ riscv64-unknown-elf-gdb build/RTOSDemo.axf
(gdb) target remote localhost:1234 The following configuration values need to be set:
(gdb) break main
Breakpoint 1 at 0x80000110 ```
CT_EXPERIMENTAL=y
CT_ARCH_RISCV=y
CT_ARCH_64=y
CT_ARCH_ARCH=rv32ima
CT_ARCH_ABI=ilp32
CT_MULTILIB=y
CT_DEBUG=y
```
These configurations can be found through the menuconfig though they are not immediately obvious. You will need to read the help page for each option to see what `CT_XXX` flag it corresponds to. For the flags above, the settings to edit are...
* CT_EXPIREMENTAL
* Paths and misc options -> Try features marked as EXPERIMENTAL
* CT_ARCH_RISCV
* Target options -> Target Architecture
* CT_ARCH_64
* Target options -> Bitness
* CT_ARCH_ARCH
* Target options -> Architecture level -> Enter "rv32ima"
* CT_ARCH_ABI
* Target options -> Generate code for the specific ABI -> Enter "ilp32"
* CT_MULTILIB
* Target options -> Build a multilib toolchain
* CT_DEBUG
* Debug facilities -> gdb
(gdb) c
Continuing.
Breakpoint 1, 0x80000110 in main () Build the GNU toolchain for RISC-V.
```
$ ./ct-ng build
``` ```
A toolchain is installed at ~/x-tools/riscv64-unknown-elf directory. You can now follow the 'Building and Running/Debugging" steps above
## Description ## Troubleshooting
### Your own toolchain Builds
### ZICSR Failures
If you receive the following while building
```
main.c: Assembler messages:
main.c:70: Error: unrecognized opcode `csrc mstatus,8', extension `zicsr' required
```
You'll need to swap the `-march` flag from `-march=rv32ima` to `-march=rv32ima_zicsr`
This demo just prints Tx/Rx message of queue to serial port, use no ### -pie not supported
other hardware and use only primary core (currently hart 0). If you receive this error while linking, add the `-no-pie` flag to your linker flags.
Other cores are simply going to wfi state and execute nothing else. See https://man.archlinux.org/man/community/riscv64-elf-binutils/riscv64-elf-ld.1.en#no~24 for more.

Loading…
Cancel
Save