🙃

RISC-Vの開発環境をLinux上に構築する

2022/07/15に公開

RISC-Vの開発環境をLinux (x86_64) 上に構築していく。

インストールするもの

ここでは以下の3つをインストールする。

  1. RISC-V GNU toolchain:
    プログラムのコンパイルに使う。
  2. Spike:
    RISC-Vのシミュレーター。実行ファイルを渡せばx64上でもRISC-Vの挙動を再現できる。
  3. pk:
    Spikeを動かす際、stdoutへの出力など、OSが管理するI/Oシステムコールを機能させる。

事前準備: 環境変数RISCVの設定

Spikeとpkをインストールする際、そのインストールパスを表すものとして環境変数RISCVが共通して使われる。RISC-V GNU toolchainもインストールパスを聞いてくるが、同じ場所にインストールすると便利。適当なディレクトリを設定する。さらに$RISCV/binにツールの実行ファイルが置かれるので、ここまでのpathを通す。

$ export RISCV=/path/to/riscv/tools
$ export PATH=$RISCV/bin:$PATH

RISC-V GNU toolchain

GCCやobjdumpなど、コンパイルや解析に使うツール群。

https://github.com/riscv-collab/riscv-gnu-toolchain

ビルドはREADMEに従っていけばうまくいった。

Clone

$ git clone https://github.com/riscv-collab/riscv-gnu-toolchain.git
$ cd riscv-gnu-toolchain

このリポジトリはsubmoduleを含んでいるが、必要なときに勝手にインストールされるので--recursivegit submoudle update --xxxなどは不要とのこと。

Install prerequisites

toolchainをビルドするのに必要なパッケージ群をインストールする。必要なパッケージ一覧はREADMEのここを見てほしい。

たくさんのパッケージが列挙してあるが、おそらくほとんどのものが既にインストールされていると思われる。私の環境の場合、だいたい3つくらいの新しいパッケージをインストールするだけだった。

Install

-jオプションなしだと結構時間かかるので付けた方が良い。

$ ./configure --prefix=$RISCV
$ make linux -j$(nproc)

完了したら$RISCV/binのディレクトリを見ると、インストールしたコマンド群が把握できて面白い。例えば下記のコマンドとかで実際にインストールができてpathが通っているかを確認できる。

$ riscv64-unknown-linux-gnu-gcc --version

RISC-V tools

riscv-software-src/riscv-toolsはいくつかのRISC-Vの開発ツールをまとめてあるものだが、このコメントにもあるようにすでにメンテナンスされていないっぽいし、実際READMEに従ってビルドしようとしても失敗した。ここでは使わないことにする。

それぞれのツールを個別にビルドしていく。

Spike

RISC-VのISAシミュレーター。

https://github.com/riscv-software-src/riscv-isa-sim

Clone

$ git clone https://github.com/riscv-software-src/riscv-isa-sim.git
$ cd riscv-isa-sim

Install device tree compiler

Device Tree Compilerが必要なのでインストールする。

# Ubuntu
$ sudo apt-get install device-tree-compiler

# Fedora
$ sudo yum install dtc

# Arch Linux
$ sudo pacman -S dtc

Install

$ mkdir build
$ cd build
$ ../configure --prefix=$RISCV
$ make
$ sudo make install

終了したら適当なspikeコマンドでインストールできているか確認する。

$ ./spike --help

RISC-V Proxy Kernel (pk)

I/O関連のシステムコールを機能させるためのもの。SpikeはRISC-VのISAシミュレーターなので、OSへのシステムコールを理解しない。(というかOS自体がない。) そこでシステムコールが発行された際には、pkがシステムコールをホストコンピュータに渡して機能させる。

https://github.com/riscv-software-src/riscv-pk

Clone

$ git clone https://github.com/riscv-software-src/riscv-pk.git
$ cd riscv-pk

Install

$ mkdir build
$ cd build
$ ../configure --prefix=$RISCV --host=riscv64-unknown-linux-gnu
$ make
$ make install

完了すると$RISCV/riscv64-unknown-linux-gnu/binpkという名前のファイルが置かれる。

ここまででできること

さてRISC-V GNU toolchainとSpikeとpkがインストールできた。ここまでくると、例えばC言語のプログラムをRISC-V向けにコンパイルして実行しstdoutに出力できる。やってみる。

// fib.c
#include <stdio.h>

int fib(int n) {
    if (n <= 1) {
      return n;
    }

    return fib(n - 2) + fib(n - 1);
}

int main() {
    printf("fib(10) = %d\n", fib(10));
}

コンパイルする。(spike/pkが静的リンクされているバイナリでしか動かないため、-staticが必要。)

$ riscv64-unknown-linux-gnu-gcc -static fib.c -o fib

実行して出力を見る。(pkに関してはpathを通した方が使いやすいかも。)

$ spike $RISCV/riscv64-unknown-linux-gnu/bin/pk fib
bbl loader
fib(10) = 55

objdumpでdisassembleしてRISC-Vのアセンブリも見れる。

$ riscv64-unknown-linux-gnu-objdump -d fib

楽しい。

おわりに

間違っている点やより良い方法の提案があれば指摘してもらえると非常にありがたいです。

Discussion