Introduction

Let’s create a root folder to hold the different elements of our build: the riscv toolchain, qemu and its images and the v8 sources. This folder will be called v8_root for the rest of the guide.

QEMU installation and setup


  • QEMU Installation:

Clone the repository and checkout to the version 5.0:

$ git clone git@github.com:qemu/qemu.git
$ cd qemu
$ git checkout v5.0.0

Install the prerequisites

$ sudo apt-get install libglib2.0-dev libpixman-1-dev

Configure and install QEMU:

$ ./configure --target-list=riscv64-softmmu && make -j 4 # j can be changed to match the number of cores on your machine
$ sudo make install  # optional

  • Images download:

Now that QEMU is installed, we need to download the Fedora images from the fedora project site. Each image needs its corresponding boot loader. U-Boot is an open-source multi-platform bootloader and can be found from the fedora project site as well.

$ cd v8_root
$ mkdir images && cd images

Note that two different versions are available: developer or minimal as well as a version number corresponding to the release date. Set the VER and TYPE accordingly:

$ export VER=20200108.n.0
$ export TYPE=MINIMAL
$ wget https://dl.fedoraproject.org/pub/alt/risc-v/repo/virt-builder-images/images/Fedora-${TYPE}-Rawhide-${VER}-sda.raw.xz
$ wget https://dl.fedoraproject.org/pub/alt/risc-v/repo/virt-builder-images/images/Fedora-${TYPE}-Rawhide-${VER}-fw_payload-uboot-qemu-virt-smode.elf
$ unxz -k Fedora-${TYPE}-Rawhide-${VER}-sda.raw.xz

  • QEMU launch:

Launching qemu with a given image boils down to this big command line:

$ qemu-system-riscv64 \
  -nographic \
  -machine virt \
  -smp 4 \
  -m 2G \
  -kernel Fedora-Developer-Rawhide-${VER}-fw_payload-uboot-qemu-virt-smode.elf \
  -object rng-random,filename=/dev/urandom,id=rng0 \
  -device virtio-rng-device,rng=rng0 \
  -device virtio-blk-device,drive=hd0 \
  -drive file=Fedora-Developer-Rawhide-${VER}-sda.raw,format=raw,id=hd0 \
  -device virtio-net-device,netdev=usernet \
  -netdev user,id=usernet,hostfwd=tcp::3333-:22

A launch script can be added to the image collection if you have to use several versions. A launch.sh file could look like:

# Quentin Ducasse, March 2022
#
# urls:
# https://wiki.qemu.org/Documentation/Platforms/RISCV
# https://picorio-doc.readthedocs.io/en/latest/software/v8.wiki/Cross-compiled-Build.html#run-qemu

# Arguments handling
if [ "$#" -ne 2 ]; then
  echo "Usage: $0 <version> <Developer|Minimal>" >&2
  exit 1
fi
version=$1
type=$2

qemu-system-riscv64 \
  -s \
  -nographic \
  -machine virt \
  -smp 4 \
  -m 2G \
  -kernel Fedora-${type}-Rawhide-${version}-fw_payload-uboot-qemu-virt-smode.elf \
  -bios none \
  -object rng-random,filename=/dev/urandom,id=rng0 \
  -device virtio-rng-device,rng=rng0 \
  -device virtio-blk-device,drive=hd0 \
  -drive file=Fedora-${type}-Rawhide-${version}-sda.raw,format=raw,id=hd0 \
  -device virtio-net-device,netdev=usernet \
  -netdev user,id=usernet,hostfwd=tcp::10000-:22

This script launches the image with for example:

$ ./launch.sh "20200108.n.0" "Minimal"  

  • QEMU runtime configuration:

Once the image boot is complete, it will ask for a login/password that are root/fedora_rocks!. Once logged in, we now need to check for two things: enable root login over ssh with password and check the glibc version (as this will guide our toolchain setup).

Setting up ssh:

(qemu) $ nano /etc/ssh/sshd_config # use whatever text editor to add the next line into the file
...
PermitRootLogin=yes
...
(qemu) $ systemctl restart sshd.service # restart the ssh server

We can now use ssh and scp to our image using the port we defined in the launch script! It is defined with hostfwd=tcp::10000-:22 which means that the port 10000 of the host machine (aka your machine) will be mapped to port 22 of our image (the default ssh port). An example of scp would be:

$ scp -r -P 10000 folder_to_transfer root@localhost:~  

