RISCV gem5 FS(Full System)
21年carrv上新发表的《Supporting RISC-V Full System Simulation in gem5》上为gem5新增加了Full System的配置,有助于帮助RISC-V在gem5上作相关研究。最近也是在学习gem5以及RISCV,在配置环境中遇到了一些问题,自己具体环境也和官方的不太一样,所以记录一下。本文主要描述了怎么在gem5上运行riscv的全系统模拟。
论文参考地址:https://carrv.github.io/2021/papers/CARRV2021_paper_7_Yuen.pdf
官方配置参考地址:https://gem5.googlesource.com/public/gem5-resources/+/refs/heads/develop/src/riscv-fs/
1、说明
提供了创建 riscv 磁盘映像、riscv 引导加载程序 ( berkeley bootloader (bbl)) 的配置说明
附带了 gem5 脚本以运行 riscv Linux 完整系统模拟。引导加载程序bbl也是用 Linux 内核和设备树编译的。
使用的磁盘映像基于busybox和UCanLinux。主要来自这里。
整体的目录结构:
riscv-fs/
|___ gem5/ # gem5 源代码(此处克隆)
|
|___ riscv-disk # 构建的磁盘镜像会放在这里
|
|___ riscv-gnu-toolchain # 交叉编译的riscv工具链
|
|___ riscv64-sample # UCanLinux 源码
| |__linux # linux 源码
| |__busybox # busybox 源码
| |__riscv-pk # riscv 代理内核源码(bbl)
| |__RootFS # 磁盘镜像的根文件系统
|
|
|
|___ README.md # 这个 README 文件
2、RISCV 工具链安装
安装所需的库
# 安装依赖
sudo apt-get install autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev
克隆 riscv gnu 工具链源
# 先创建文件夹
mkdir riscv-fs
cd riscv-fs
git clone https://gitee.com/mirrors/riscv-gnu-toolchain.git
cd riscv-gnu-toolchain
qemu下载比较慢,所以将其去掉
参考了博客:https://blog.csdn.net/yushulx/article/details/108796831
git rm --cached qemu
git submodule update --init --recursive
去掉了qemu的话就不用下面这条命令了,会报错,但是没关系,不影响
git checkout 88b004d4c2a7d4e4f08b17ee32d2
将前缀更改为您的目录
./configure --prefix=/opt/riscv
编译
make linux -j$(nproc)
更新环境变量,在.bashrc中末尾添加下面代码并更新
export PATH=$PATH:/opt/riscv/bin/
3、安装gem5
官方参考https://www.gem5.org/getting_started/
# 返回riscv-fs目录
cd ../
# 这里可以参考一下其他的博客,把原码下载下来,并配置依赖环境
git clone https://gem5.googlesource.com/public/gem5
编译
cd gem5
scons build/RISCV/gem5.opt -j$(nproc)
4、UCanLinux
克隆 UCanLinux source
# 回到riscv-fs目录
cd ../
git clone https://github.com/UCanLinux/riscv64-sample
接下来构建bbl和磁盘映像
4.1 Linux内核
克隆最新的 LTS Linux 内核 (v5.10):
cd riscv64-sample/
git clone --depth 1 --branch v5.10 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
配置和编译内核:
cd linux
从 riscv64-sample 目录复制内核配置(之前克隆的)
cp ../kernel.config .config
配置内核并编译
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- menuconfig
#会进入一个图形界面,直接退出并保存就行,一定要保存!
直接保存并退出。
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- all -j$(nproc)
结果:
这应该在linux目录中生成一个vmlinux。可以在此处下载预先构建的 RISC-V 5.10 linux 内核。
4.2 引导加载程序 (bbl)
要构建引导加载程序,请克隆 RISCV 代理内核 ( pk) 源,这是一个应用程序执行环境,也包含 bbl 源。
# 返回riscv64-sample 目录
cd ../
git clone https://github.com/riscv/riscv-pk.git
cd riscv-pk
mkdir build
cd build
apt-get install device-tree-compiler
编译
../configure --host=riscv64-unknown-linux-gnu --with-payload=../../linux/vmlinux --prefix=/opt/riscv/
make -j$(nproc)
chmod 755 bbl
# optional: strip the bbl binary
riscv64-unknown-linux-gnu-strip bbl
其中make -j$(nproc)结果为
这将在riscv-pk/build目录中生成一个带有 linux 内核的引导加载程序二进制文件bbl。此引导程序二进制文件的预构建副本,可在此处下载 linux 内核。
4.3 Busy Box
克隆并编译busybox:
# 返回 riscv64-sample 目录
cd ../..
git clone git://busybox.net/busybox.git
cd busybox
git checkout 1_30_stable # checkout the latest stable branch
make menuconfig #同样会出来一个图形界面、直接退出保存即可,后面的也一样。
cp ../busybox.config .config # 可选
make menuconfig
make CROSS_COMPILE=riscv64-unknown-linux-gnu- all -j$(nproc)
结果:
make CROSS_COMPILE=riscv64-unknown-linux-gnu- install
4.4 磁盘映像的根文件系统
接下来,我们将设置一个根文件系统:
# 返回 riscv64-sample 目录
cd ../
mkdir RootFS
cd RootFS
# 从 busbybox 复制 linux 工具/二进制文件(上面创建)
cp -a ../busybox/_install/* .
# 从上面编译的 linux 内核安装模块
cd ../linux/
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- INSTALL_MOD_PATH=../RootFS modules_install
#从上面内置的工具链安装库
cd ../RootFS
cp -a /opt/riscv/sysroot/lib .
# 创建空目录
mkdir dev home mnt proc sys tmp va
cd etc/network
mkdir if-down.d if-post-down.d if-pre-up.d if-up.d
# 为 riscv 构建 m5 util 并将其移动到根文件系统 #
cd ../../../../
cd gem5/util/m5
scons build/riscv/out/m5
cp build/riscv/out/m5 ../../../riscv64-sample/RootFS/sbin/
注意:默认的交叉编译器是riscv64-unknown-linux-gnu-. 可以使用 scons加riscv.CROSS_COMPILE更改交叉编译器,例如:
scons riscv.CROSS_COMPILE=riscv64-linux-gnu- build/riscv/out/m5
4.5 磁盘映像
创建一个 512MB 大小的磁盘。
cd ../../../
dd if=/dev/zero of=riscv_disk bs=1M count=512
在磁盘上制作并挂载根文件系统:
mkfs.ext2 -L riscv-rootfs riscv_disk
sudo mkdir /mnt/rootfs
sudo mount riscv_disk /mnt/rootfs
sudo cp -a riscv64-sample/RootFS/* /mnt/rootfs
sudo chown -R -h root:root /mnt/rootfs/
df /mnt/rootfs
sudo umount /mnt/rootfs
磁盘映像riscv_disk已准备好。可以在此处下载预先构建的压缩磁盘映像。
注意:如果创建磁盘映像后需要调整其大小,可以执行以下操作:
e2fsck -f riscv_disk
resize2fs ./riscv_disk 512M
此外,如果需要更改磁盘映像的内容,可以将其挂载为:
mount -o loop riscv_disk /mnt/rootfs[some mount directory]
修改挂载文件位置中的内容,上面的/mnt/rootfs中,
注意:只能新增加新的文件夹,不能修改第一次就现有的
修改完后
umount /mnt/rootfs
5、使用gem5 运行脚本
可以配置 riscv 完整系统并运行模拟的 gem5 脚本在 configs/example/riscv中。主要脚本fs_linux.py需要以下参数:
bbl:带有内核的 bbl(berkeley bootloader)二进制文件(位于riscv64-sample/riscv-pk/build/bbl)
disk:要使用的磁盘映像的路径(位于riscv64-sample/riscv_disk)。
atomiccpu_type : cpu 模型。
num_cpus: cpu 核数。
此脚本的示例用法如下:
./build/RISCV/gem5.opt configs/example/riscv/fs_linux.py --kernel=../riscv64-sample/riscv-pk/build/bbl --disk-image=../riscv64-sample/riscv_disk --cpu-type=AtomicSimpleCPU -n=1
结果:
注意其中的端口:system.platform.terminal: Listening for connections on port 3456, 不是下面那个7000
要与模拟系统的控制台进行交互,您可以使用telnet,
telnet localhost 3456
会出现:
按下 crtl+] 后会出现
telnet>
等两秒按下回车,再等一会就成功了:
另一种选择是使用gem5提供的m5term。
cd gem5/util/term
make # compiling
./m5term localhost <port> # launching the terminal
基于此配置的默认 linux 系统具有login和password,两个都是root