For running any riscv based linux on gem5, you need to install dependencies and build gem5.
sudo apt install \
build-essential \
git \
m4 \
scons \
zlib1g \
zlib1g-dev \
libprotobuf-dev \
protobuf-compiler \
libprotoc-dev \
libgoogle-perftools-dev \
python3-dev \
python3-six \
python-is-python3 \
libboost-all-dev \
pkg-config
git clone https://github.com/gem5/gem5
cd gem5
scons build/RISCV/gem5.opt -j$(nproc)
Download prebuilt ucanlinux riscv disk image from here:
dist.gem5.org/dist/v22-1/images/riscv/busybox/riscv-disk.img.gz
Download prebuilt bootloader from here:
https://github.com/UCanLinux/riscv64-sample/blob/master/bbl
or here:
http://dist.gem5.org/dist/v22-1/kernels/riscv/static/bootloader-vmlinux-5.10
Extract the riscv disk image riscv-disk.img.gz.
In a terminal run disk image and the bootloader as an example:
gem5/build/RISCV/gem5.opt \
gem5/configs/example/riscv/fs_linux.py \
--caches --l1i_size=16kB --l1d_size=16kB \
--l2cache --l2_size=256kB \
--mem-type=DDR4_2400_8x8 \
--mem-size=1GB \
--cpu-type=TimingSimpleCPU \
--kernel=riscv-imgs/ucanlinux/bbl \
--disk-image=riscv-imgs/ucanlinux/riscv-disk.imgAfter running via gem5, you can control and see the boot process by connecting to default port 3456.
Either you can connect via telnet:
telnet localhost 3456or after building (one time) m5term, you can connect via it:
cd gem5/util/term
makegem5/util/term/m5term localhost 3456Download prebuilt fedora riscv disk image from here:
https://fedorapeople.org/groups/risc-v/disk-images
Download prebuilt bootloader from here:
https://github.com/UCanLinux/riscv64-sample/blob/master/bbl
or here:
http://dist.gem5.org/dist/v22-1/kernels/riscv/static/bootloader-vmlinux-5.10
Extract the riscv disk image stage4-disk.img.xz:
xz -d -v stage4-disk.img.xzIn a terminal run disk image and the bootloader as an example:
gem5/build/RISCV/gem5.opt \
gem5/configs/example/riscv/fs_linux.py \
--caches --l1i_size=16kB --l1d_size=16kB \
--l2cache --l2_size=256kB \
--mem-type=DDR4_2400_8x8 \
--mem-size=1GB \
--cpu-type=TimingSimpleCPU \
--kernel=riscv-imgs/fedora/bbl \
--disk-image=riscv-imgs/fedora/stage4-disk.imgAfter running via gem5, you can control and see the boot process by connecting to default port 3456.
Either you can connect via telnet:
telnet localhost 3456or after building (one time) m5term, you can connect via it:
cd gem5/util/term
makegem5/util/term/m5term localhost 3456Download bootloader image from here: http://dist.gem5.org/dist/v22-1/kernels/riscv/static/bootloader-vmlinux-5.10
Download riscv64 linux image from here: https://cdimage.ubuntu.com/releases/22.04.3/release/ubuntu-22.04.3-preinstalled-server-riscv64+unmatched.img.xz
Extract the disk image ubuntu-22.04.3-preinstalled-server-riscv64+unmatched.img.xz:
xz -d -v ubuntu-22.04.3-preinstalled-server-riscv64+unmatched.img.xzTo boot ubuntu, either you can use riscv_linux.py python script by setting kernel and disk_image paths of the downloaded images:
build/RISCV/gem5.opt ./riscv_linux.pyor you can also use command line that does same thing exactly as script:
gem5/build/RISCV/gem5.opt \
gem5/configs/example/riscv/fs_linux.py \
--caches --l1i_size=16kB --l1d_size=16kB \
--l2cache --l2_size=256kB \
--mem-type=DDR4_2400_8x8 \
--mem-size=3GB \
--cpu-type=TimingSimpleCPU \
--kernel=riscv-imgs/ubuntu/bootloader-vmlinux-5.10 \
--disk-image=riscv-imgs/ubuntu/ubuntu-22.04.3-preinstalled-server-riscv64+unmatched.img \
--command-line="console=ttyS0 root=/dev/vda1 ro"In the above command the most important thing is root=/dev/vda1 part in command-line flag and also root_partition=1 parameter in riscv_linux.py. Default root partition is 0 and if you do not set this flag, either in the script or command line, ubuntu cannot boot like other os images.
For booting any os image you can determine the root partition via fdisk -l <your-disk-image> command. Here is an example:
shc@karpuz:~/projects/imgextract$ fdisk -l ./ubuntu.img
Disk ./ubuntu.img: 4,5 GiB, 4831838208 bytes, 9437184 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 1FFAD53A-DA06-4DAA-96B2-7D6029A8F4E0
Device Start End Sectors Size Type
./ubuntu.img1 235520 9437150 9201631 4,4G Linux filesystem
./ubuntu.img12 227328 235519 8192 4M Linux filesystem
./ubuntu.img13 34 2081 2048 1M HiFive FSBL
./ubuntu.img14 2082 10239 8158 4M HiFive BBL
./ubuntu.img15 10240 227327 217088 106M EFI System
Partition table entries are not in disk order.As you can see above, Linux filesystem (the one with biggest size) shows in device ubuntu.img 1 and 1 indicates that root_partition= 1 or in the other words root should be mounted at dev/vda 1. (It was 0 (dev/vda) for other os images I mentioned above.)
Is same like others, I mentioned above.
If you want to edit any disk image and place your own files, either you can use qemu, boot the os and e.g. copy your files from host with scp command:
Install qemu:
sudo apt install qemu-system-misc opensbi u-boot-qemu qemu-utilsRun qemu with your disk image:
qemu-system-riscv64 \
-machine virt \
-nographic \
-m 16384 \
-smp 8 \
-bios /usr/lib/riscv64-linux-gnu/opensbi/generic/fw_jump.elf \
-kernel /usr/lib/u-boot/qemu-riscv64_smode/uboot.elf \
-device virtio-net-device,netdev=eth0 \
-netdev user,id=eth0,hostfwd=tcp::5555-:22 \
-drive file=myubuntu.img,format=raw,if=virtioFor example, copy your file from host:
scp -P 5555 /home/shc/myfile ubuntu@localhost:/home/ubuntuthen exit from qemu, now your disk image is modified and you can boot your disk image as I explained for e.g. ubuntu, and you can see your file on running gem5 system.
OR
easily you can mount disk image, edit and unmount it:
Look for partitions with fdisk -l <your-disk-image> command. Look for start addresses of them;
if there is not then your offset is 0 and mount as:
mkdir mnt
sudo mount -o loop ./your-disk-image ./mntThen edit system files in mnt directory, if you cannot, use sudo chmod 777 <file-to-be-edit> command or for all sudo chmod -R 777 ./mnt.
If you see as given example for ubuntu, look for linux filesystem start address which is 235520 in the example. Now, multiply the address with 512 and your offset is should be 512 * 235520 = 120586240 and mount as:
mkdir mnt
sudo mount -o loop,offset=120586240 ./your-disk-image ./mntThen edit the files in mnt directory.
Lastly, unmount your image:
sudo umount ./mntNow your disk image is modified and you can boot your disk image as I explained for e.g. ubuntu, and you can see your file on running gem5 system.