Ubuntu-20.04 gem5 构建并实现一个简单的配置脚本

参考资料:

【计算机体系结构】gem5模拟器入门

https://www.gem5.org/documentation/learning_gem5/part1/simple_config/

gem5在建立一个简单例子的代码解析及一些问题的解答

1. 下载系统安装包

1)由于公司电脑不能联网,所以在VMware16 Ubuntu-20.04 中将需要 sudo apt-get install 的包下载至 offline-packages/ 文件夹,然后再在公司电脑进行离线安装

复制代码
# 创建下载目录
mkdir ~/offline-packages
cd ~/offline-packages

# 下载所有包及依赖
sudo apt-get download $(apt-cache depends --recurse --no-recommends --no-suggests \
  --no-conflicts --no-breaks --no-replaces --no-enhances \
  --no-pre-depends build-essential git m4 scons zlib1g zlib1g-dev \
  libprotobuf-dev protobuf-compiler libprotoc-dev libgoogle-perftools-dev \
  python3-dev python-is-python3 libboost-all-dev pkg-config | \
  grep "^\w" | sort -u)

# 打包所有文件
cd ~
tar -czvf offline-packages.tar.gz offline-packages/

并且 gcc 也需要安装(Ubuntu-20.04默认gcc是9.4.0版本)

gem5:

**We support GCC Versions >=10, up to GCC 13**

复制代码
# 首先添加PPA源
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt update

# 创建单独的目录用于gcc-11相关包
mkdir ~/gcc11-packages
cd ~/gcc11-packages

# 方法1:直接下载指定包
sudo apt-get download gcc-11 g++-11

# 方法2:下载所有相关依赖(更完整)
sudo apt-get download $(apt-cache depends --recurse --no-recommends --no-suggests \
  --no-conflicts --no-breaks --no-replaces --no-enhances \
  --no-pre-depends gcc-11 g++-11 | grep "^\w" | sort -u)

2)下载gem5工程

复制代码
git clone https://gitee.com/koverlu/gem5.git

2. 离线安装

1)将 gem5 工程和 offline-packages/ 文件夹拷贝至目标机器的与虚拟机同名文件夹下

/home/zx/Download/

2)进入 offline-packages/ 安装 .deb

复制代码
tar -zxvf offline-packages.tar.gz offline-packages/
cd ./offline-packages/ 
sudo dpkg -i *amd64.deb

注意:这里如果全部安装:sudo dpkg -i *.deb 就会造成错误:

dpkg-query: 错误: 文件 /usr/lib/systemd/catalog 和软件包 systemd:i386 有重复的文件触发关注

执行:dpkg --print-architecture 的输出是 amd64

执行:dpkg --print-foreign-architectures 的输出是 i386

说明之前执行了:sudo dpkg --add-architecture i386,支持多架构,

所以将所有*.deb都安装就会两种架构的包都安装,造成冲突。

如果造成了冲突:dpkg-query: 错误: 文件 /usr/lib/systemd/catalog 和软件包 systemd:i386 有重复的文件触发关注,解决办法就是到目录/var/lib/dpkg中, 删除trigger文件夹(如果不这样,当安装其它程序时,总是提示上述错误,无法更新和使用 apt-get -f install ),再重新执行:sudo dpkg -i *amd64.deb,只安装支持amd64架构的包。

3)查看gcc版本

复制代码
gcc --versioni
g++ -- version

# 如果版本不正确 查看gcc-11 g++-11是否安装成功
ls /usr/bin/gcc*
# 如果有gcc-11 就软连接默认gcc-11版本
sudo rm /usr/bin/cpp /usr/bin/gcc /usr/bin/g++
sudo ln -s /usr/bin/cpp-11 /usr/bin/cpp
sudo ln -s /usr/bin/gcc-11 /usr/bin/gcc
sudo ln -s /usr/bin/g++-11 /usr/bin/g++

4)查看python版本

复制代码
python --version
python3 --version

# 如果python3的版本还是2.7 
# 安装python3.8进行软连接
sudo ln -sf /etc/alternatives/python /usr/bin/python
sudo ln -sf /etc/alternatives/python3 /usr/bin/python3

3. 构建gem5模拟器

可以先执行:lscpu 查看cpu的数量,例如我的是32个,所以进入gem5工程文件夹后,构建gem5时可修改cpu数为32

复制代码
cd ../gem5/
scons build/X86/gem5.opt -j32

构建完成后,终端的最后两行是

复制代码
...
 [    LINK]  -> ALL/gem5.opt
