-
Notifications
You must be signed in to change notification settings - Fork 14
Build OpenJDK11 for RV32G
PLCT目前在进行RV32G的OpenJDK移植工作,由于目前RV32的工具链支持并不完善,暂时还没有RV64上Fedora一样的镜像,使用riscv-yocto等构建的镜像需要手动编译大量的lib,所以我们暂时先采用qemu user mode的方法来进行构建后的调试。
下面我们来试着自己编译一个OpenJDK11.0.9的RV32G zero版本。
本次实验基于 Ubuntu 20.04 LTS
$ lsb_release -a
LSB Version: core-11.1.0ubuntu2-noarch:security-11.1.0ubuntu2-noarch
Distributor ID: Ubuntu
Description: Ubuntu 20.04.3 LTS
Release: 20.04
Codename: focal
提前需要安装的工具链相关的软件如下:
$ sudo apt-get update -qq \
&& \
DEBIAN_FRONTEND=noninteractive \
sudo apt install -y -qq --no-install-recommends \
autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev \
gawk build-essential bison flex texinfo gperf libtool patchutils bc \
zlib1g-dev libexpat-dev git \
libglib2.0-dev libfdt-dev libpixman-1-dev \
libncurses5-dev libncursesw5-dev ninja-build \
python3 autopoint pkg-config zip unzip screen \
make libxext-dev libxrender-dev libxtst-dev \
libxt-dev libcups2-dev libfreetype6-dev \
mercurial libasound2-dev cmake libfontconfig1-dev python3-pip \
gettext
除此之外,额外依赖库还需要:
$ pip3 install docwriter
$ git clone https://github.com/riscv/riscv-gnu-toolchain
进入源码目录并checkout主目录到固定版本:
$ cd riscv-gnu-toolchain
$ git checkout b39e36
移除qemu子目录(后续在官网下载最新的源码)及riscv-newlib子目录,拉取子目录代码并checkout到固定版本:
$ git rm qemu
$ git rm riscv-newlib
$ git submodule update --init --recursive
# riscv-gcc
$ cd riscv-gcc
$ git checkout 5964b5
$ cd -
# riscv-binutils
$ cd riscv-binutils
$ git checkout 116a73
$ cd -
# riscv-gdb
$ cd riscv-gdb
$ git checkout 5da071
$ cd -
# riscv-glibc
$ cd riscv-glibc
$ git checkout 9826b0
$ cd -
# riscv-dejagnu
$ cd riscv-dejagnu
$ git checkout 4ea498
$ cd -
修改 /path/to/riscv32
为自己指定的目录,随后编译构建:
$ ./configure --prefix=/path/to/riscv32 --with-arch=rv32gc --with-abi=ilp32d
$ make linux -j
tips:如果在执行make命令时出现out of memory的报错问题,可以去掉参数-j重新尝试。
之后将toolchain 的安装路径写入.bashrc
文件:
$ echo -e '\nexport PATH="/path/to/riscv32/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc
(不推荐) 或者也可以直接执行export
命令,但是要注意重启或新开终端后需要再次执行:
$ export PATH="/path/to/riscv32/bin:$PATH"
$ wget https://download.qemu.org/qemu-5.2.0.tar.xz
$ tar xvJf qemu-5.2.0.tar.xz
$ cd qemu-5.2.0/
$ ./configure --target-list=riscv32-softmmu,riscv32-linux-user --prefix=/path/to/qemu
$ make -j && make install
$ /path/to/qemu/bin/qemu-system-riscv32 --version
出现类似如下输出,则安装成功
qemu-riscv32 version 5.2.0
Copyright (c) 2003-2020 Fabrice Bellard and the QEMU Project developers
在编译之前我们还需要安装一些额外的库的riscv版本,列表如下:
-
ALSA
-
CUPS
-
LIBPNG
-
Freetype2
-
Fontconfig
-
zlib
-
libuuid
-
libxml2
-
libpthread-stubs
-
libffi
-
X11
- xproto
- xtrans
- xextproto
- renderproto
- xcb-proto
- fixesproto
- kbproto
- recordproto
- inputproto
- xorgproto
- libICE
- libSM
- libXau
- libXcb
- libX11
- libXt
- libXfixes
- libXrender
- libXext
- libXi
- libXtst
- libXrandr
方案一 自动构建脚本
直接执行上述构建脚本即可
方案二 根据构建指导手动构建
可以参考毕昇JDK官方的构建指导和azul-research的构建指导,还可以参考azul-research的Dockerfile 进行构建,在编译的时候请将其中riscv64-unknown-linux-gnu更改为riscv32-unknown-linux-gnu。
上述手动构建脚本中的tips:
-
cups的相关脚本需要有所改动:
$ cd cups && ./configure --host=riscv32-unknown-linux-gnu --disable-ssl --disable-gssapi --disable-avahi --disable-libusb --disable-dbus --disable-systemd $ make CFLAGS="-Wno-error=sign-conversion -Wno-error=format-truncation" CXXFLAGS="-Wno-error=sign-conversion -Wno-error=format-truncation" && make install DSTROOT=$sysroot
-
脚本中给出freetype仓库有些问题,需要去官网下载:
$ wget https://download.savannah.gnu.org/releases/freetype/freetype-2.10.4.tar.gz $ tar -xzvf freetype-2.10.4.tar.gz
-
json-c需要切换到
json-c-0.13
分支 -
util-linux只需要libuuid.so和相关头文件即可,其他模块报错可以忽略
-
使用xorg安装libxshmfence的时候可能会出现报错:
这时候需要进入
/path/to/xorg/lib/libxshmfence
并手动修改打上patch:diff --git a/src/xshmfence_futex.h b/src/xshmfence_futex.h index 673ac0e..de6c3d6 100644 --- a/src/xshmfence_futex.h +++ b/src/xshmfence_futex.h @@ -53,6 +53,14 @@ static inline int futex_wait(int32_t *addr, int32_t value) { #include <sys/time.h> #include <sys/syscall.h> +#ifndef __NR_futex +#define __NR_futex 240 +#endif + +#ifndef SYS_futex +#define SYS_futex __NR_futex +#endif + static inline long sys_futex(void *addr1, int op, int val1, struct timespec *timeout, void *addr2, int val3) { return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3);
下载源码:
$ git clone https://github.com/openjdk-riscv/jdk11u.git
进入目录并切换分支:
$ cd jdk11u
$ git checkout 96943a
因为编译JDK需要自举,即假设要编译大版本号为N的JDK,我们还要另外准备一个大版本号至少为N-1的、已经编译好的JDK,这是因为OpenJDK由多个部分(HotSpot、JDK类库、JAXWS、JAXP等等)构成,其中一部分(HotSpot)代码使用C、C++编写,而更多的代码则是使用Java语言来实现,因此编译这些Java代码就需要用到另一个编译期可用的JDK,官方称这个JDK为“Bootstrap JDK”。
下载openJDK10:
$ wget https://download.java.net/openjdk/jdk10/ri/jdk-10_linux-x64_bin_ri.tar.gz
解压:
$ tar -xzvf jdk-10_linux-x64_bin_ri.tar.gz
Zero 版本构建运行以下命令:
$ bash configure \
--openjdk-target=riscv32-unknown-linux-gnu \
--disable-warnings-as-errors \
--with-sysroot=/path/to/riscv32/sysroot \
--with-boot-jdk=/path/to/jdk-10 \
--with-native-debug-symbols=none \
--with-jvm-variants=zero \
--with-jvm-interpreter=cpp
make JOBS=$(nproc) && make install
模版解释器构建运行以下命令:
bash configure \
--openjdk-target=riscv32-unknown-linux-gnu \
--disable-warnings-as-errors \
--with-sysroot=/home/zifeihan/riscv/riscv32/sysroot \
--with-boot-jdk=/home/zifeihan/jre/jre11 \
--with-jvm-variants=core \
--with-debug-level=slowdebug \
--with-native-debug-symbols=internal
make JOBS=$(nproc) && make install
C2 版本构建命令:
bash configure \
--openjdk-target=riscv32-unknown-linux-gnu \
--disable-warnings-as-errors \
--with-sysroot=/home/zifeihan/riscv/riscv32/sysroot \
--with-boot-jdk=/home/zifeihan/jre/jre11 \
--with-jvm-variants=custom \
--with-jvm-features=cds,cmsgc,compiler2,epsilongc,g1gc,jfr,jni-check,jvmti,management,nmt,parallelgc,serialgc,services,vm-structs \
--with-debug-level=slowdebug \
--with-native-debug-symbols=internal
make JOBS=$(nproc) && make install
由于我们之前工具链构建的linux headers为v5.4版本,而且QEMU在user mode下会使用主机系统的kernel来进行模拟系统调用等操作,所以如果主机kernel版本为v5.4以下,还需要升级kernel版本。
ubuntu查看kernel版本:
$ uname -a
Linux linux-ubuntu-1804-01 5.4.0-050400-generic #201911242031 SMP Mon Nov 25 01:35:10 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
获取kernel的安装包:
$ wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.4/linux-headers-5.4.0-050400_5.4.0-050400.201911242031_all.deb
$ wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.4/linux-headers-5.4.0-050400-generic_5.4.0-050400.201911242031_amd64.deb
$ wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.4/linux-image-unsigned-5.4.0-050400-generic_5.4.0-050400.201911242031_amd64.deb
$ wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.4/linux-modules-5.4.0-050400-generic_5.4.0-050400.201911242031_amd64.deb
安装并重启:
$ sudo dpkg -i *.deb
$ sudo reboot
之后使用QEMU的用户模式来进行测试:
$ /path/to/qemu/bin/qemu-riscv32 -L /path/to/riscv32/sysroot ./java -version
测试结果:
openjdk version "11.0.9-internal" 2020-10-20
OpenJDK Runtime Environment (build 11.0.9-internal+0-adhoc.dingli.jdk11u)
OpenJDK Zero VM (build 11.0.9-internal+0-adhoc.dingli.jdk11u, interpreted mode)