diff --git a/.github/workflows/codacy.yml b/.github/workflows/codacy.yml index 14482b30a..6c37e2944 100644 --- a/.github/workflows/codacy.yml +++ b/.github/workflows/codacy.yml @@ -27,7 +27,7 @@ jobs: security-events: write # for github/codeql-action/upload-sarif to upload SARIF results actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status name: Codacy Security Scan - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: # Checkout the repository to the GitHub Actions runner - name: Checkout code diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index dfe0ee8d2..ab895ebb5 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -11,7 +11,7 @@ on: jobs: analyze: name: Analyze - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 permissions: actions: read contents: read diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml index aae4dc6c3..c98429e93 100644 --- a/.github/workflows/compliance.yml +++ b/.github/workflows/compliance.yml @@ -4,7 +4,7 @@ on: [push, pull_request] jobs: arch-tests: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - name: install-dependencies diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 000000000..78b72178d --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,33 @@ +name: Publish Docker image to Docker Hub +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +# https://docs.docker.com/build/ci/github-actions/multi-platform/ +jobs: + docker: + name: Build Docker Image and Publish (only on push) + runs-on: ubuntu-22.04 + steps: + + - name: Check out the repo + uses: actions/checkout@v4 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to Docker Hub + uses: docker/login-action@v3 + if: github.event_name == 'push' + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN }} + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + platforms: linux/amd64,linux/arm64/v8 + push: ${{ github.event_name == 'push' }} + tags: sysprog21/rv32emu:latest diff --git a/Dockerfile b/Dockerfile index 8f1676e50..e3aa92bad 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,13 @@ -FROM ubuntu:22.04 -LABEL maintainer="henrybear327@gmail.com" +FROM sysprog21/rv32emu-gcc as base_gcc +FROM sysprog21/rv32emu-sail as base_sail -# Install packages required for the emulator to compile and execute correctly +FROM ubuntu:22.04 as final + +# Install extra packages for the emulator to compile and execute with full capabilities correctly RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y \ - libsdl2-dev libsdl2-mixer-dev python3-pip git + libsdl2-dev libsdl2-mixer-dev python3-pip git && \ + rm -rf /var/lib/apt/lists/* RUN python3 -m pip install git+https://github.com/riscv/riscof @@ -12,44 +15,15 @@ RUN python3 -m pip install git+https://github.com/riscv/riscof ENV TZ=Asia/Taipei RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone -# when using apt install gcc-riscv64-unknown-elf, this will cause "unsupported ISA subset 'z'" during compilation -# thus, we are building from scratch, following the version here -> https://github.com/sysprog21/rv32emu/blob/master/.ci/riscv-toolchain-install.sh -# for x86, we can optimize this part and take the nightly build directly, but not for aarch64 -ENV RISCV=/opt/riscv -ENV PATH=$RISCV/bin:$PATH -WORKDIR $RISCV -RUN apt install -y 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 -RUN git clone --recursive https://github.com/riscv/riscv-gnu-toolchain -RUN cd riscv-gnu-toolchain && \ - git checkout tags/2023.10.06 && \ - ./configure --prefix=/opt/riscv --with-arch=rv32gc --with-abi=ilp32d && \ - make -j$(nproc) && \ - make clean - -# the default reference emulator is x86-based -# we need to build it ourselves if we are using it on aarch64 -# https://riscof.readthedocs.io/en/stable/installation.html#install-plugin-models -# the above commands are modified to match the current build flow as indicated in the Github CI -> https://github.com/riscv/sail-riscv/blob/master/.github/workflows/compile.yml -WORKDIR /home/root/ -RUN apt install -y opam zlib1g-dev pkg-config libgmp-dev z3 device-tree-compiler -RUN opam init --disable-sandboxing -y -RUN opam install -y sail -RUN git clone https://github.com/riscv/sail-riscv.git -# based on this commit https://github.com/sysprog21/rv32emu/commit/01b00b6f175f57ef39ffd1f4fa6a611891e36df3#diff-3b436c5e32c40ecca4095bdacc1fb69c0759096f86e029238ce34bbe73c6e68f -# we infer that the sail-riscv binary was taken from commit 9547a30bf84572c458476591b569a95f5232c1c7 -RUN cd sail-riscv && \ - git checkout 9547a30bf84572c458476591b569a95f5232c1c7 && \ - eval $(opam env) && \ - make && \ - ARCH=RV32 make - # copy in the source code WORKDIR /home/root/rv32emu COPY . . +# Copy the GNU Toolchain files +ENV RISCV=/opt/riscv +ENV PATH=$RISCV/bin:$PATH +COPY --from=base_gcc /opt/riscv/ /opt/riscv/ + # replace the emulator (riscv_sim_RV32) with the arch that the container can execute RUN rm /home/root/rv32emu/tests/arch-test-target/sail_cSim/riscv_sim_RV32 -RUN cp /home/root/sail-riscv/c_emulator/riscv_sim_RV32 /home/root/rv32emu/tests/arch-test-target/sail_cSim/riscv_sim_RV32 - -# clean up apt cache -RUN rm -rf /var/lib/apt/lists/* +COPY --from=base_sail /home/root/riscv_sim_RV32 /home/root/rv32emu/tests/arch-test-target/sail_cSim/riscv_sim_RV32 diff --git a/docker/.gitignore b/docker/.gitignore new file mode 100644 index 000000000..bf0824e59 --- /dev/null +++ b/docker/.gitignore @@ -0,0 +1 @@ +*.log \ No newline at end of file diff --git a/docker/Dockerfile-gcc b/docker/Dockerfile-gcc new file mode 100644 index 000000000..bf0e593bf --- /dev/null +++ b/docker/Dockerfile-gcc @@ -0,0 +1,20 @@ +FROM ubuntu:22.04 as base + +# when using apt install gcc-riscv64-unknown-elf, this will cause "unsupported ISA subset 'z'" during compilation +# thus, we are building from scratch, following the version here -> https://github.com/sysprog21/rv32emu/blob/master/.ci/riscv-toolchain-install.sh +# for x86, we can optimize this part and take the nightly build directly, but not for aarch64 +RUN apt-get update && \ + apt install -y \ + git 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 && \ + rm -rf /var/lib/apt/lists/* +RUN git clone --recursive https://github.com/riscv/riscv-gnu-toolchain +RUN cd riscv-gnu-toolchain && \ + git checkout tags/2023.10.06 && \ + ./configure --prefix=/opt/riscv --with-arch=rv32gc --with-abi=ilp32d && \ + make -j$(nproc) && \ + make clean + +FROM ubuntu:22.04 as final + +# Keep the GNU Toolchain files only +COPY --from=base /opt/riscv/ /opt/riscv/ diff --git a/docker/Dockerfile-sail b/docker/Dockerfile-sail new file mode 100644 index 000000000..144f6a96c --- /dev/null +++ b/docker/Dockerfile-sail @@ -0,0 +1,29 @@ +# builds the base image of rv32emu (the toolchains) +# docker build --progress=plain -t sysprog21/rv32emu-base -f Dockerfile-base . 2>&1 | tee build.log +FROM ubuntu:22.04 as base + +# the default reference emulator is x86-based +# we need to build it ourselves if we are using it on aarch64 +# https://riscof.readthedocs.io/en/stable/installation.html#install-plugin-models +# the above commands are modified to match the current build flow as indicated in the Github CI -> https://github.com/riscv/sail-riscv/blob/master/.github/workflows/compile.yml +RUN apt-get update && \ + apt install -y opam zlib1g-dev pkg-config libgmp-dev z3 device-tree-compiler && \ + rm -rf /var/lib/apt/lists/* +RUN opam init --disable-sandboxing -y +RUN opam switch create ocaml-base-compiler.4.13.1 # opam switch list-available +RUN opam search sail +# https://opam.ocaml.org/packages/sail/sail.0.16/ +RUN opam install -y sail.0.16 # latest version 0.17.x will cause complication issues for sail-riscv on commit 9547a3 +RUN git clone https://github.com/riscv/sail-riscv.git +# based on this commit https://github.com/sysprog21/rv32emu/commit/01b00b6f175f57ef39ffd1f4fa6a611891e36df3#diff-3b436c5e32c40ecca4095bdacc1fb69c0759096f86e029238ce34bbe73c6e68f +# we infer that the sail-riscv binary was taken from commit 9547a30bf84572c458476591b569a95f5232c1c7 +RUN cd sail-riscv && \ + git checkout 9547a30bf84572c458476591b569a95f5232c1c7 && \ + eval $(opam env) && \ + make && \ + ARCH=RV32 make + +FROM ubuntu:22.04 as final + +# keep the emulator only +COPY --from=base /sail-riscv/c_emulator/riscv_sim_RV32 /home/root/riscv_sim_RV32 diff --git a/docker/build.sh b/docker/build.sh new file mode 100755 index 000000000..d079c62ea --- /dev/null +++ b/docker/build.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# Note +# a) The build process will take around 20 and 10 minutes when building a native image on the native arch for gcc and sail, respectively, if internet connection is fast +# b) The multi-arch image build will take a long time (several hours) as we will use QEMU emulation. At the time of writing, we can only run multi-arch build successfully on x86 machines. + +# To enable multi-arch image build +# https://www.docker.com/blog/how-to-rapidly-build-multi-architecture-images-with-buildx/ +docker buildx create --name cross-platform-builder --use --bootstrap + +docker buildx build --progress=plain --push --platform linux/amd64,linux/arm64/v8 --tag sysprog21/rv32emu-gcc -f Dockerfile-gcc . 2>&1 | tee build-gcc.log +rm build-gcc.log + +docker buildx build --progress=plain --push --platform linux/amd64,linux/arm64/v8 --tag sysprog21/rv32emu-sail -f Dockerfile-sail . 2>&1 | tee build-sail.log +rm build-sail.log diff --git a/docs/base-image.md b/docs/base-image.md new file mode 100644 index 000000000..e420e2c69 --- /dev/null +++ b/docs/base-image.md @@ -0,0 +1,13 @@ +# Base images + +This directory contains the Dockerfiles of the base images, containing the `gcc` and `sail` toolchain. + +The build process should be rarely used, unless an update on the toolchain is required. When a new build is made by running `build.sh`, build and push to Docker Hub are automated. + +## Details + +For `gcc`, we are using the compiler version `tags/2023.10.06`, as using the binaries from `apt install gcc-riscv64-unknown-elf` will cause `"unsupported ISA subset 'z'"` error during the compilation of the emulator on M1. + +For `sail`, we set up the toolchain to use `sail-0.16`, as the latest version `0.17.x` series will cause compilation errors. + +We are using the commit `9547a30bf84572c458476591b569a95f5232c1c7` from `sail-riscv` for the reference simulator, as this is the commit cloest to the time when the [x86 reference sail emulator](https://github.com/sysprog21/rv32emu/commit/01b00b6f175f57ef39ffd1f4fa6a611891e36df3#diff-3b436c5e32c40ecca4095bdacc1fb69c0759096f86e029238ce34bbe73c6e68f) was added to the `rv32emu` Github repo.