quan m. nguyen


This document is out-of-date, no longer authoritative, and only here for historical purposes. Please consult riscv.org for the most recent installation instructions.

The RISC-V GCC/Newlib Toolchain Installation Manual

January 2, 2014


The purpose of this page is to document a procedure through which an interested user can build the RISC-V GCC/Newlib toolchain.

A project with a duration such as this requires adequate documentation to support future development and maintenance. This document is created with the hope of being useful; however, its accuracy is not guaranteed.

Table of Contents

  1. Introduction
  2. Table of Contents
  3. Copyright Information
  4. Meta-installation Notes
  5. Installing the Toolchain
  6. Testing Your Toolchain
  7. "Help! It doesn't work!"

Copyright Information

This document is currently under development. This document is copyrighted by Quan Nguyen, © 2014. All rights reserved. I do intend, however, to release this document to the public freely upon its satisfactory completion.

This work was completed at Andrew and Yunsup's request.

Meta-installation Notes

You may notice this document strikes you as similar to its bigger sibling, the Linux/RISC-V Installation Manual. That's because the instructions are rather similar. That said...

Running Shell Commands

Instructive text will appear as this paragraph does. Any instruction to execute in your terminal will look like this:

$ echo "execute this"

Optional shell commands that may be required for your particular system will be backed by a blue background, and marked "Optional":

Optional $ echo "call this, maybe"

If you will need to replace a bit of code that applies specifically to your situation, it will be surrounded by [square brackets].

The Standard Build Unit

To instruct how long it will take someone to build the various components of the packages on this page, I have provided build times in terms of the Standard Build Unit (SBU), as coined by Gerard Beekmans in his immensely useful Linux From Scratch website.

On an Intel Xeon Dual Quad-core server with 48 GiB RAM, I achieved the following build time for binutils: 38.64 seconds. Thus, 38.64 seconds = 1 SBU. (EECS members at the University of California, Berkeley: I used the s141.millennium server.)

As a point of reference, my 2007 MacBook with an Intel Core 2 Duo and 1 GiB RAM has 100.1 seconds to each SBU. Building riscv-linux-gcc, unsurprisingly, took about an hour.

Items marked as "optional" are not measured.

Having Superuser Permissions

You will need root privileges to install the tools to directories like /usr/bin, but you may optionally specify a different installation directory. Otherwise, superuser privileges are not necessary.

Installing the Toolchain

Let's start with the directory in which we will install our tools. Find a nice, big expanse of hard drive space, and let's call that $TOP. Change to the directory you want to install in, and then set the $TOP environment variable accordingly:

$ export TOP=$(pwd)

For the sake of example, my $TOP directory is on s141.millennium, at /scratch/quannguyen/noob, named so because I believe even a newbie at the command prompt should be able to complete this tutorial. Here's to you, n00bs!

Tour of the Sources

If we are starting from a relatively fresh install of GNU/Linux, it will be necessary to install the RISC-V toolchain. The toolchain consists of the following components:

In the installation guide for Linux builds, we built only the simulator and the front-end server. Binaries built against Newlib with riscv-gcc will not have the luxury of being run on a full-blown operating system, but they will still demand to have access to some crucial system calls.

What's Newlib?

Newlib is a "C library intended for use on embedded systems." It has the advantage of not having so much cruft as Glibc at the obvious cost of incomplete support (and idiosyncratic behavior) in the fringes. The porting process is much less complex than that of Glibc because you only have to fill in a few stubs of glue code.

These stubs of code include the system calls that are supposed to call into the operating system you're running on. Because there's no operating system proper, the simulator runs, on top of it, a proxy kernel (riscv-pk) to handle many system calls, like open, close, and printf.

Obtaining and Compiling the Sources (7.87 SBU)

First, clone the tools from the ucb-bar GitHub repository:

$ git clone git@github.com:ucb-bar/riscv-tools.git

This command will bring in only references to the repositories that we will need. We rely on Git's submodule system to take care of resolving the references. Enter the newly-created riscv-tools directory and instruct Git to update its submodules. If you want to use ssh-add to prevent yourself from typing in your private key password many times, do so now by running

Optional $ exec ssh-agent /bin/bash
$ ssh-add ~/.ssh/id_rsa

Then, cd into the directory and then initialize and update the submodules.

$ cd $TOP/riscv-tools
$ git submodule update --init

To build GCC, we will need several other packages, including flex, bison, autotools, libmpc, libmpfr, and libgmp. Ubuntu distribution installations will require this command to be run. If you have not installed these things yet, then run this:

Optional $ sudo apt-get install autoconf automake autotools-dev libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf

Before we start installation, we need to set the $RISCV environment variable. The variable is used throughout the build script process to identify where to install the new tools. (This value is used as the argument to the --prefix configuration switch.)

$ export RISCV=$TOP/riscv

If your $PATH variable does not contain the directory specified by $RISCV, add it to the $PATH environment variable now:

$ export PATH=$PATH:$RISCV/bin

One more thing: If your machine doesn't have the capacity to handle 16 make jobs (or conversely, it can handle more), edit build.common to change the number specified by JOBS.

Optional $ sed -i 's/JOBS=16/JOBS=[number]/' build.common

With everything else set up, run the build script.


Testing Your Toolchain

Now that you have a toolchain, it'd be a good idea to test it on the quintessential "Hello world!" program. Exit the riscv-tools directory and write your "Hello world!" program. I'll use a long-winded echo command.

$ cd $TOP
$ echo -e '#include <stdio.h>\n int main(void) { printf("Hello world!\\n"); return 0; }' > hello.c

Then, build your program with riscv-gcc.

$ riscv-gcc -o hello hello.c

When you're done, you may think to do ./hello, but not so fast. We can't even run spike hello, because our "Hello world!" program involves a system call, which couldn't be handled by our host x86 system. We'll have to run the program within the proxy kernel, which itself is run by spike, the RISC-V architectural simulator. Run this command to run your "Hello world!" program:

$ spike $RISCV/target/bin/pk hello

The RISC-V architectural simulator, spike, takes as its argument the path of the binary to run. We explicitly (not using $PATH) specify the location of riscv-pk in the installation directory (in our case, $RISCV). Then, riscv-pk receives as its argument the name of the program you want to run.

Hopefully, if all's gone well, you'll have your program saying, "Hello world!". If not...

"Help! It doesn't work!"

I know, I've been there too. Good luck!