gem5 system emulation 模式,内部实现了对system call的模拟,使用了一段时间后,有一些发现: 如果使用spec2017 x86编译,那么会存在对intel比较新的指令不支持的问题;后来使用gcc march k6 m32来解决,即使用amd的k6 32bit编译,但是这也只是权宜之计 ;
gem5的开发人员在邮件list中介绍intel对gem5的译码支持比较差,最开始gem5的x86也是基于amd的 ;
很多论文中使用了arm架构,gem5的开发人员也和arm合作比较紧密,所以gem5对arm架构的指令支持比较好 ;
即使使用上面的方法,se模式还是会遇到gem5没有模拟的system call函数的问题
同时还会遇到环境的问题,比如549.fotonik3d,需要手动将input输入的压缩文件obj.dat.xz手动解压之后才能运行。
因为上述的问题,在邮件list中可以看出gem5的开发人员比较倾向于使用full system模式,用他的话就是works magically。
x86 full system
如果是基于x86 ubuntu系统模拟gem5 arch,制作disk image比较简单,可以git clone gem5 resource, 在spec2017文件夹下放入spec2017.iso,调用build.sh自动调用packer将spec2017装入ubuntu的disk image生成spec-2017。
./build/x86/gem5.fast --outdir=./m5out/ configs/example/gem5_library/x86-spec-cpu2017-benchmarks.py --image=path/spec-2017 --benchmark=505.mcf_r --size=ref --partition=1
这里需要强调的是,gem5中介绍了多次qemu-kvm, 但是qemu-kvm并不是在x86架构中生成disk image和真正运行gem5时必须的工具。
在gem5中引入它的主要作用就是在boot阶段使用qemu,在真实的cpu上运行boot 阶段,进行加速,实际上如果我们在云服务器上跑,如果没有qemu软件或者权限,只是使用atomic cpu跑boot也是比较快的。
就是不要被qemu迷惑,fullsystem gem5可以理解成在gem5上跑app,不过这个app是os,单纯的用atomic cpu跑也没有任何问题。
arm full system
x86 full system的问题是memory最大支持3gb,目前看gem5的设置是不支持5gb 6gb这样的设置。
我们介绍一下如何生成gem5的disk image。
首先看一下最终成功运行full system 使用的指令:
./build/arm/gem5.fast -d ./m5out/arm/fullsystem64/spec2017 ./configs/example/fs.py --kernel 2022/binaries/vmlinux.arm64 --disk-image path/expanded-aarch64-ubuntu-trusty-headless.img --bootloader 2022/binaries/boot.arm64 --mem-type=ddr4_2400_4x16 --param 'system.highest_el_is_64 = true' --script=./m5out/arm/fullsystem64/spec2017_restore/spec2017.rcs kernel 我的理解就是os内核程序,disk image则是装载了benchmark的磁盘镜像。
内核程序与我们无关,我们可以直接使用,disk image 则需要我们手动装载。
gem5官方提供的kernel和disk image https://www.gem5.org/documentation/general_docs/fullsystem/guest_binaries
script这里指定的是一个script
#!/bin/bashsource /root/.bashrc/sbin/m5 checkpoint 1echo a real multi node workload might start here ...cd /home/gem5/spec2017source shrcecho reset stats/sbin/m5 resetstatsruncpu --size test --iterations 1 --config myconfig.aarch64.cfg --nobuild 605.mcf_s/sbin/m5 exit 1 通过指定这个script,gem5在boot成功后,运行这个script,就调用了脚本内的runcpu,自动运行了spec2017对应的app。
如果我们不指定这个script,并且不对disk image进行任何修改,那么boot成功后,要求输入用户名和密码,输入root可以进入,不过这个操作比较麻烦,还是建议指定script。
现在唯一需要的工作就是实现disk image,这里帮助对我很大的是这篇博客。https://www.eecg.utoronto.ca/~elsayed9/website/blog/gem5_fs_arm_flow.php 首先遇到的问题就是官方提供的image 1gb或者2gb,然而spec2017有4gb我们需要对image进行扩容。按照博客的操作如下
```bash$ # backup the original disk image if needed$ cp aarch64-ubuntu-trusty-headless.img expanded-aarch64-ubuntu-trusty-headless.img$ # increase disk image by 2g$ dd if=/dev/zero bs=1g count=2 >> expanded-aarch64-ubuntu-trusty-headless.img$ sudo parted expanded-aarch64-ubuntu-trusty-headless.img resizepart 1 100%$ # parse some info for 'losetup' and 'mount' later$ name=$(sudo fdisk -l expanded-aarch64-ubuntu-trusty-headless.img | tail -1 | awk -f: '{ print $1 }' | awk -f '{ print $1 }')$ start_sector=$(sudo fdisk -l expanded-aarch64-ubuntu-trusty-headless.img | grep $name | awk -f '{ print $2 }')$ units=$(sudo fdisk -l expanded-aarch64-ubuntu-trusty-headless.img | grep units | awk -f '{ print $8 }')$ # attach to device and record output, to me it was /dev/loop18 $ sudo losetup -f --show expanded-aarch64-ubuntu-trusty-headless.img -o $(($start_sector*$units)) $ sudo e2fsck -f /dev/loop18 # fix potential errors, press y for all fixes$ sudo resize2fs /dev/loop18 # actual resizing step$ sudo e2fsck -f /dev/loop18 # double check there are no error$ sudo losetup -d /dev/loop18 # detach from the loop device$ # mount image and check new size$ mkdir disk_mnt$ sudo mount -o loop,offset=$(($start_sector*$units)) expanded-aarch64-ubuntu-trusty-headless.img disk_mnt$ df -h # should show the new expanded image size with the used and avail for disk_mnt$ sudo umount disk_mnt
扩容之后mount image,就可以安装spec2017到这个disk image了。
这里建议看一下 gem5-resources/src/spec-2017/disk-image/spec-2017/install-spec2017.sh 这个是装载spec2017到x86 os的过程,我们装载spec2017到arm,可以按照这个流程来。
gem5 resources的路径https://gem5.googlesource.com/public/gem5-resources sudo chroot . #将当前mount目录切换为主目录 创建/home/gem5/文件夹 将cpu_spec2017.iso拷贝到这个文件夹 按照cpu_spec2017.iso的install流程,mount cpu_spec2017.iso 然后install.sh install 之后,我们可以build,生成spec2017的可执行文件等。建议参考install-spec2017.sh disk image中已经有gcc aarch64的编译工具,因此我们不需要额外再安装gcc aarch64,还是比较方便的。 我们将spec2017安装到了/home/gem5/,再结合一下刚才介绍的spec2017.rcs,就能看出来这个script的作用实际上就是进入文件夹,然后runcpu。
我们看一下gem5成功boot后运行spec2017的os系统界面 ,这个界面通过./util/term/m5term 得到,后面会介绍。
[ 0.345190] sd 00 [sda] attached scsi disk[ 0.352995] ext4-fs (sda1): mounted filesystem without journal. opts: (null)[ 0.353004] vfs: mounted root (ext4 filesystem) on device 8:1.[ 0.353626] devtmpfs: mounted[ 0.353684] freeing unused kernel memory: 448k[ 0.359059] random: fast init donemount failed for selinuxfs on /sys/fs/selinux: no such file or directory[ 0.372646] random: init: uninitialized urandom read (12 bytes read)[ 0.399519] random: mountall: uninitialized urandom read (12 bytes read)boot success reset statsrun 602.gcc_s testspec cpu(r) 2017 benchmark suitescopyright 1995-2017 standard performance evaluation corporation (spec)runcpu v5825using 'linux-aarch64' toolsreading file manifests... read 32270 entries from 2 files in 0.44s (72680 files/s)loading runcpu modules.................locating benchmarks...found 47 benchmarks in 53 benchsets.reading config file '/home/gem5/spec2017/config/myconfig.aarch64.cfg'1 configuration selected: action run mode workload report type benchmarks-------- -------- -------- ----------------- --------------------------validate speed test specspeed2017_int 602.gcc_s -------------------------------------------------------------------------------setting up environment for running 大约1billion指令之后,大约半小时,完成boot。再执行3.5billion的指令进入真实的runcpu仿真。gem5仿真显示的界面:**** real simulation ****build/arm/dev/arm/rv_ctrl.cc:176: warn: screg: access to unknown device dcc0pos0dev0build/arm/arch/arm/insts/pseudo.cc:172: warn: instruction 'csdb' unimplementedbuild/arm/dev/arm/gic_v2.cc:683: warn: gic aprn write ignored because not implemented: 0xd0build/arm/dev/arm/gic_v2.cc:683: warn: gic aprn write ignored because not implemented: 0xd4build/arm/dev/arm/gic_v2.cc:683: warn: gic aprn write ignored because not implemented: 0xd8build/arm/dev/arm/gic_v2.cc:683: warn: gic aprn write ignored because not implemented: 0xdcatomiccpu 0 at 103419026000 tid[0] 100000000 instructions are executed.build/arm/dev/arm/rv_ctrl.cc:122: warn: tried to read realview i/o at offset 0x60 that doesn't existbuild/arm/dev/arm/rv_ctrl.cc:122: warn: tried to read realview i/o at offset 0x48 that doesn't existbuild/arm/dev/arm/rv_ctrl.cc:198: warn: tried to write rvio at offset 0xa8 (data 0) that doesn't existbuild/arm/dev/arm/rv_ctrl.cc:198: warn: tried to write rvio at offset 0xa8 (data 0) that doesn't existbuild/arm/dev/arm/rv_ctrl.cc:198: warn: tried to write rvio at offset 0xa8 (data 0) that doesn't existbuild/arm/dev/arm/rv_ctrl.cc:198: warn: tried to write rvio at offset 0xa8 (data 0) that doesn't existbuild/arm/dev/arm/rv_ctrl.cc:198: warn: tried to write rvio at offset 0xa8 (data 0) that doesn't existbuild/arm/dev/arm/rv_ctrl.cc:198: warn: tried to write rvio at offset 0xa8 (data 0) that doesn't existbuild/arm/dev/arm/rv_ctrl.cc:198: warn: tried to write rvio at offset 0xa8 (data 0) that doesn't existbuild/arm/dev/arm/rv_ctrl.cc:198: warn: tried to write rvio at offset 0xa8 (data 0) that doesn't existbuild/arm/dev/arm/rv_ctrl.cc:198: warn: tried to write rvio at offset 0xa8 (data 0) that doesn't existbuild/arm/dev/arm/rv_ctrl.cc:198: warn: tried to write rvio at offset 0xa8 (data 0) that doesn't existbuild/arm/dev/arm/rv_ctrl.cc:122: warn: tried to read realview i/o at offset 0x8 that doesn't existbuild/arm/dev/arm/rv_ctrl.cc:122: warn: tried to read realview i/o at offset 0x48 that doesn't existbuild/arm/dev/arm/energy_ctrl.cc:77: warn: energyctrl: disabled handler, ignoring read from reg 0atomiccpu 0 at 437185231000 tid[0] 200000000 instructions are executed.atomiccpu 0 at 499727384000 tid[0] 300000000 instructions are executed.atomiccpu 0 at 582010000000 tid[0] 400000000 instructions are executed.atomiccpu 0 at 641077500000 tid[0] 500000000 instructions are executed.atomiccpu 0 at 700009321500 tid[0] 600000000 instructions are executed.atomiccpu 0 at 759169539000 tid[0] 700000000 instructions are executed.atomiccpu 0 at 818393124500 tid[0] 800000000 instructions are executed.atomiccpu 0 at 877446054000 tid[0] 900000000 instructions are executed.showinstnum atomiccpu 0 at 907078901500 tid[0] 950264835 instructions are executed.writing checkpointbuild/arm/sim/simulate.cc:194: info: entering event queue @ 907078901500. starting simulation...atomiccpu 0 at 936518571000 tid[0] 1000000000 instructions are executed.atomiccpu 0 at 1019589630500 tid[0] 100000000 instructions are executed.atomiccpu 0 at 1075531936500 tid[0] 200000000 instructions are executed.atomiccpu 0 at 1133110363000 tid[0] 300000000 instructions are executed.atomiccpu 0 at 1190919530500 tid[0] 400000000 instructions are executed.atomiccpu 0 at 1248468781000 tid[0] 500000000 instructions are executed.atomiccpu 0 at 1305429062000 tid[0] 600000000 instructions are executed.atomiccpu 0 at 1363401303000 tid[0] 700000000 instructions are executed.atomiccpu 0 at 1421469390000 tid[0] 800000000 instructions are executed.atomiccpu 0 at 1479484997500 tid[0] 900000000 instructions are executed.atomiccpu 0 at 1537414678500 tid[0] 1000000000 instructions are executed.atomiccpu 0 at 1595390184500 tid[0] 1100000000 instructions are executed.atomiccpu 0 at 1646996227500 tid[0] 1200000000 instructions are executed.atomiccpu 0 at 1698272492000 tid[0] 1300000000 instructions are executed.atomiccpu 0 at 1754533327500 tid[0] 1400000000 instructions are executed.atomiccpu 0 at 1814630599500 tid[0] 1500000000 instructions are executed.atomiccpu 0 at 1866048774500 tid[0] 1600000000 instructions are executed.atomiccpu 0 at 1922046022000 tid[0] 1700000000 instructions are executed.atomiccpu 0 at 1978814167500 tid[0] 1800000000 instructions are executed.atomiccpu 0 at 2036107971000 tid[0] 1900000000 instructions are executed.atomiccpu 0 at 2093257147500 tid[0] 2000000000 instructions are executed.atomiccpu 0 at 2150632827000 tid[0] 2100000000 instructions are executed.atomiccpu 0 at 2206964371500 tid[0] 2200000000 instructions are executed.atomiccpu 0 at 2264055743500 tid[0] 2300000000 instructions are executed.atomiccpu 0 at 2324544549000 tid[0] 2400000000 instructions are executed.atomiccpu 0 at 2381492086000 tid[0] 2500000000 instructions are executed.atomiccpu 0 at 2439386832000 tid[0] 2600000000 instructions are executed.atomiccpu 0 at 2497622146000 tid[0] 2700000000 instructions are executed.atomiccpu 0 at 2556071830000 tid[0] 2800000000 instructions are executed.atomiccpu 0 at 2613942974500 tid[0] 2900000000 instructions are executed.atomiccpu 0 at 2672323657000 tid[0] 3000000000 instructions are executed.atomiccpu 0 at 2730096081000 tid[0] 3100000000 instructions are executed.atomiccpu 0 at 2788185618000 tid[0] 3200000000 instructions are executed.atomiccpu 0 at 2846567200000 tid[0] 3300000000 instructions are executed.atomiccpu 0 at 2906211195500 tid[0] 3400000000 instructions are executed.atomiccpu 0 at 2965004517500 tid[0] 3500000000 instructions are executed. 这里的atomic****cpuinstructions are executed.是我自己增加的打印,不必关注,主要为了显示各个阶段的指令数目。最后再介绍一下./util/term/m5term 3460。 在gem5开始运行后,会显示system.terminal listening for connections on port number.
这时我们另开一个terminal,输入./util/term/m5term number,即可观察到当前os具体运行到哪一步,而上面说的,如果不指定script,需要手动输入root也是在这里。
对我帮助很大的两篇博客:
https://www.eecg.utoronto.ca/~elsayed9/website/blog/gem5_fs_arm_flow.php
https://lucian.run/2021/10/03/gem5%20fs/
有小伙伴后台私信我申请读博士的事,有意向的小伙伴欢迎私信。
数据中心和光学互连的增长趋势
智能汽车软件关键技术解析
闲谈液晶显示技术(LCD)的诞生发展史
冷压端子是什么,它的主要生产工艺是什么
矿井下无人值守变电所电力监控系统的探讨与产品选型
Gem5 Arm Fullsystem仿真
谷歌Transformer八子全部“出逃”,他们创作了ChatGPT中的“T”
英国6月EV车市概况:全球汽车市场的缩影
宏碁子公司酷碁开发了第二代的“智慧佛珠”产品——“珠运通”
华为5G技术将助力上海移动打造双千兆城市
场效应管在园林类电机驱动电路的应用
Azure“一站式搬家”服务全力保护云中资源与数据
单片开关电源关键元器件的选择
汽车线束测试仪能够给车辆检测带来的好处有哪些
精简感测模组设计 In-cell/SITO主宰触控市场
一加9的真机照疑似曝光,采用挖孔屏方案
振芯科技去年电子元器件产销量下降超4成
TWS耳机充电盒方案,ETA9640 5V
机器人利用传感器进行工作的五大未来展望浅析
提前曝光!2019款新iPad mini/Air突然上线