使用 gem5

gem5 中的全系统模拟


我们将介绍的内容


什么是全系统模拟?

全系统模拟是一种模拟完整计算机系统的仿真类型,包括 CPU、内存、I/O 设备以及操作系统等系统软件。

它允许对硬件和软件交互进行详细分析和调试。

模拟的组件


在 gem5 中启动真实系统的基础知识

概述:gem5 可以模拟真实系统的启动过程,提供对启动期间硬件和软件行为的深入洞察。

涉及的步骤

  1. 设置模拟环境
    • 选择 ISA(例如,x86、ARM)。
    • 配置系统组件(CPU、内存、缓存)。
  2. 获取正确的资源,如内核、引导加载程序、磁盘镜像等。
  3. 配置启动参数
    • 如有必要,设置内核命令行参数。
  4. 运行模拟
    • 启动模拟并监控启动过程。

让我们在 gem5 中运行全系统模拟

不完整的代码已经构建了一个板子。

让我们在 gem5 中运行全系统工作负载。

这个工作负载是 Ubuntu 24.04 启动。它将在以下三个时间点触发 m5 退出:


获取工作负载并设置退出事件

要设置工作负载,我们将以下内容添加到 materials/02-Using-gem5/07-full-system/x86-fs-kvm-run.py

workload = obtain_resource("x86-ubuntu-24.04-boot-with-systemd", resource_version="1.0.0")
board.set_workload(workload)

获取工作负载并设置退出事件(续)

让我们创建退出事件处理器,并将其设置到我们的模拟器对象中。

def exit_event_handler():
    print("first exit event: Kernel booted")
    yield False
    print("second exit event: In after boot")
    yield False
    print("third exit event: After run script")
    yield True

simulator = Simulator(
    board=board,
    on_exit_event={
        ExitEvent.EXIT: exit_event_handler(),
    },
)
simulator.run()

使用 m5term 查看终端/串口输出

在启动此工作负载之前,让我们构建 m5term 应用程序,以便我们可以连接到正在运行的系统。

cd /workspaces/2024/gem5/util/term
make

现在您有了一个 m5term 二进制文件。


查看 gem5 的输出

现在,让我们运行工作负载并使用 m5term 连接到磁盘镜像启动的终端。

使用以下命令运行 gem5:

gem5 x86-fs-kvm-run.py

在另一个终端窗口中,运行以下命令以连接到磁盘镜像启动的终端:

m5term 3456

3456 是终端运行的端口号。 您将在 gem5 输出中看到此信息。

如果您运行多个 gem5 实例,它们将具有连续的端口号。 如果您在非交互式环境中运行,将没有端口可以连接。


创建您自己的磁盘镜像


使用 Packer 和 QEMU 创建磁盘镜像

为了创建一个可以在 gem5 中使用的通用 Ubuntu 磁盘镜像,我们将使用:

gem5 resources 已经有代码可以使用上述方法创建通用 Ubuntu 镜像。

让我们浏览创建过程的重要部分。


获取 ISO 和 user-data 文件

由于我们使用 Ubuntu autoinstall,我们需要一个实时服务器安装 ISO。

我们还需要 user-data 文件,它将告诉 Ubuntu autoinstall 如何安装 Ubuntu。


如何获取我们自己的 user-data 文件

要从头开始获取 user-data 文件,您需要在机器上安装 Ubuntu。

您可以在自己的 VM 上安装 Ubuntu 并获取 user-data 文件。


使用 QEMU 获取 user-data 文件

我们也可以使用 QEMU 安装 Ubuntu 并获取上述文件。

qemu-system-x86_64 -m 2G \
      -cdrom ubuntu-22.04.2-live-server-amd64.iso \
      -boot d -drive file=ubuntu-22.04.2.raw,format=raw \
      -enable-kvm -cpu host -smp 2 -net nic \
      -net user,hostfwd=tcp::2222-:22

安装 Ubuntu 后,我们可以使用 ssh 获取 user-data 文件。


Packer 脚本的重要部分

让我们浏览 Packer 文件。


Packer 脚本的重要部分(续)


让我们使用基础 Ubuntu 镜像创建包含 GAPBS 基准测试的磁盘镜像

更新 x86-ubuntu.pkr.hcl 文件。

Packer 文件的一般结构将相同,但有一些关键更改:


iso_checksum 是我们正在使用的 iso 文件的 sha256sum。要获取 sha256sum,请在 linux 终端中运行以下命令。

sha256sum ./x86-ubuntu-24-04.gz
"<wait30>",
"gem5<enter><wait>",
"12345<enter><wait>",
"sudo mv /etc/netplan/50-cloud-init.yaml.bak /etc/netplan/50-cloud-init.yaml<enter><wait>",
"12345<enter><wait>",
"sudo netplan apply<enter><wait>",
"<wait>"

对后安装脚本的更改

对于此后安装脚本,我们需要获取依赖项并构建 GAPBS 基准测试。

将此添加到 post-installation.sh 脚本

git clone https://github.com/sbeamer/gapbs
cd gapbs
make

让我们运行 Packer 脚本并在 gem5 中使用此磁盘镜像!

cd /workspaces/2024/materials/02-Using-gem5/07-full-system
x86-ubuntu-gapbs/build.sh

让我们在 gem5 中使用我们构建的磁盘镜像

让我们将 md5sum 和路径添加到我们的 local JSON

让我们运行 gem5 GAPBS config

GEM5_RESOURCE_JSON_APPEND=./completed/local-gapbs-resource.json gem5 x86-fs-gapbs-kvm-run.py

此脚本应该运行 bfs 基准测试。


让我们看看如何使用 m5term 访问终端

让我们将最后一个 yield True 更改为 yield False,这样模拟就不会退出,我们可以访问模拟。

def exit_event_handler():
    print("first exit event: Kernel booted")
    yield False
    print("second exit event: In after boot")
    yield False
    print("third exit event: After run script")
    yield False

再次,让我们使用 m5term

现在让我们使用 m5term 二进制文件连接到我们的模拟

m5term 3456