scons: done building targets.

4. 实现一个简单的配置脚本

python 复制代码
cat > ./configs/simple.py << 'EOF'
#!/usr/bin/env python3
#导入m5和SimObjects
import m5
from m5.objects import *
 
#创建要模拟的系统
system = System()
#设置系统时钟。1、建立时钟域,2、设置时钟频率,3、为时钟域指定电压域
system.clk_domain = SrcClockDomain()
system.clk_domain.clock = '1GHz'
system.clk_domain.voltage_domain = VoltageDomain()
 
#设置系统模拟内存(计时模式),设置内存范围
system.mem_mode = 'timing'
system.mem_ranges = [AddrRange('512MB')]
 
#创建CPU(基于时间),
system.cpu = TimingSimpleCPU()
 
#创建系统范围内存总线
system.membus = SystemXBar()
 
#将CPU上的缓存端口连接到内存总线上。由于没有建立缓存cache,所以将icache和dcache直接连接到menbus
system.cpu.icache_port = system.membus.cpu_side_ports
system.cpu.dcache_port = system.membus.cpu_side_ports
 
#连接CPU的其他端口以确保系统可以正常工作,例如I/O控制器。
system.cpu.createInterruptController()
#将系统的一个特殊端口连接到menbus,这个端口只允许系统读写内存。
system.system_port = system.membus.cpu_side_ports
 
#x86的特定要求,将PIO和中断端口连接到内存总线
if m5.defines.buildEnv['TARGET_ISA'] == "x86":
    system.cpu.interrupts[0].pio = system.membus.mem_side_ports
    system.cpu.interrupts[0].int_requestor = system.membus.cpu_side_ports
    system.cpu.interrupts[0].int_responder = system.membus.mem_side_ports
 
#创建一个内存控制器,并将其连接到内存总线。这里使用的是DDR3控制器,负责内存的范围。
system.mem_ctrl = MemCtrl()
system.mem_ctrl.port = system.membus.mem_side_ports
system.mem_ctrl.dram = DDR3_1600_8x8()
system.mem_ctrl.dram.range = system.mem_ranges[0]
 
#---------设置CPU执行的进程--------------------#
#这里使用syscall仿真模式
#1、设置可执行文件,2、创建进程,设置进程执行的可执行文件,
# 3、将进程设置为CPU的工作负载,4、在CPU上创建进程(或者说创建执行环境)
binary = 'tests/test-progs/hello/bin/x86/linux/hello'
 
#对于gem5 v21及更高版本,加入下面一行。
system.workload = SEWorkload.init_compatible(binary)
 
process = Process()
process.cmd = [binary]
system.cpu.workload = process
system.cpu.createThreads()
 
#---------实例化系统并执行-------------#
#创建根对象,并实例化模拟
root = Root(full_system = False,system = system)
m5.instantiate()
 
#开始模拟。这里的print不是语句而是作为一个函数被调用。
print("Beginning simulation")
exit_event = m5.simulate()
 
#模拟结束后对系统进行检测
print('Exiting @ tick {} because {}'
    .format(m5.curTick(),exit_event.getCause()))
 
EOF

执行

bash 复制代码
build/X86/gem5.opt configs/simple.py 

终端输出:Hello world!

相关推荐
且从容.3 小时前
ubuntu安装flink
linux·ubuntu·flink
爱和冰阔落4 小时前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
程序员沉梦听雨4 小时前
WSL2的安装与使用
linux·wsl
微小的鱼5 小时前
Linux的渲染与显示系统链路
android·java·linux
lisanmengmeng5 小时前
alertmanger 标签 rules 打上分组标签
linux·运维·服务器
Android系统攻城狮6 小时前
Linux FFmpeg深度解析之av_write_frame调用流程与实战(三十三)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
jktantan6 小时前
注解式脱敏:用 Jackson 的 ContextualSerializer 做字段级策略(一)
spring boot·后端·算法·spring cloud·系统架构
Linux-lucky17 小时前
45-Linux学习之旅之防火墙与WEB加固
linux·前端·网络·学习·ubuntu
禁默18 小时前
启元 Q1 二次开发实践:Ubuntu 部署与仿真验证,从 PrimeConsole 到 ROS 2 Humble + RViz
linux·运维·ubuntu
skywalk816318 小时前
把 去也网站 从 Ubuntu 搬到 FreeBSD:一次 Service Jail + nginx 的部署实录
linux·运维·nginx·ubuntu·freebsd