diff --git a/src/ubuntu-generic-diskimages/22.04-dockerfile/Dockerfile b/src/ubuntu-generic-diskimages/22.04-dockerfile/Dockerfile new file mode 100644 index 000000000..18ba9548f --- /dev/null +++ b/src/ubuntu-generic-diskimages/22.04-dockerfile/Dockerfile @@ -0,0 +1,45 @@ +FROM ubuntu:22.04 AS stage1 + +# Install necessary packages for kernel build +RUN apt update && apt install -y \ + build-essential \ + libncurses-dev \ + bison \ + flex \ + libssl-dev \ + libelf-dev \ + bc \ + wget \ + git \ + kmod \ + apt-src \ + vim \ + curl \ + file + +RUN sed -Ei 's/^# deb-src /deb-src /' /etc/apt/sources.list +RUN apt update +RUN mkdir /workspace +RUN cd /workspace && apt source linux-image-unsigned-5.15.0-25-generic + +RUN cd /workspace/linux-5.15.0 && \ + make defconfig && \ + make -j 32 && \ + make INSTALL_MOD_PATH=/workspace/output modules_install + +RUN git clone https://github.com/nkrim/gem5.git --depth=1 --filter=blob:none --no-checkout --sparse --single-branch --branch=gem5-bridge && \ + cd gem5 && \ + git sparse-checkout add util/m5 && \ + git sparse-checkout add util/gem5_bridge && \ + git sparse-checkout add include && \ + git checkout + +RUN cd gem5/util/gem5_bridge && \ + make KMAKEDIR=/workspace/linux-5.15.0 INSTALL_MOD_PATH=/workspace/output build install + +RUN cd /workspace/output/lib/modules/5.15.* && \ + rm -rf build source + +FROM scratch AS export-stage +COPY --from=stage1 /workspace/output/lib/modules . +COPY --from=stage1 workspace/linux-5.15.0/vmlinux . diff --git a/src/ubuntu-generic-diskimages/24.04-dockerfile/Dockerfile b/src/ubuntu-generic-diskimages/24.04-dockerfile/Dockerfile new file mode 100644 index 000000000..1112719cd --- /dev/null +++ b/src/ubuntu-generic-diskimages/24.04-dockerfile/Dockerfile @@ -0,0 +1,43 @@ +# Start from Ubuntu 24.04 base image +FROM ubuntu:24.04 AS stage1 + +# Install necessary packages for kernel and module build +RUN apt update && apt install -y \ + build-essential \ + libncurses-dev \ + bison \ + flex \ + libssl-dev \ + libelf-dev \ + bc \ + wget \ + git \ + kmod + + +RUN sed -i 's/^Types: deb$/Types: deb deb-src/' /etc/apt/sources.list.d/ubuntu.sources +RUN apt update +RUN mkdir /workspace +RUN cd /workspace && apt source linux-image-unsigned-6.8.0-47-generic + +RUN cd /workspace/linux-6.8.0 && \ + make defconfig && \ + make -j 32 && \ + make INSTALL_MOD_PATH=/workspace/output modules_install + +RUN git clone https://github.com/nkrim/gem5.git --depth=1 --filter=blob:none --no-checkout --sparse --single-branch --branch=gem5-bridge && \ + cd gem5 && \ + git sparse-checkout add util/m5 && \ + git sparse-checkout add util/gem5_bridge && \ + git sparse-checkout add include && \ + git checkout + +RUN cd gem5/util/gem5_bridge && \ + make KMAKEDIR=/workspace/linux-6.8.0 INSTALL_MOD_PATH=/workspace/output build install + +RUN cd /workspace/output/lib/modules/6.8.12 && \ + rm -rf build + +FROM scratch AS export-stage +COPY --from=stage1 /workspace/output/lib/modules . +COPY --from=stage1 /workspace/linux-6.8.0/vmlinux . diff --git a/src/ubuntu-generic-diskimages/BUILDING.md b/src/ubuntu-generic-diskimages/BUILDING.md index 48b49352d..722095adb 100644 --- a/src/ubuntu-generic-diskimages/BUILDING.md +++ b/src/ubuntu-generic-diskimages/BUILDING.md @@ -39,6 +39,8 @@ dd if=/dev/zero of=flash0.img bs=1M count=64 dd if=/usr/share/qemu-efi-aarch64/QEMU_EFI.fd of=flash0.img conv=notrunc ``` +If you want to get the `gem5-bridge` driver and the kernel locally, please refer to the documentation [here](make-kernel-and-gem5-bridge-driver.md). + **Note**: The `build-arm.sh` will make this file for you. Note: Building the image can take a while to run. diff --git a/src/ubuntu-generic-diskimages/files/arm/gem5_init.sh b/src/ubuntu-generic-diskimages/files/arm/gem5_init.sh index 0c13e97ad..cf05f64c7 100755 --- a/src/ubuntu-generic-diskimages/files/arm/gem5_init.sh +++ b/src/ubuntu-generic-diskimages/files/arm/gem5_init.sh @@ -15,6 +15,25 @@ mount -t sysfs /sys /sys cmdline=$(cat /proc/cmdline) no_systemd=false +# Load gem5_bridge driver +## Default parameters (ARM64) +gem5_bridge_baseaddr=0x10010000 +gem5_bridge_rangesize=0x10000 +## Try to read overloads from kernel arguments +if [[ $cmdline =~ gem5_bridge_baseaddr=([[:alnum:]]+) ]]; then + gem5_bridge_baseaddr=${BASH_REMATCH[1]} +fi +if [[ $cmdline =~ gem5_bridge_rangesize=([[:alnum:]]+) ]]; then + gem5_bridge_rangesize=${BASH_REMATCH[1]} +fi +## Insert driver +modprobe gem5_bridge \ + gem5_bridge_baseaddr=$gem5_bridge_baseaddr \ + gem5_bridge_rangesize=$gem5_bridge_rangesize + +# see if this modprode fails or not +# print warning if it fails, gem5-bridge module is not going to work, you will need sudo for running exit events + # gem5-bridge exit signifying that kernel is booted # This will cause the simulation to exit. Note that this will # cause qemu to fail. diff --git a/src/ubuntu-generic-diskimages/http/arm-22-04/user-data b/src/ubuntu-generic-diskimages/http/arm-22-04/user-data index b82387329..387209290 100644 --- a/src/ubuntu-generic-diskimages/http/arm-22-04/user-data +++ b/src/ubuntu-generic-diskimages/http/arm-22-04/user-data @@ -70,7 +70,7 @@ autoinstall: type: format id: format-0 - device: disk-vda - size: 4257218560 + size: 4557218560 wipe: superblock flag: '' number: 2 diff --git a/src/ubuntu-generic-diskimages/http/arm-24-04/user-data b/src/ubuntu-generic-diskimages/http/arm-24-04/user-data index 895062bbb..ec9ada114 100644 --- a/src/ubuntu-generic-diskimages/http/arm-24-04/user-data +++ b/src/ubuntu-generic-diskimages/http/arm-24-04/user-data @@ -62,7 +62,7 @@ autoinstall: type: format id: format-0 - device: disk-vda - size: 4257218560 + size: 4557218560 wipe: superblock flag: '' number: 2 diff --git a/src/ubuntu-generic-diskimages/make-arm-kernel.sh b/src/ubuntu-generic-diskimages/make-arm-kernel.sh new file mode 100755 index 000000000..57b05e060 --- /dev/null +++ b/src/ubuntu-generic-diskimages/make-arm-kernel.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# Ensure an argument is provided +if [ -z "$1" ]; then + echo "Usage: $0 " + echo "Example: $0 24.04" + echo " $0 22.04" + exit 1 +fi + +# Set variables based on the argument +if [ "$1" == "24.04" ]; then + DOCKERFILE="./24.04-dockerfile/Dockerfile" + OUTPUT="my-arm-6.8.12-kernel" +elif [ "$1" == "22.04" ]; then + DOCKERFILE="./22.04-dockerfile/Dockerfile" + OUTPUT="my-arm-5.15.167-kernel" +else + echo "Invalid version: $1" + echo "Supported versions: 24.04, 22.04" + exit 1 +fi + +# Build the Docker image +DOCKER_BUILDKIT=1 docker build --no-cache \ + --file "$DOCKERFILE" \ + --output "$OUTPUT" . + +echo "Build completed for $1: Output directory is $OUTPUT" diff --git a/src/ubuntu-generic-diskimages/make-kernel-and-gem5-bridge-driver.md b/src/ubuntu-generic-diskimages/make-kernel-and-gem5-bridge-driver.md new file mode 100644 index 000000000..cc4609fb0 --- /dev/null +++ b/src/ubuntu-generic-diskimages/make-kernel-and-gem5-bridge-driver.md @@ -0,0 +1,128 @@ + +# Make Kernel and the gem5 Bridge Driver + +This document outlines the steps to build a Linux kernel and its modules with the gem5-bridge driver for the ARM Ubuntu disk images. Below are separate instructions for Ubuntu 24.04 and Ubuntu 22.04. + +**Note**: These dockerfiles assume that you are running on arm host to build them. If you are not on ARM host then you would need to use a cross compiler to make the kernel and the modules. + +## Table of Contents + +- [Ubuntu 24.04 Disk Image](#ubuntu-2404-disk-image) +- [Ubuntu 22.04 Disk Image](#ubuntu-2204-disk-image) + +## **Ubuntu 24.04 Disk Image** + +### Build the Docker Image + +The Docker image build process will copy the built kernel and modules to your host system, making them readily available for further use. + + Run the `make-arm-kernel.sh` script located in the directory `src/ubuntu-generic-diskimages`. + Since we are building the kernel that is included by default in Ubuntu 24.04, you need to use the `24.04` argument with the script: + +```bash +./make-arm-kernel.sh 24.04 +``` + +### Verify Output + +- Check the contents of `my-arm-6.8.12-kernel`: + + ```bash + ls my-arm-6.8.12-kernel/ + ``` + + You should see: + - `vmlinux` — The built kernel image. + - `6.8.12/` — Directory containing the kernel modules. + +### Add Kernel Modules to the Disk Image + +- Add a Packer file provisioner to copy the modules to the disk image. The Packer script is located at `ubuntu-generic-diskimages/packer-scripts/arm-ubuntu.pkr.hcl`. +Make sure that this provisioner is added before the shell provisioner, as these files are used when the shell provisioner runs`post-installation.sh`: + + ```hcl + provisioner "file" { + destination = "/home/gem5" + source = "my-arm-6.8.12-kernel/6.8.12" + } + ``` + +- Add the following code snippet to the post-install script to move the modules into the correct location and regenerate the initramfs. The post-install script is located at `ubuntu-generic-diskimages/scripts/post-installation.sh`. +Make sure the modules are moved before using `gem5-bridge` or compiling benchmarks with `gem5-bridge`, i.e. add the snippet before the line `echo "Building and installing gem5-bridge (m5) and libm5"`: + + ```bash + mv /home/gem5/6.8.12 /lib/modules/6.8.12 + depmod --quick -a 6.8.12 + update-initramfs -u -k 6.8.12 + ``` + +### Build the Disk Image + +- Build the disk image using your build script: + + ```bash + ./build-arm.sh 24.04 + ``` + +### Test with gem5 + +- Use the disk image and the kernel to run a gem5 filesystem simulation, ensuring the new kernel and modules are correctly set up. + +## **Ubuntu 22.04 Disk Image** + +### Build the Docker Image + +The Docker image build process will copy the built kernel and modules to your host system, making them readily available for further use. + + Run the `make-arm-kernel.sh` script located in the directory `src/ubuntu-generic-diskimages`. + Since we are building the kernel that is included by default in Ubuntu 22.04, you need to use the `22.04` argument with the script: + +```bash +./make-arm-kernel.sh 22.04 +``` + +### Add Kernel Modules to the Disk Image + +- Add a Packer file provisioner to copy the modules to the disk image. The Packer script is located at `ubuntu-generic-diskimages/packer-scripts/arm-ubuntu.pkr.hcl`. +Make sure that this provisioner is added before the shell provisioner as we will used these files in the `post-installation.sh`: + + ```hcl + provisioner "file" { + destination = "/home/gem5" + source = "my-arm-5.15.167-kernel/5.15.167" + } + ``` + +- Add the following code snippet to the post-install script to move the modules into the correct location and regenerate the initramfs. The post-install script is located at `ubuntu-generic-diskimages/scripts/post-installation.sh`. +Make sure the modules are moved before using `gem5-bridge` or compiling benchmarks with `gem5-bridge`, i.e. add the snippet before the line `echo "Building and installing gem5-bridge (m5) and libm5"`: + + ```bash + mv /home/gem5/5.15.167 /lib/modules/5.15.167 + depmod --quick -a 5.15.167 + update-initramfs -u -k 5.15.167 + ``` + +### Build the Disk Image + +- Build the disk image using your build script: + + ```bash + ./build-arm.sh 22.04 + ``` + +### Test with gem5 + +- Use the disk image and the kernel to run a gem5 filesystem simulation, ensuring the new kernel and modules are correctly set up. See the bottom of this file for an example. + +- You can use the following code snippet to use the disk image and kernel you made. + +```python +image = DiskImageResource("/path/to/gem5-resources/src/ubuntu-generic-diskimages/arm-disk-image-22-04/arm-ubuntu") +image._root_partition = "2" + +board.set_kernel_disk_workload( + kernel=KernelResource("/path/to/gem5-resources/src/ubuntu-generic-diskimages/my-arm-5.15.167-kernel/vmlinux"), + disk_image=image, + bootloader=obtain_resource("arm64-bootloader-foundation"), +) +``` diff --git a/src/ubuntu-generic-diskimages/packer-scripts/arm-ubuntu.pkr.hcl b/src/ubuntu-generic-diskimages/packer-scripts/arm-ubuntu.pkr.hcl index 6e81dd5e6..02fdea798 100644 --- a/src/ubuntu-generic-diskimages/packer-scripts/arm-ubuntu.pkr.hcl +++ b/src/ubuntu-generic-diskimages/packer-scripts/arm-ubuntu.pkr.hcl @@ -92,7 +92,7 @@ source "qemu" "initialize" { "" ] cpus = "4" - disk_size = "4600" + disk_size = "5000" format = "raw" headless = "true" http_directory = local.iso_data[var.ubuntu_version].http_directory @@ -139,4 +139,5 @@ build { environment_vars = ["ISA=arm64"] expect_disconnect = true } + } diff --git a/src/ubuntu-generic-diskimages/scripts/post-installation.sh b/src/ubuntu-generic-diskimages/scripts/post-installation.sh index 7d29bc153..24a0f889c 100755 --- a/src/ubuntu-generic-diskimages/scripts/post-installation.sh +++ b/src/ubuntu-generic-diskimages/scripts/post-installation.sh @@ -18,13 +18,6 @@ apt-get install -y build-essential echo "Installing serial service for autologin after systemd" mv /home/gem5/serial-getty@.service /lib/systemd/system/ -# Make sure the headers are installed to extract the kernel that DKMS -# packages will be built against. -sudo apt -y install "linux-headers-$(uname -r)" "linux-modules-extra-$(uname -r)" - -echo "Extracting linux kernel $(uname -r) to /home/gem5/vmlinux-x86-ubuntu" -sudo bash -c "/usr/src/linux-headers-$(uname -r)/scripts/extract-vmlinux /boot/vmlinuz-$(uname -r) > /home/gem5/vmlinux-x86-ubuntu" - echo "Installing the gem5 init script in /sbin" mv /home/gem5/gem5_init.sh /sbin mv /sbin/init /sbin/init.old @@ -47,14 +40,15 @@ if [ -z "$ISA" ]; then fi # Just get the files we need -git clone https://github.com/gem5/gem5.git --depth=1 --filter=blob:none --no-checkout --sparse --single-branch --branch=stable +git clone https://github.com/nkrim/gem5.git --depth=1 --filter=blob:none --no-checkout --sparse --single-branch --branch=gem5-bridge pushd gem5 # Checkout just the files we need git sparse-checkout add util/m5 +git sparse-checkout add util/gem5_bridge git sparse-checkout add include git checkout # Install the headers globally so that other benchmarks can use them -cp -r include/gem5 /usr/local/include/\ +cp -r include/gem5 /usr/local/include/ # Build the library and binary pushd util/m5