From ef7547f07caebbd58e7743cf7a13c559232dfd56 Mon Sep 17 00:00:00 2001 From: Teloecho Date: Sat, 30 Nov 2024 18:09:10 +0100 Subject: [PATCH 1/7] resources: Add riscv-fs/riscv-busybox-opensbi Inspired by riscv-fs-nodisk however, replacing legacy Berkeley bootloader (bbl) with OpenSBI FW_PAYLOAD bootloader, additionally just using default Linux and Busybox configurations instead of not up-to-date UCanLinux configs. --- src/riscv-fs/README.md | 3 + src/riscv-fs/riscv-busybox-opensbi/README.md | 249 +++++++++++++++++++ 2 files changed, 252 insertions(+) create mode 100644 src/riscv-fs/riscv-busybox-opensbi/README.md diff --git a/src/riscv-fs/README.md b/src/riscv-fs/README.md index fac07270..f7005516 100644 --- a/src/riscv-fs/README.md +++ b/src/riscv-fs/README.md @@ -4,6 +4,9 @@ This repository contains the latest resources for RISC-V full-system builds. **Directory Structure:** +- **riscv-busybox-opensbi:** + Documentation on building a RISC-V OpenSBI bootloader including Linux kernel and Busybox compiled into a single binary. No extra disk. + - **riscv-opensbi:** Documentation on building a RISC-V OpenSBI bootloader and Linux 6.5.5 kernel. diff --git a/src/riscv-fs/riscv-busybox-opensbi/README.md b/src/riscv-fs/riscv-busybox-opensbi/README.md new file mode 100644 index 00000000..469a57d1 --- /dev/null +++ b/src/riscv-fs/riscv-busybox-opensbi/README.md @@ -0,0 +1,249 @@ +--- +title: RISC-V Full System in One Kernel Resource +tags: + - fullsystem + - bootloader + - riscv +layout: default +permalink: resources/riscv-fs-busybox-opensbi +shortdoc: > + Resources to build an OpenSBI bootloader with Linux image, initramfs and Busybox that works with gem5 full system simulations. +author: ["Jonathan Kretschmer"] +--- + +# RISC-V Linux Full System Bootloader, initramfs and Workload in One + +This document provides instructions to create an +(OpenSBI)[https://github.com/riscv-software-src/opensbi] bootloader binary +with Linux kernel image payload containing an initramfs with +(Busybox)[https://www.busybox.net/] that works with gem5 full system simulations. + +This guide is inspired by and partly copied from +(riscv-fs-nodisk)[https://github.com/gem5/gem5-resources/blob/stable/src/riscv-fs-alt/riscv-boot-exit-nodisk/README.md] +and (Linux on RISC-V using QEMU and BUSYBOX from scratch)[https://risc-v-machines.readthedocs.io/en/latest/linux/simple/]. + +For this guide we assume following directory structure. Gem5 source itself is +required either, but not listed here to avoid duplication. +``` +riscv-all-in-one/ + ├── busybox/ # busybox source + ├── cpio/ # contains the .cpio file + ├── initramfs/ # contains the structure of initramfs + ├── linux/ # linux source + ├── opensbi/ # OpenSBI source, providing a RISC-V bootloader + ├── riscv-gnu-toolchain/ # riscv tool chain for cross compilation + └── README.md # This README file +``` + +# Building the resource +## Step 1. Building the `riscv-gnu-toolchain` +In this step, we'll use +[GNU toolchain for RISC-V](https://github.com/riscv-collab/riscv-gnu-toolchain). + +This step is necessary if you do not have basic libraries built for RISCV or +if you're cross-compiling RISCV. + +```sh +cd riscv-all-in-one/ +git clone https://github.com/riscv-collab/riscv-gnu-toolchain.git +cd riscv-gnu-toolchain +git switch --detach 20f615317e2ce888dfc11b29ccde4a649494b654 # for reproducability, newer versions should work either +mkdir build +cd build +# --prefix parameter specifying the installation location +# --enable-multilib build either cross-compiler with support for both 32-bit and 64-bit +../configure --prefix=/path/to/rvtoolchain --enable-multilib +make linux -j$(nproc) +``` +To update the PATH environment variable so that the RISCV compilers can be +found, +```sh +export PATH=/path/to/rvtoolchain/bin/:$PATH +``` + +## Step 2. Getting and Building `busybox` +More information about Busybox is [here](https://www.busybox.net/). +```sh +cd riscv-all-in-one/ +git clone --branch 1_36_stable https://git.busybox.net/busybox.git # choose a stable branch + +# alternatively downloading tar +wget https://git.busybox.net/busybox/snapshot/busybox-1_36_1.tar.bz2 +tar xf busybox-1_36_1.tar.bz2 +mv busybox-1_36_1 busybox + +cd busybox +# create a default configuration +make CROSS_COMPILE=riscv64-unknown-linux-gnu- defconfig +make CROSS_COMPILE=riscv64-unknown-linux-gnu- menuconfig +# Configure static linking in order to simplify things. +# Settings ---> +# Build Options ---> +# Build static binary (no shared libs) ---> yes +make CROSS_COMPILE=riscv64-unknown-linux-gnu- all -j$(nproc) +make CROSS_COMPILE=riscv64-unknown-linux-gnu- install # optional +``` +The files of interest are in `busybox/_install/bin`. + +## Step 3. Compiling the Workload (e.g. gem5's m5) +Change to the directory with your clone of gem5 version 24.0.0.1. +```sh +cd gem5/ +cd util/m5 +scons build/riscv/out/m5 +``` +**Note**: the default cross-compiler is `riscv64-unknown-linux-gnu-`. +To change the cross-compiler, you can set the cross-compiler using the scons +sticky variable `riscv.CROSS_COMPILE`. For example, +```sh +scons riscv.CROSS_COMPILE=riscv64-linux-gnu- build/riscv/out/m5 +``` + +## Step 4. Determining the Structure of `initramfs` +Your Linux requires a *file system* in order to properly run. So we will +prepare the file structure and the `init` script. +```sh +cd riscv-all-in-one/ +mkdir initramfs +cd initramfs +mkdir -p {bin,sbin,dev,etc,home,mnt,proc,sys,usr,tmp} +mkdir -p usr/{bin,sbin} +mkdir -p proc/sys/kernel +# Without following devices, we cannot see the output to `stdout` and `stderr` +fakeroot -- mknod -m 622 dev/console c 5 1 +fakeroot -- mknod -m 622 dev/sda b 8 0 +fakeroot -- mknod -m 622 dev/tty c 5 0 +fakeroot -- mknod -m 622 dev/ttyprintk c 5 3 +fakeroot -- mknod -m 622 dev/null c 1 3 +``` +**Note:** `mknod -m 622 /dev/tty c 5 0` means we're creating `/dev/tty` with +permission of `622`. `c` means a character device being created, `5` is the +major number, and `0` is the minor number. More information about the +major/minor numbering is available at +(https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/devices.txt). + +Drop the `busybox` executable from the previous section into the filesystem: +```sh +cp ../busybox/busybox ./bin/ +``` +Drop the workload: +```sh +cp /path/to/your/gem5/util/m5/build/riscv/out/m5 ./sbin/m5 # replace m5 by the desired workload +``` +After the kernel has started, we have to start Busybox and finalize the system +initialization. We will use a script called `init` that will do the hard work, +and finally starts the workload. +Create `initramfs/init` script with the following content, +``` +#!/bin/busybox sh + +# Make symlinks +/bin/busybox --install -s + +# Mount system +mount -t devtmpfs devtmpfs /dev +mount -t proc proc /proc +mount -t sysfs sysfs /sys +mount -t tmpfs tmpfs /tmp + +# Busybox TTY fix +setsid cttyhack sh + +# https://git.busybox.net/busybox/tree/docs/mdev.txt?h=1_32_stable +echo /sbin/mdev > /proc/sys/kernel/hotplug +mdev -s + +# enter a shell +#sh +# or execute the workload +/sbin/m5 exit # replace with desired workload +``` +Add executable flag: +```sh +chmod +x init +``` +At this stage, your initramfs should look like: +```sh +$ tree +. +├── bin +│ └── busybox +├── dev +│ ├── console +│ ├── null +│ ├── sda +│ ├── tty +│ └── ttyprintk +├── etc +├── home +├── init +├── mnt +├── proc +│ └── sys +│ └── kernel +├── sbin +│ └── m5 +├── sys +├── tmp +└── usr + ├── bin + └── sbin + +15 directories, 8 files +``` +To create the cpio file from the `initramfs` folder, +```sh +mkdir riscv-all-in-one/cpio +cd riscv-all-in-one/initramfs +fakeroot -- find . -print0 | cpio --owner root:root --null -o --format=newc > ../cpio/initramfs.cpio +# alternatively with the tool available in the (previously build) linux kernel +#../linux/usr/gen_initramfs.sh -o ../cpio/initramfs.cpio ./ +lsinitramfs ../cpio/initramfs.cpio # checking the file structure of the created cpio file +``` + +## Step 5. Compiling `Linux Kernel` with a customized `initramfs` +```sh +cd riscv-all-in-one/ +git clone --depth 1 --branch v6.11 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git + +# alternatively downloading tar +wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.11.10.tar.xz +tar xf linux-6.11.10.tar.xz +mv linux-6.11.10 linux + +cd linux +# ?? CFLAGS_KERNEL=" -march=rv64gc" +make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- defconfig +make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- menuconfig +# Go to "General setup --->" +# Check on "Initial RAM filesystem and RAM disk (initramfs/initrd) support" +# Change "Initramfs source file(s)" to the absoblute path of riscv-all-in-one/cpio/initramfs.cpio +make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- all -j$(nproc) +``` +The file of interest is at `arch/riscv/boot/Image`. + +## Step 6. Compiling `OpenSBI` with the Linux kernel as the payload +```sh +cd riscv-all-in-one/ +git clone https://github.com/riscv-software-src/opensbi +cd opensbi +git switch --detach v1.4 +make PLATFORM=generic FW_PAYLOAD_PATH=../linux/arch/riscv/boot/Image CROSS_COMPILE=riscv64-unknown-linux-gnu- -j$(nproc) +``` +The desired bootloader file is at `build/platform/generic/firmware/fw_payload.elf`. + +# Example + +You can run the created bootloader with Linux and Busybox payload using the example riscv `fs_linux.py` config, +```sh +cd gem5 +./build/RISCV/gem5.opt configs/example/riscv/fs_linux.py --kernel="../gem5-resources/src/riscv-fs/riscv-all-in-one/opensbi/build/platform/generic/firmware/fw_payload.elf" +``` +You can check the console output with `telnet` or gem5's `m5term`, +```sh +telnet localhost +# or +cd util/term +make +./m5term localhost +``` From d5bdb872cb7f02c6e8c10a6dfdb6ec90e7f770ec Mon Sep 17 00:00:00 2001 From: Teloecho Date: Tue, 31 Dec 2024 14:28:26 +0100 Subject: [PATCH 2/7] resources: convert to precompiled toolchain version following suggestion of review on PR #61 to use the more convinient precompiled toolchain. self-compiled is useful for modified toolchain, but not required for reproducibility of the standard resource though --- src/riscv-fs/riscv-busybox-opensbi/README.md | 77 ++++++++++---------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/src/riscv-fs/riscv-busybox-opensbi/README.md b/src/riscv-fs/riscv-busybox-opensbi/README.md index 469a57d1..b1b7f67b 100644 --- a/src/riscv-fs/riscv-busybox-opensbi/README.md +++ b/src/riscv-fs/riscv-busybox-opensbi/README.md @@ -36,36 +36,43 @@ riscv-all-in-one/ ``` # Building the resource -## Step 1. Building the `riscv-gnu-toolchain` -In this step, we'll use -[GNU toolchain for RISC-V](https://github.com/riscv-collab/riscv-gnu-toolchain). +## Step 1. Getting the `riscv-gnu-toolchain` -This step is necessary if you do not have basic libraries built for RISCV or -if you're cross-compiling RISCV. +We'll use the precompiled toolchain for Debian 12 (Bookworm) System, +package `g++-12-riscv64-linux-gnu`, version `12.2.0-13cross1`. +Install it by running: ```sh -cd riscv-all-in-one/ -git clone https://github.com/riscv-collab/riscv-gnu-toolchain.git -cd riscv-gnu-toolchain -git switch --detach 20f615317e2ce888dfc11b29ccde4a649494b654 # for reproducability, newer versions should work either -mkdir build -cd build -# --prefix parameter specifying the installation location -# --enable-multilib build either cross-compiler with support for both 32-bit and 64-bit -../configure --prefix=/path/to/rvtoolchain --enable-multilib -make linux -j$(nproc) -``` -To update the PATH environment variable so that the RISCV compilers can be -found, -```sh -export PATH=/path/to/rvtoolchain/bin/:$PATH -``` +sudo apt install g++-12-riscv64-linux-gnu + +# The shipped toolchain version might use weird `-12` suffixes. Setting custom +# toolchain suffixes in the makefiles is cumbersome, therefore link the tools +# to the regular prefix naming scheme. +# (Taken from [riscv-opensbi](src/riscv-fs/riscv-opensbi/build-env.dockerfile)) +sudo su +ln -s /usr/bin/riscv64-linux-gnu-cpp-12 /usr/bin/riscv64-linux-gnu-cpp & \ +ln -s /usr/bin/riscv64-linux-gnu-cpp-12 /usr/bin/riscv64-linux-gnu-cpp & \ +ln -s /usr/bin/riscv64-linux-gnu-g++-12 /usr/bin/riscv64-linux-gnu-g++ & \ +ln -s /usr/bin/riscv64-linux-gnu-gcc-12 /usr/bin/riscv64-linux-gnu-gcc & \ +ln -s /usr/bin/riscv64-linux-gnu-gcc-ar-12 /usr/bin/riscv64-linux-gnu-gcc-ar & \ +ln -s /usr/bin/riscv64-linux-gnu-gcc-nm-12 /usr/bin/riscv64-linux-gnu-gcc-nm & \ +ln -s /usr/bin/riscv64-linux-gnu-gcc-ranlib-12 /usr/bin/riscv64-linux-gnu-gcc-ranlib & \ +ln -s /usr/bin/riscv64-linux-gnu-gcov-12 /usr/bin/riscv64-linux-gnu-gcov & \ +ln -s /usr/bin/riscv64-linux-gnu-gcov-dump-12 /usr/bin/riscv64-linux-gnu-gcov-dump & \ +ln -s /usr/bin/riscv64-linux-gnu-gcov-tool-12 /usr/bin/riscv64-linux-gnu-gcov-tool & \ +ln -s /usr/bin/riscv64-linux-gnu-lto-dump-12 /usr/bin/riscv64-linux-gnu-lto-dump +exit # the root mode +``` + +If you want to build the [GNU toolchain for RISC-V](https://github.com/riscv-collab/riscv-gnu-toolchain) +yourself, use the `--enable-multilib` flag on the `configure` step and `make` the +`linux` target. ## Step 2. Getting and Building `busybox` More information about Busybox is [here](https://www.busybox.net/). ```sh cd riscv-all-in-one/ -git clone --branch 1_36_stable https://git.busybox.net/busybox.git # choose a stable branch +git clone --branch 1_36_stable https://git.busybox.net/busybox.git # alternatively downloading tar wget https://git.busybox.net/busybox/snapshot/busybox-1_36_1.tar.bz2 @@ -74,30 +81,25 @@ mv busybox-1_36_1 busybox cd busybox # create a default configuration -make CROSS_COMPILE=riscv64-unknown-linux-gnu- defconfig -make CROSS_COMPILE=riscv64-unknown-linux-gnu- menuconfig +make CROSS_COMPILE=riscv64-linux-gnu- defconfig +make CROSS_COMPILE=riscv64-linux-gnu- menuconfig # Configure static linking in order to simplify things. # Settings ---> # Build Options ---> # Build static binary (no shared libs) ---> yes -make CROSS_COMPILE=riscv64-unknown-linux-gnu- all -j$(nproc) -make CROSS_COMPILE=riscv64-unknown-linux-gnu- install # optional +make CROSS_COMPILE=riscv64-linux-gnu- all -j$(nproc) +make CROSS_COMPILE=riscv64-linux-gnu- install # optional ``` The files of interest are in `busybox/_install/bin`. ## Step 3. Compiling the Workload (e.g. gem5's m5) -Change to the directory with your clone of gem5 version 24.0.0.1. +Change to the directory with your clone of gem5 version `24.0.0.1`. ```sh cd gem5/ cd util/m5 -scons build/riscv/out/m5 -``` -**Note**: the default cross-compiler is `riscv64-unknown-linux-gnu-`. -To change the cross-compiler, you can set the cross-compiler using the scons -sticky variable `riscv.CROSS_COMPILE`. For example, -```sh scons riscv.CROSS_COMPILE=riscv64-linux-gnu- build/riscv/out/m5 ``` +**Note**: the default cross-compiler is `riscv64-unknown-linux-gnu-`. ## Step 4. Determining the Structure of `initramfs` Your Linux requires a *file system* in order to properly run. So we will @@ -212,13 +214,12 @@ tar xf linux-6.11.10.tar.xz mv linux-6.11.10 linux cd linux -# ?? CFLAGS_KERNEL=" -march=rv64gc" -make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- defconfig -make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- menuconfig +make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfig +make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- menuconfig # Go to "General setup --->" # Check on "Initial RAM filesystem and RAM disk (initramfs/initrd) support" # Change "Initramfs source file(s)" to the absoblute path of riscv-all-in-one/cpio/initramfs.cpio -make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- all -j$(nproc) +make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- all -j$(nproc) ``` The file of interest is at `arch/riscv/boot/Image`. @@ -228,7 +229,7 @@ cd riscv-all-in-one/ git clone https://github.com/riscv-software-src/opensbi cd opensbi git switch --detach v1.4 -make PLATFORM=generic FW_PAYLOAD_PATH=../linux/arch/riscv/boot/Image CROSS_COMPILE=riscv64-unknown-linux-gnu- -j$(nproc) +make CROSS_COMPILE=riscv64-linux-gnu- PLATFORM=generic FW_PAYLOAD_PATH=../linux/arch/riscv/boot/Image -j$(nproc) ``` The desired bootloader file is at `build/platform/generic/firmware/fw_payload.elf`. From 00958ecfc3f2f94a24083147d908a90fbac6b25d Mon Sep 17 00:00:00 2001 From: Teloecho Date: Tue, 31 Dec 2024 14:38:48 +0100 Subject: [PATCH 3/7] resources: formatting and clarifications improvements for PR #61 - fix markdown formatting (blank lines, links, etc.) - clarify comment alternative initramfs.cpio archive generation --- src/riscv-fs/riscv-busybox-opensbi/README.md | 59 +++++++++++++++----- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/src/riscv-fs/riscv-busybox-opensbi/README.md b/src/riscv-fs/riscv-busybox-opensbi/README.md index b1b7f67b..8343da3c 100644 --- a/src/riscv-fs/riscv-busybox-opensbi/README.md +++ b/src/riscv-fs/riscv-busybox-opensbi/README.md @@ -14,16 +14,17 @@ author: ["Jonathan Kretschmer"] # RISC-V Linux Full System Bootloader, initramfs and Workload in One This document provides instructions to create an -(OpenSBI)[https://github.com/riscv-software-src/opensbi] bootloader binary +[OpenSBI](https://github.com/riscv-software-src/opensbi) bootloader binary with Linux kernel image payload containing an initramfs with -(Busybox)[https://www.busybox.net/] that works with gem5 full system simulations. +[Busybox](https://www.busybox.net/) that works with gem5 full system simulations. This guide is inspired by and partly copied from -(riscv-fs-nodisk)[https://github.com/gem5/gem5-resources/blob/stable/src/riscv-fs-alt/riscv-boot-exit-nodisk/README.md] -and (Linux on RISC-V using QEMU and BUSYBOX from scratch)[https://risc-v-machines.readthedocs.io/en/latest/linux/simple/]. +[riscv-fs-nodisk](https://github.com/gem5/gem5-resources/blob/stable/src/riscv-fs-alt/riscv-boot-exit-nodisk/README.md) +and [Linux on RISC-V using QEMU and BUSYBOX from scratch](https://risc-v-machines.readthedocs.io/en/latest/linux/simple/). For this guide we assume following directory structure. Gem5 source itself is required either, but not listed here to avoid duplication. + ``` riscv-all-in-one/ ├── busybox/ # busybox source @@ -35,8 +36,9 @@ riscv-all-in-one/ └── README.md # This README file ``` -# Building the resource -## Step 1. Getting the `riscv-gnu-toolchain` +## Building the resource + +### Step 1. Getting the `riscv-gnu-toolchain` We'll use the precompiled toolchain for Debian 12 (Bookworm) System, package `g++-12-riscv64-linux-gnu`, version `12.2.0-13cross1`. @@ -68,13 +70,15 @@ If you want to build the [GNU toolchain for RISC-V](https://github.com/riscv-col yourself, use the `--enable-multilib` flag on the `configure` step and `make` the `linux` target. -## Step 2. Getting and Building `busybox` +### Step 2. Getting and Building `busybox` + More information about Busybox is [here](https://www.busybox.net/). + ```sh cd riscv-all-in-one/ git clone --branch 1_36_stable https://git.busybox.net/busybox.git -# alternatively downloading tar +# alternatively download a tar archive with the source wget https://git.busybox.net/busybox/snapshot/busybox-1_36_1.tar.bz2 tar xf busybox-1_36_1.tar.bz2 mv busybox-1_36_1 busybox @@ -90,20 +94,26 @@ make CROSS_COMPILE=riscv64-linux-gnu- menuconfig make CROSS_COMPILE=riscv64-linux-gnu- all -j$(nproc) make CROSS_COMPILE=riscv64-linux-gnu- install # optional ``` + The files of interest are in `busybox/_install/bin`. -## Step 3. Compiling the Workload (e.g. gem5's m5) +### Step 3. Compiling the Workload (e.g. gem5's m5) + Change to the directory with your clone of gem5 version `24.0.0.1`. + ```sh cd gem5/ cd util/m5 scons riscv.CROSS_COMPILE=riscv64-linux-gnu- build/riscv/out/m5 ``` + **Note**: the default cross-compiler is `riscv64-unknown-linux-gnu-`. -## Step 4. Determining the Structure of `initramfs` +### Step 4. Determining the Structure of `initramfs` + Your Linux requires a *file system* in order to properly run. So we will prepare the file structure and the `init` script. + ```sh cd riscv-all-in-one/ mkdir initramfs @@ -118,6 +128,7 @@ fakeroot -- mknod -m 622 dev/tty c 5 0 fakeroot -- mknod -m 622 dev/ttyprintk c 5 3 fakeroot -- mknod -m 622 dev/null c 1 3 ``` + **Note:** `mknod -m 622 /dev/tty c 5 0` means we're creating `/dev/tty` with permission of `622`. `c` means a character device being created, `5` is the major number, and `0` is the minor number. More information about the @@ -125,17 +136,22 @@ major/minor numbering is available at (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/devices.txt). Drop the `busybox` executable from the previous section into the filesystem: + ```sh cp ../busybox/busybox ./bin/ ``` + Drop the workload: + ```sh cp /path/to/your/gem5/util/m5/build/riscv/out/m5 ./sbin/m5 # replace m5 by the desired workload ``` + After the kernel has started, we have to start Busybox and finalize the system initialization. We will use a script called `init` that will do the hard work, and finally starts the workload. Create `initramfs/init` script with the following content, + ``` #!/bin/busybox sh @@ -160,11 +176,15 @@ mdev -s # or execute the workload /sbin/m5 exit # replace with desired workload ``` + Add executable flag: + ```sh chmod +x init ``` + At this stage, your initramfs should look like: + ```sh $ tree . @@ -193,22 +213,25 @@ $ tree 15 directories, 8 files ``` + To create the cpio file from the `initramfs` folder, + ```sh mkdir riscv-all-in-one/cpio cd riscv-all-in-one/initramfs fakeroot -- find . -print0 | cpio --owner root:root --null -o --format=newc > ../cpio/initramfs.cpio -# alternatively with the tool available in the (previously build) linux kernel -#../linux/usr/gen_initramfs.sh -o ../cpio/initramfs.cpio ./ +# alternatively with the tool available in the (previously build!) linux kernel +# cd ../linux; ./usr/gen_initramfs.sh -o ../cpio/initramfs.cpio ../initramfs/; lsinitramfs ../cpio/initramfs.cpio # checking the file structure of the created cpio file ``` -## Step 5. Compiling `Linux Kernel` with a customized `initramfs` +### Step 5. Compiling `Linux Kernel` with a customized `initramfs` + ```sh cd riscv-all-in-one/ git clone --depth 1 --branch v6.11 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git -# alternatively downloading tar +# alternatively download a tar archive with the source wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.11.10.tar.xz tar xf linux-6.11.10.tar.xz mv linux-6.11.10 linux @@ -221,9 +244,11 @@ make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- menuconfig # Change "Initramfs source file(s)" to the absoblute path of riscv-all-in-one/cpio/initramfs.cpio make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- all -j$(nproc) ``` + The file of interest is at `arch/riscv/boot/Image`. ## Step 6. Compiling `OpenSBI` with the Linux kernel as the payload + ```sh cd riscv-all-in-one/ git clone https://github.com/riscv-software-src/opensbi @@ -231,16 +256,20 @@ cd opensbi git switch --detach v1.4 make CROSS_COMPILE=riscv64-linux-gnu- PLATFORM=generic FW_PAYLOAD_PATH=../linux/arch/riscv/boot/Image -j$(nproc) ``` + The desired bootloader file is at `build/platform/generic/firmware/fw_payload.elf`. -# Example +## Example You can run the created bootloader with Linux and Busybox payload using the example riscv `fs_linux.py` config, + ```sh cd gem5 ./build/RISCV/gem5.opt configs/example/riscv/fs_linux.py --kernel="../gem5-resources/src/riscv-fs/riscv-all-in-one/opensbi/build/platform/generic/firmware/fw_payload.elf" ``` + You can check the console output with `telnet` or gem5's `m5term`, + ```sh telnet localhost # or From 2cb2179cacf52fa62aaa19c64315849d6a96787c Mon Sep 17 00:00:00 2001 From: Teloecho Date: Thu, 2 Jan 2025 16:54:00 +0100 Subject: [PATCH 4/7] resources: turn into bootloader resource, improve metadata - change permalink and add a tag to highlight nodisk charakter - reorder tags to align with other resource READMEs - describe how to use the resource within the gem5 stdlib framework as a bootloader or kernel passed to set_kernel_disk_workload() - add licensing notes for OpenSBI, Linux and Busybox --- src/riscv-fs/riscv-busybox-opensbi/README.md | 52 +++++++++++++++++--- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/src/riscv-fs/riscv-busybox-opensbi/README.md b/src/riscv-fs/riscv-busybox-opensbi/README.md index 8343da3c..7b3164e2 100644 --- a/src/riscv-fs/riscv-busybox-opensbi/README.md +++ b/src/riscv-fs/riscv-busybox-opensbi/README.md @@ -1,13 +1,14 @@ --- title: RISC-V Full System in One Kernel Resource tags: + - riscv - fullsystem - bootloader - - riscv + - nodisk layout: default -permalink: resources/riscv-fs-busybox-opensbi +permalink: resources/riscv-fs-busybox-opensbi-nodisk shortdoc: > - Resources to build an OpenSBI bootloader with Linux image, initramfs and Busybox that works with gem5 full system simulations. + Resources to build an OpenSBI bootloader with Linux kernel image, initramfs and Busybox that works with gem5 full system simulations. author: ["Jonathan Kretschmer"] --- @@ -17,12 +18,13 @@ This document provides instructions to create an [OpenSBI](https://github.com/riscv-software-src/opensbi) bootloader binary with Linux kernel image payload containing an initramfs with [Busybox](https://www.busybox.net/) that works with gem5 full system simulations. +No extra disk image required by leveraging Linux's early userspace support. This guide is inspired by and partly copied from [riscv-fs-nodisk](https://github.com/gem5/gem5-resources/blob/stable/src/riscv-fs-alt/riscv-boot-exit-nodisk/README.md) and [Linux on RISC-V using QEMU and BUSYBOX from scratch](https://risc-v-machines.readthedocs.io/en/latest/linux/simple/). -For this guide we assume following directory structure. Gem5 source itself is +The instructions assume following directory structure. Gem5 source itself is required either, but not listed here to avoid duplication. ``` @@ -259,13 +261,32 @@ make CROSS_COMPILE=riscv64-linux-gnu- PLATFORM=generic FW_PAYLOAD_PATH=../linux/ The desired bootloader file is at `build/platform/generic/firmware/fw_payload.elf`. -## Example +## Example Run + +You can run the created bootloader with Linux and Busybox payload using the +example config `configs/example/gem5_library/riscv-fs.py` from the gem5 +repository. +Change the passed value of the parameter `kernel` for the +[`board.set_kernel_disk_workload`](https://www.gem5.org/documentation/general_docs/stdlib_api/gem5.components.boards.riscv_board.html) +method call to +`obtain_resource("riscv-fs-busybox-opensbi-nodisk", resource_version="1.0.0")`. +Leave the `disk_image` value as it is or set it to some dummy disk. As it is a +*nodisk* resource the disk image is not used, but it may not be blank or `None` +for the method call unfortunately. +Adding the parameter `bootloader=obtain_resource("riscv-fs-busybox-opensbi-nodisk", resource_version="1.0.0")` +has the overall same effect, however the `kernel` parameter requires some dummy value again. + +```sh +cd gem5/ +./build/RISCV/gem5.opt configs/example/gem5_library/riscv-fs.py +``` -You can run the created bootloader with Linux and Busybox payload using the example riscv `fs_linux.py` config, +For a quick test the `fs_linux.py` config might be helpful. See next code block +for its usage. However [setting up local resources](https://www.gem5.org/documentation/gem5-stdlib/using-local-resources) +is quite straight forward either and preferred for reproducability reasons. ```sh -cd gem5 -./build/RISCV/gem5.opt configs/example/riscv/fs_linux.py --kernel="../gem5-resources/src/riscv-fs/riscv-all-in-one/opensbi/build/platform/generic/firmware/fw_payload.elf" +./build/RISCV/gem5.opt configs/example/riscv/fs_linux.py --kernel="../gem5-resources/src/riscv-fs/riscv-fs-busybox-opensbi-nodisk/opensbi/build/platform/generic/firmware/fw_payload.elf" ``` You can check the console output with `telnet` or gem5's `m5term`, @@ -277,3 +298,18 @@ cd util/term make ./m5term localhost ``` + +## Licensing + +OpenSBI is distributed under the terms of the +[BSD 2-clause license](https://github.com/riscv-software-src/opensbi?tab=License-1-ov-file). + +Linux is released under the GNU General Public License version 2 (GPLv2), but +it also contains several files under other compatible licenses. For more +information about Linux Kernel Copy Right please refer to +[here](https://www.kernel.org/legal.html) and +[here](https://www.kernel.org/doc/html/latest/process/license-rules.html#kernel-licensing). + +Busybox is also released under the GNU General Public License version 2 (GPLv2). +For more information about Busybox Copy Right please refer to +[here](https://busybox.net/license.html). From 7e3abb27f090eb390d2b897fdc6990969b864412 Mon Sep 17 00:00:00 2001 From: Teloecho Date: Thu, 2 Jan 2025 20:08:42 +0100 Subject: [PATCH 5/7] resources: align path names --- src/riscv-fs/riscv-busybox-opensbi/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/riscv-fs/riscv-busybox-opensbi/README.md b/src/riscv-fs/riscv-busybox-opensbi/README.md index 7b3164e2..58e63e2e 100644 --- a/src/riscv-fs/riscv-busybox-opensbi/README.md +++ b/src/riscv-fs/riscv-busybox-opensbi/README.md @@ -35,7 +35,7 @@ riscv-all-in-one/ ├── linux/ # linux source ├── opensbi/ # OpenSBI source, providing a RISC-V bootloader ├── riscv-gnu-toolchain/ # riscv tool chain for cross compilation - └── README.md # This README file + └── README.md # Copy/link of this README file ``` ## Building the resource @@ -286,7 +286,7 @@ for its usage. However [setting up local resources](https://www.gem5.org/documen is quite straight forward either and preferred for reproducability reasons. ```sh -./build/RISCV/gem5.opt configs/example/riscv/fs_linux.py --kernel="../gem5-resources/src/riscv-fs/riscv-fs-busybox-opensbi-nodisk/opensbi/build/platform/generic/firmware/fw_payload.elf" +./build/RISCV/gem5.opt configs/example/riscv/fs_linux.py --kernel="/path/to/your/riscv-all-in-one/opensbi/build/platform/generic/firmware/fw_payload.elf" ``` You can check the console output with `telnet` or gem5's `m5term`, From b634dc84cf1578664e7523f292817a8330863cfe Mon Sep 17 00:00:00 2001 From: Teloecho Date: Thu, 2 Jan 2025 20:10:02 +0100 Subject: [PATCH 6/7] resources: update to version ref to new gem5 release --- src/riscv-fs/riscv-busybox-opensbi/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/riscv-fs/riscv-busybox-opensbi/README.md b/src/riscv-fs/riscv-busybox-opensbi/README.md index 58e63e2e..ae58684e 100644 --- a/src/riscv-fs/riscv-busybox-opensbi/README.md +++ b/src/riscv-fs/riscv-busybox-opensbi/README.md @@ -101,7 +101,7 @@ The files of interest are in `busybox/_install/bin`. ### Step 3. Compiling the Workload (e.g. gem5's m5) -Change to the directory with your clone of gem5 version `24.0.0.1`. +Change to the directory with your clone of gem5 version `24.1.0.1`. ```sh cd gem5/ From 9cb3868e6dd92a05e05773646687190dd878ca6f Mon Sep 17 00:00:00 2001 From: Teloecho Date: Fri, 3 Jan 2025 18:03:30 +0100 Subject: [PATCH 7/7] resources: fix init script to actually exit - move m5 exit to beginning of script and extract shell setup into extra script for better readability - swap setsid,hotplug lines (script doesn't proceed after setsid line) - fix version in busybox docs link --- src/riscv-fs/riscv-busybox-opensbi/README.md | 27 +++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/riscv-fs/riscv-busybox-opensbi/README.md b/src/riscv-fs/riscv-busybox-opensbi/README.md index ae58684e..1b565bb0 100644 --- a/src/riscv-fs/riscv-busybox-opensbi/README.md +++ b/src/riscv-fs/riscv-busybox-opensbi/README.md @@ -156,6 +156,19 @@ Create `initramfs/init` script with the following content, ``` #!/bin/busybox sh +# content of /init + +/sbin/m5 exit # replace with desired workload + +# or install busybox applets and setup shell +#exec /setup_shell # script to execute the workload +``` + +Create `initramfs/setup_shell` script with the following content, + +``` +#!/bin/busybox sh +# content of /setup_shell # Make symlinks /bin/busybox --install -s @@ -166,23 +179,19 @@ mount -t proc proc /proc mount -t sysfs sysfs /sys mount -t tmpfs tmpfs /tmp -# Busybox TTY fix -setsid cttyhack sh - -# https://git.busybox.net/busybox/tree/docs/mdev.txt?h=1_32_stable +# https://git.busybox.net/busybox/tree/docs/mdev.txt?h=1_36_stable echo /sbin/mdev > /proc/sys/kernel/hotplug mdev -s -# enter a shell -#sh -# or execute the workload -/sbin/m5 exit # replace with desired workload +# Busybox TTY fix +setsid cttyhack sh ``` -Add executable flag: +Add executable flags: ```sh chmod +x init +chmod +x setup_shell ``` At this stage, your initramfs should look like: