FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://sites.google.com/site/fpgadevelopindex/

Rocket-Chip を ZedBoardにインプリしてCoremarkを測定する(クロスコンパイル編)

Rocket-ChipをZedBoardに載せてLinuxが動作するようになったので、次はそのLinuxの上でアプリケーションを動かしてみる。 まずはRocket-Chipの基本性能が知りたいので、例によってCoremarkを動かしてみた。

(まあ実際には最新gccでCoremarkクロスコンパイル --> Rocket-Chip上で動かない --> gcc再ビルド だったのだが、ここでは分かりやすくするために最初の失敗を省略している)

CoremarkをRocket-Chip(というかRISC-V)で動かすためには、まずはクロスコンパイルしてRISC-V向けのバイナリを作る必要がある。

まず引掛ったのが、現在riscv/linuxで公開されているLinuxと、最新のRISC-V向けGCCでABIが合っていないということだ。。。

Compiled binaries not working in riscv-qemu · Issue #5 · riscv/riscv-gnu-toolchain · GitHub

現在公開されている最新のriscv64-unknown-linux-gnu-gccでCoremarkをコンパイルし、Rocketで実行すると、こうなる。

/ # ./coremark.exe
Segmentation fault

ずっと悩んでいたのだが、古いgccコンパイルしないとABIが合っていないようだ。

The problem is that we made an ABI-breaking change recently--hopefully
these will decrease in frequency as the tools mature.  At this moment, the
easiest thing to do is to go a few commits back on the toolchain
(c2086ad).  The more complex alternative
is to pull a new kernel, compile it with the new toolchain, and build a new
root filesystem with the updated userland libraries and programs.

という訳で、riscv-toolsのリビジョンを落として、再コンパイルしてgccを作り直す。

git@github.com:riscv/riscv-gnu-toolchain.git
cd riscv-gnu-toolchain
git checkout c2086ad
cd ..
mkdir ../riscv-gnu-toolchain-old-linux/configure --prefix=/home/masayuki/riscv-gnu-toolchain/
make linux

でバイナリを作り直した。riscv-linux-gcc がビルドされる。 という訳で、やっとRISC-Vのcoremarkのビルドに取り掛かる。

tar xvfz coremark_v1.0.tgz
cd coremark_v1.0
cp linux64 riscv64
cd riscv64

core_portme.mak を書き換える。GCCとLDを変更するだけだ。

...
CC = riscv-linux-gcc    # RISC-V 向け旧ABIのgccを指定
...
PORT_CFLAGS = -O2 -static # staticを追加してRocket-Chip上のLinuxで動くように

LD              = riscv-linux-gcc # RISC-V 向け旧ABIのgccを指定
...

ビルドする。

$ make PORT_DIR=riscv64/
make XCFLAGS=" -DPERFORMANCE_RUN=1" load run1.log
make[1]: ディレクトリ `/home/masayuki/riscv-hw/coremark_riscv/coremark_v1.0' に入ります
make port_prebuild
make[2]: ディレクトリ `/home/masayuki/riscv-hw/coremark_riscv/coremark_v1.0' に入ります
make[2]: `port_prebuild' に対して行うべき事はありません.
make[2]: ディレクトリ `/home/masayuki/riscv-hw/coremark_riscv/coremark_v1.0' から出ます
make link
make[2]: ディレクトリ `/home/masayuki/riscv-hw/coremark_riscv/coremark_v1.0' に入ります
riscv-linux-gcc -O2 -static -Iriscv64/ -I. -DFLAGS_STR=\""-O2 -static -DPERFORMANCE_RUN=1  -lrt"\" -DITERATIONS=0 -DPERFORMANCE_RUN=1 core_list_join.c core_main.c core_matrix.c core_state.c core_util.c riscv64//core_portme.c -o ./coremark.exe -lrt
Link performed along with compile
make[2]: ディレクトリ `/home/masayuki/riscv-hw/coremark_riscv/coremark_v1.0' から出ます
make port_postbuild
make[2]: ディレクトリ `/home/masayuki/riscv-hw/coremark_riscv/coremark_v1.0' に入ります
make[2]: `port_postbuild' に対して行うべき事はありません.
make[2]: ディレクトリ `/home/masayuki/riscv-hw/coremark_riscv/coremark_v1.0' から出ます
make port_preload
make[2]: ディレクトリ `/home/masayuki/riscv-hw/coremark_riscv/coremark_v1.0' に入ります
make[2]: `port_preload' に対して行うべき事はありません.
make[2]: ディレクトリ `/home/masayuki/riscv-hw/coremark_riscv/coremark_v1.0' から出ます
echo Loading done ./coremark.exe
Loading done ./coremark.exe
make port_postload
make[2]: ディレクトリ `/home/masayuki/riscv-hw/coremark_riscv/coremark_v1.0' に入ります
make[2]: `port_postload' に対して行うべき事はありません.
make[2]: ディレクトリ `/home/masayuki/riscv-hw/coremark_riscv/coremark_v1.0' から出ます
make port_prerun
make[2]: ディレクトリ `/home/masayuki/riscv-hw/coremark_riscv/coremark_v1.0' に入ります
make[2]: `port_prerun' に対して行うべき事はありません.
make[2]: ディレクトリ `/home/masayuki/riscv-hw/coremark_riscv/coremark_v1.0' から出ます
./coremark.exe  0x0 0x0 0x66 0 7 1 2000 > ./run1.log
./coremark.exe: 2: ./coremark.exe: Syntax error: word unexpected (expecting ")")
make[1]: *** [run1.log] エラー 2
make[1]: ディレクトリ `/home/masayuki/riscv-hw/coremark_riscv/coremark_v1.0' から出ます
make: *** [rerun] エラー 2

いろいろエラーが出るけど、これはクロスコンパイルしているからしようがない。

さて、RISC-V向けLinuxのディスクイメージにcoremark.exeを追加して、実機で動作させてみよう。