-
Notifications
You must be signed in to change notification settings - Fork 138
RISC V binutils
RISC-V binutils must be build manually, so first you'll need to get sources.
The source files are stored in GitHub repository in the RISC-V's riscv-gnu-toolchain project. Use git to get a local clone of the repository (--recursive
option is required to get all submodules):
git clone --recursive https://github.com/riscv/riscv-gnu-toolchain
In case if submodules were not initialized automatically (their folders contain only .git
file), set them manually from the project root:
cd riscv-gnu-toolchain
git submodule foreach 'git reset --hard'
You can face problem with cloning "qemu" submodule. It is not required for the most of our usage cases, thus this can be ignored.
This cheat-sheet is based on GitHub README. See it if you have any problem or need more information.
# Install prerequisites
sudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential \
bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev
# For convenience, you can proceed the build from project root
cd riscv-gnu-toolchain
# Create a directory where the binutils will be installed (can be any)
mkdir bin
# Create a directory for a build process (can be any), enter it
mkdir build && cd build
# Configure build (configures for RV64GC by default) using script from the project root.
# Set absolute path of destination binutils directory ("bin") for "prefix" flag
../configure --prefix=/riscv-gnu-toolchain/bin
# Make sources (can dump a lot of info). Paralleling can be archieved by specifying "-j NUMBER_OF_WORKERS" flag.
# Note: environment variables $CXX ($CC) should point to compiler supporting at least C++11 by default.
make
# Install (can dump a lot of info, usually requires sudo)
sudo make install
# Update $PATH variable to have binaries available
export PATH=$PATH:/riscv-gnu-toolchain/bin/bin
setenv PATH $PATH:/riscv-gnu-toolchain/bin/bin
- Create a file with assembler code and save it as
<test_name>.s
.
The simplest example of the program (a single NOP):
.section .text
.globl _start
_start:
addi x0, x0, 0
For further steps, you can look into RISC-V Assembly Programmer's Manual.
- Generate an object file:
riscv64-unknown-elf-as <test_name>.s -o <test_name>.o
- Convert the object file into the binary file:
riscv64-unknown-elf-ld <test_name>.o -o <test_name>.out
- (Optional) Look the content of
<test_name>.out
using (pay attention only to.text
section):
riscv64-unknown-elf-objdump -D <test_name>.out
Note that in addition to assembler this RISC-V GNU toolchain also includes C and C++ cross-compiler, so you can also build C/C++ code into a RISC-V binary on regular x86 machines.
.section .rodata # Read-only data
##############################################################################
# This section includes read-only memory data. Big constants could be added
# here. Below is a Word (32b) with "0xdeadbeef" value, addressed as
# "example_data":
##############################################################################
example_data:
.word 0xDEADBEEF
.section .text # Instructions
.globl _start
##############################################################################
# Parameters (something like C/C++ "#define") but for small immediate values
# only:
##############################################################################
.equ PARAMETER, 2
_start:
##############################################################################
# Main code section.
##############################################################################
lw t0, example_data # t0 = mem[example_data] (t0 = 0xdeadbeef)
addi t1, zero, PARAMETER # t1 = zero + PARAMETER (t1 = 0 + 2 = 2)
loop:
add t1, t1, t0
j loop
MIPT-V / MIPT-MIPS — Cycle-accurate pre-silicon simulation.