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
いろいろエラーが出るけど、これはクロスコンパイルしているからしようがない。