Checking for glibc:

Run the command ldd --version to output the glibcversion of the image:

(qemu) $ ldd --version
ldd (GNU libc) 2.30.9000
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

In the case of the Fedora Minimal-20200108.n.0 image, it uses glibc 2.30.9000.

Note: To terminate the QEMU process pres Ctrl-A then X.

RISC-V compilation toolchain


The glibc version we got from the previous step will help us configure the riscv-compilation-toolchain.

$ cd v8_root
$ git clone https://github.com/riscv/riscv-gnu-toolchain
$ cd riscv-gnu-toolchain
$ git submodule update --init --recursive
$ cd riscv-glibc
$ git checkout glibc-2.30.9000 # set glibc version (git tag will display all tags to look into)

Going back into the toolchain repository, we can now configure and compile the toolchain:

$ ./configure --prefix=/opt/riscv-glibc-2.30.9000 # I'd encourage you to do that if you have multiple toolchains
$ sudo make linux -j8 # setting linux will compile the glibc version (otherwise newlib!), adjust j8 as you prefer

You will need to add the path of the toolchain to the global path with:

$ export PATH="/opt/riscv-glibc-2.30.9000/bin:$PATH"

Note: you might want to reiterate this export before building v8, this way (and by not adding it to bashrc) you can control which toolchain is used

V8 setup


  • depot_tools installation:

The V8 project uses Google’s depot_tools to meta-manage git and the source code. Instructions are presented in the V8 dev site but boils down to: depot_tools installation and repository sync.

$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
$ export PATH=$PATH:/path/to/depot_tools # or add to your bashrc to keep it in the path
$ gclient
Usage: gclient.py <command> [options]

Meta checkout dependency manager for Git.

Commands are:
  config   creates a .gclient file in the current directory
  diff     displays local diff for every dependencies
  fetch    fetches upstream commits for all modules
...

  • Get the sources:

Getting the official V8 sources boils down to:

$ cd v8_root
$ fetch v8

To add the RISC-V branch (as it is not upstream):

$ git remote add riscv git@github.com:riscv/v8.git
$ git fetch riscv
$ git checkout riscv64
$ gclient sync --with_branch_heads --with_tags # gclient will look for depedencies itself

  • Configure build:

Build dependencies are installed with the script build/build-deps.sh. We will need to change a line of the build/toolchain/linux/BUILD.gn file to make it compliant with our toolchain. It presents the gcc RISC-V toolchain in:

gcc_toolchain("riscv64") {
  toolprefix = "riscv64-linux-gnu"
  ...

However, our toolchain uses the riscv64-unknown-linux-gnu prefix. You can double check this and use yours by doing:

$ ls /opt/riscv-glibc-2.30.9000
bin/  include/  lib/  libexec/  riscv64-unknown-linux-gnu/  share/  sysroot/
$ ls /opt/riscv-glibc-2.30.9000/bin
riscv64-unknown-linux-gnu-addr2line  riscv64-unknown-linux-gnu-g++        riscv64-unknown-linux-gnu-gcov-dump         
riscv64-unknown-linux-gnu-ld.bfd     riscv64-unknown-linux-gnu-run        riscv64-unknown-linux-gnu-ar
riscv64-unknown-linux-gnu-gcc        riscv64-unknown-linux-gnu-gcov-tool  riscv64-unknown-linux-gnu-lto-dump  
riscv64-unknown-linux-gnu-size       riscv64-unknown-linux-gnu-as         riscv64-unknown-linux-gnu-gcc-11.1.0    
riscv64-unknown-linux-gnu-gdb        riscv64-unknown-linux-gnu-nm         ...

We can replace the line in the toolchain with:

sed -i 's/riscv64-linux-gnu/riscv64-unknown-linux-gnu/g' build/toolchain/linux/BUILD.gn

  • Build V8:

We can now build V8 with:

$ gn gen out/riscv64.native.debug --args='is_component_build=false is_debug=true target_cpu="riscv64" v8_target_cpu="riscv64" use_goma=false goma_dir="None" treat_warnings_as_errors=false'
$ ninja -C out/riscv64.native.debug -j8 # tune j as needed

IF THE BUILD FAILS WITH #error Please add support for your architecture in build/build_config.h, we need to generate d8 only with:

$ cd out/riscv64.native.debug
$ gn gen .
$ ninja d8 -j8 # tune j as needed