Run or debug with QEMU user mode - openjdk-riscv/jdk11u GitHub Wiki
使用QEMU用户模式执行Java二进制文件
由于目前riscv32g的linux系统暂时并不完善,同时为了便于增量调试,推荐采用QEMU的用户模式来运行benchmark及调试。
QEMU的安装过程可以参照交叉编译OpenJDK11 for RV32G(ZERO VM),这里不再赘述。
直接使用命令行执行
如果只是运行java -version
,可使用命令行:
$ /path/to/qemu/bin/qemu-riscv32 -L /path/to/riscv32/sysroot /path/to/jdk/bin/java -version
可以直接执行并正常输出。
但是在运行SPECjvm2008的时候会出现报错:
$ /path/to/qemu/bin/qemu-riscv32 -L /path/to/riscv32/sysroot /path/to/jdk/bin/java -jar SPECjvm2008.jar -ikv -ict -coe startup.helloworld
SPECjvm2008 Base
Properties file: none
Benchmarks: startup.helloworld
WARNING: Run will not be compliant.
Property specjvm.run.checksum.validation must be true for publication.
Not a compliant sequence of benchmarks for publication.
Property specjvm.run.initial.check must be true for publication.
--- --- --- --- --- --- --- --- ---
Benchmark: startup.helloworld
Run mode: static run
Test type: single
Threads: 1
Iterations: 1
Run length: 1 operation
Iteration 1 (1 operation) begins: Fri Mar 12 09:34:53 CST 2021
java.lang.RuntimeException: INVALID: Error Running Startup Test
java.lang.RuntimeException: INVALID: Error Running Startup Test
at spec.benchmarks.startup.Main.harnessMain(Main.java:115)
at spec.harness.BenchmarkThread.runLoop(BenchmarkThread.java:170)
at spec.harness.BenchmarkThread.executeIteration(BenchmarkThread.java:82)
at spec.harness.BenchmarkThread.run(BenchmarkThread.java:59)
Iteration 1 (1 operation) ends: Fri Mar 12 09:34:53 CST 2021
Iteration 1 (1 operation) result: **NOT VALID**
Errors in benchmark: startup.helloworld
[iter=1] Interrupted when joining benchmark thread 0: null
[iter=1] java.lang.InterruptedException: null
java.base/java.lang.Object.wait(Native Method)
java.base/java.lang.Thread.join(Thread.java:1305)
java.base/java.lang.Thread.join(Thread.java:1380)
spec.harness.ProgramRunner.runIteration(ProgramRunner.java:504)
spec.harness.ProgramRunner.runBenchmark(ProgramRunner.java:348)
spec.harness.ProgramRunner.run(ProgramRunner.java:98)
[iter=1] Iteration failed.
[iter=1][bt:1|op:1] java.lang.RuntimeException: INVALID: Error Running Startup Test
Score on startup.helloworld: **NOT VALID**
使用脚本包裹二进制文件
这里需要写一个shell脚本来包裹一下bin目录下面的二进制文件,并且手动填写里面包含qemu和sysroot,脚本如下:
#!/bin/sh
sysroot=/path/to/riscv32/sysroot
QEMU=/path/to/qemu/bin/qemu-riscv32
JAVA_HOME=/path/to/jdk
cd $JAVA_HOME/bin
for i in `ls|grep -v "\-bak$"`
do
if [ -f $i ]
then
if [ -f ${i}-bak ]
then
continue
fi
echo $i
mv $i ${i}-bak
echo "#!/bin/sh" > ${i}
echo "export JAVA_HOME=$JAVA_HOME" >> ${i}
echo "$QEMU -L $sysroot \$JAVA_HOME/bin/${i}-bak \"\$@\"" >> ${i}
chmod +x ${i}
fi
done
将脚本中的 sysroot
、QEMU
以及 JAVA_HOME(此处为编译构建生成的的JDK镜像,非源码或者bootJDK)
分别修改为具体的目录,随后保存(存储路径无要求)为prepare.sh
。
赋权并执行脚本:
$ chmod +x prepare.sh
$ bash prepare.sh
至此/path/to/jdk/bin/java -version
可以直接运行无需在命令行中配置qemu
及sysroot
,运行SPECjvm2008也可以顺利PASS:
# 先进入到SPECjvm2008目录下
$ cd /path/to/SPECjvm2008
$ /path/to/jdk/bin/java -jar SPECjvm2008.jar -ikv -ict -coe startup.helloworld
SPECjvm2008 Base
Properties file: none
Benchmarks: startup.helloworld
WARNING: Run will not be compliant.
Property specjvm.run.checksum.validation must be true for publication.
Not a compliant sequence of benchmarks for publication.
Property specjvm.run.initial.check must be true for publication.
--- --- --- --- --- --- --- --- ---
Benchmark: startup.helloworld
Run mode: static run
Test type: single
Threads: 1
Iterations: 1
Run length: 1 operation
Iteration 1 (1 operation) begins: Fri Mar 12 06:12:15 UTC 2021
Iteration 1 (1 operation) ends: Fri Mar 12 06:12:19 UTC 2021
Iteration 1 (1 operation) result: 13.91 ops/m
Valid run!
Score on startup.helloworld: 13.91 ops/m
生成报告部分可能会报错,是因为qemu对jdk图形化模块的支持问题,可以忽略。