Add Dockerfiles and scripts to fetch/build wallysoc/*_wally.

This commit is contained in:
Kunlin Han 2024-03-24 14:22:34 -07:00
parent 94a630f950
commit f45bdc1a65
5 changed files with 289 additions and 0 deletions

View File

@ -0,0 +1,83 @@
FROM wallysoc/ubuntu_wally
# SET ENVIRONMENT VARIABLES
# assume 4 threads are available to speed up
ARG NUM_THREADS=4
ENV RISCV=/opt/riscv
WORKDIR /opt/riscv
# TOOLCHAIN
RUN git clone https://github.com/riscv/riscv-gnu-toolchain && \
cd riscv-gnu-toolchain && \
sed -i 's/https/git/' .gitmodules && git submodule sync && \
./configure --prefix=${RISCV} --enable-multilib \
--with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;" && \
make --jobs ${NUM_THREADS} && \
make install && cd ${RISCV} && \
rm -rf ${RISCV}/riscv-gnu-toolchain
# # TOOLCHAIN
# RUN git clone https://github.com/riscv/riscv-gnu-toolchain && \
# cd riscv-gnu-toolchain && \
# sed -i 's/https/git/' .gitmodules && git submodule sync && \
# ./configure --prefix=${RISCV} --enable-multilib \
# --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;"
# RUN cd riscv-gnu-toolchain && make --jobs ${NUM_THREADS}
# RUN cd riscv-gnu-toolchain && make install && cd ${RISCV}
# RUN cd riscv-gnu-toolchain && rm -rf ${RISCV}/riscv-gnu-toolchain
# elf2hex
RUN git clone https://github.com/sifive/elf2hex.git && \
cd elf2hex && \
autoreconf -i && \
./configure --target=riscv64-unknown-elf --prefix=${RISCV} && \
make && \
make install && cd ${RISCV} && \
rm -rf ${RISCV}/elf2hex
# QEMU
RUN git clone --recursive https://github.com/qemu/qemu && \
cd qemu && \
./configure --target-list=riscv64-softmmu --prefix=${RISCV} && \
make --jobs ${NUM_THREADS} && \
make install && cd ${RISCV} && \
rm -rf ${RISCV}/qemu
# Spike
RUN git clone https://github.com/riscv-software-src/riscv-isa-sim && \
mkdir riscv-isa-sim/build && \
cd riscv-isa-sim/build && \
../configure --prefix=$RISCV --enable-commitlog && \
make --jobs ${NUM_THREADS} && \
make install && cd ${RISCV} && \
rm -rf ${RISCV}/riscv-isa-sim
# SAIL
RUN opam init -y --disable-sandboxing && \
opam switch create 5.1.0 && \
opam install sail -y && \
eval $(opam config env) && \
git clone https://github.com/riscv/sail-riscv.git && \
cd sail-riscv && \
ARCH=RV32 make c_emulator/riscv_sim_RV32 && \
ARCH=RV64 make c_emulator/riscv_sim_RV64 && \
ln -s ${RISCV}/sail-riscv/c_emulator/riscv_sim_RV64 ${RISCV}/bin/riscv_sim_RV64 && \
ln -s ${RISCV}/sail-riscv/c_emulator/riscv_sim_RV32 ${RISCV}/bin/riscv_sim_RV32 && \
rm -rf ${RISCV}/sail-riscv
# Buildroot
RUN git clone https://github.com/buildroot/buildroot.git && \
cd buildroot && \
git checkout 2021.05 && \
# cp -r /opt/riscv/riscv-wally/linux/buildroot-config-src/wally ./board && \
# cp ./board/wally/main.config .config && \
wget https://raw.githubusercontent.com/openhwgroup/cvw/main/linux/buildroot-config-src/wally/main.config -o .config && \
make --jobs ${NUM_THREADS}
RUN pip3 install --no-cache-dir \
testresources riscv_config \
git+https://github.com/riscv/riscof.git
USER ${USERNAME}

View File

@ -0,0 +1,33 @@
FROM ubuntu:22.04@sha256:aa772c98400ef833586d1d517d3e8de670f7e712bf581ce6053165081773259d
# Create a user group 'xyzgroup'
ARG USERNAME=cad
ARG USER_UID=1000
ARG USER_GID=$USER_UID
RUN apt update && \
apt install -y \
git gawk make texinfo bison flex build-essential python3 libz-dev libexpat-dev autoconf device-tree-compiler ninja-build libpixman-1-dev build-essential ncurses-base ncurses-bin libncurses5-dev dialog curl wget ftp libgmp-dev python3-pip pkg-config libglib2.0-dev opam z3 zlib1g-dev automake autotools-dev libmpc-dev libmpfr-dev gperf libtool patchutils verilator cpio bc vim emacs gedit nano && \
apt-get clean
# COPY requirements.txt /root
RUN pip3 install --no-cache-dir \
sphinx sphinx_rtd_theme matplotlib scipy scikit-learn adjustText lief
RUN ln -s /usr/bin/python3 /usr/bin/python
# Create the user
RUN groupadd --gid $USER_GID ${USERNAME} \
&& useradd --uid $USER_UID --gid $USER_GID -m ${USERNAME} \
# [Optional] Add sudo support. Omit if you don't need to install software after connecting.
&& apt-get update \
&& apt-get install -y sudo \
&& echo ${USERNAME} ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/${USERNAME} \
&& chmod 0440 /etc/sudoers.d/${USERNAME}
# Change RISCV user
RUN chown -Rf cad:cad /opt
# Add cad user
USER ${USERNAME}
WORKDIR /home/${USERNAME}

131
docs/docker/README.md Normal file
View File

@ -0,0 +1,131 @@
# Consistant Build of Toolchain for Wally
`Dockerfile.*` contains a ~~multi-stage~~ build for all the toolchains that are required for Wally's open-source features.
## TODOs
- [ ] Pinning the tools version
- As for the consistent tool build, should we use specific versions of tools in order to avoid bugs at the master branch?
- And we will upgrade the versions of tool after a certain period of time to get the latest features and patches while verifying it wont cause any problem.
- [ ] Mount the EDA Tools and Path
- [x] Enable X11 forwarding for docker
- `--network=host` for docker run
- `xhost +localhost:${USER}` for host
## TL;DR
Files at this folder can help you to build/fetch environment you need to run wally with the help of Docker.
Here are some common use cases, read the following text for other configuration:
```shell
# For HMC students, /opt/riscv is available and nothing needs to be built, skip this file
# For those with all the toolchains installed, simply mount the toolchains
TOOLCHAINS_MOUNT=<path-to-toolchains> ./start
# For those have nothing, fetching the builds are easiest thing
./start
# For other cases, checkout start-up script for building option
```
## New Dockerfile Design
There are two parts of the new docker-related design:
- build proper image(s)
- set up start-up script
### Problem Statement
The following 3 problems are to be resolved:
- remove storage of useless files with `Dockerfile`
- git build: clean up
- packages info
- apt: `apt-get clean`
- pip: `--no-cache-dir`
- reuse storage
- read-only $RISCV volume across different users with `docker image`
- local-built RISCV with `start-up script`
- use commercial EDA tools: optional environment variable configuration with `start-up script`
### Dockerfiles
There are two Dockerfiles:
- `Dockerfile.ubuntu`: basic ubuntu system setup and produce `ubuntu_wally` image in docker
- corresponds to `wallysoc/ubuntu_wally`
- `Dockerfile.builds`: all the required toolchains are built
- corresponds to `wallysoc/toolchains_wally`
Because we are going to use the whole environment of ubuntu to get both executables and python packages, we are not going to use multi-stage builds, which runs only executables.
### Scripts
There are two scripts:
- `get_images.sh`: get docker image `wallysoc/ubuntu_wally` or `wallysoc/toolchains_wally`
- `start.sh`: start running the container
#### Image Building Script
Options (if you want to build the images):
- UBUNTU_BUILD: value other than 0
- TOOLCHAINS_BUILD: value other than 0
#### Start-up Script
There are two settings:
- build/fetch both ubuntu_wally and toolchains in docker image and use it
- build/fetch only ubuntu_wally and use local toolchains folder
Options:
- ubuntu_wally: fetch by default
- build: UBUNTU_BUILD=1
- toolchains: fetch by default
- build: TOOLCHAINS_BUILD=1
- use local toolchain: TOOLCHAINS_MOUNT
### Commercial EDA Tools
This is kind of tricky, because Docker network is a different network from the host. Therefore, it should be carefully handled in order to use the host's license server while minimizing the access of docker container.
There are at least two ways to solve this problem:
- use `--network=host` in docker-run to use the same network
- (NOT WORKING) use bridge in docker-run while forwarding docker network's traffic to localhost without setting `X11UseLocalhost no`
- this idea is from https://stackoverflow.com/a/64284364/10765798
## Old Dockerfile Analysis
> Refer to https://github.com/openhwgroup/cvw/blob/91919150a94ccf8e750cf7c9eec1c400efaef7f5/docs/Dockerfile
There are stages in the old Dockerfile:
- debian-based package installtion
- apt package
- python3 package
- user and its group configuration
- clone and build toolchain with prefix=$RISCV
- riscv-gnu-toolchain
- elf2hex
- qemu
- spike
- sail
- buildroot
## References
- Dockerfile Docs: https://docs.docker.com/reference/dockerfile/
- Multi-stage builds: https://docs.docker.com/build/building/multi-stage/
- Best Practices: https://docs.docker.com/develop/develop-images/guidelines/
- Chinese Reference: https://yeasy.gitbook.io/docker_practice/
- Clean Cache
- apt cache: https://gist.github.com/marvell/7c812736565928e602c4
- pip cache: https://stackoverflow.com/questions/50333650/install-python-package-in-docker-file
- Docker Network: https://docs.docker.com/network/

20
docs/docker/get_images.sh Executable file
View File

@ -0,0 +1,20 @@
UBUNTU_BUILD=${UBUNTU_BUILD:-0}
TOOLCHAINS_BUILD=${TOOLCHAINS_BUILD:-0}
# if UBUNTU_BUILD is 0, then call function fetch_ubuntu_image
# otherwise, call function build_ubuntu_image
if [ $UBUNTU_BUILD -eq 0 ]; then
docker pull wallysoc/ubuntu_wally
else
docker build -t ubuntu_wally -f Dockerfile.ubuntu .
docker tag ubuntu_wally:latest wallysoc/ubuntu_wally:latest
fi
# if TOOLCHAINS_BUILD is 0, then call function fetch_toolchains_image
# otherwise, call function build_toolchains_image
if [ $TOOLCHAINS_BUILD -eq 0 ]; then
docker pull wallysoc/wally_toolchains
else
docker build -t wally_toolchains -f Dockerfile.builds .
docker tag wally_toolchains:latest wallysoc/wally_toolchains:latest
fi

22
docs/docker/start.sh Executable file
View File

@ -0,0 +1,22 @@
UBUNTU_WALLY_HASH=$(docker images --quiet wallysoc/ubuntu_wally)
TOOLCHAINS_HASH=$(docker images --quiet wallysoc/toolchains_wally)
TOOLCHAINS_MOUNT=${TOOLCHAINS_MOUNT}
if [ -z $UBUNTU_WALLY_HASH ]; then
echo "CANNOT FIND wallysoc/ubuntu_wally, please get the image first with \`get_image.sh\`";
exit 1
else
echo "Get ${UBUNTU_WALLY_HASH} for ubuntu_wally"
fi
if [ ! -z $TOOLCHAINS_MOUNT ]; then
docker run -it --rm -v ${TOOLCHAINS_MOUNT}:/opt/riscv wallysoc/ubuntu_wally
elif [ -z $TOOLCHAINS_HASH ]; then
echo "CANNOT FIND wallysoc/toolchains_wally, please get the image first with \`get_image.sh\`";
exit 1
else
echo "Get ${TOOLCHAINS_HASH} for toolchains_wally"
docker run -it --rm wallysoc/toolchains_wally
fi
echo "Successfully reach the end"