大家好,欢迎来到IT知识分享网。
NEMU模拟器源码编译与使用
本文属于 《RISC-V指令集差分测试(DiffTest)系列教程》之一,欢迎查看其它文章。
1 NEMU介绍
NEMU(NJU Emulator)最早是由南京大学实现的一个用于教学的计算机指令集体系结构(ISA)模拟器,香山处理器团队基于2019版的NEMU进行增强和维护,用于香山处理器前期RISC-V指令集和体系结构的模拟。
因此,NEMU也称为香山模拟器,NEMU支持x86、mips32、RV32和RV64等指令集体系结构。
2 编译MySBI+BenOS
2.1 下载源码
这里,我们以《RISC-V体系结构编程与实践》书中第2章,提供的MySBI+BenOS实验代码为例,进行说明。
关于MySBI+BenOS实验代码的更多说明,可参考《RISC-V体系结构编程与实践》第2章 搭建RISC-V实验环境。
- benos目录下为实验代码,包含MySBI(相当于BIOS)和BenOS;这个超精简BIOS和超精简OS,仅仅几行代码,越简单越易学;
- riscv64-benos_defconfig为NEMU的编译配置文件,这个应该是该实验代码的作者,定制修改过的,可以正确跑实验代码。
2.2 编译
这里,我们安装的编译器为:riscv64-unknown-linux-gnu-gcc
进入目录
cd benos
将Makefile文件第一行,修改为:
GNU ?= riscv64-unknown-linux-gnu
表示使用riscv64-unknown-linux-gnu为编译器前缀,来进行编译。
设置board环境变量
export board=nemu
执行编译
make
编译完毕
生成了,如下文件:
- benos.bin,BenOS可执行文件
- benos.elf,BenOS带调试信息的ELF文件
- mysbi.bin,MySBI固件的可执行文件
- mysbi.elf,MySBI带调试信息的ELF文件
- benos_payload.bin,把benos.bin和mysbi.bin整合到一个可执行二进制文件中。
NEMU要求使用一个完整的二进制可执行文件,因此只有benos_payload.bin
,才可以在NEMU中运行。
3 编译NEMU
3.1 编译
安装依赖包
apt install build-essential man gcc gdb git libreadline-dev libsdl2-dev zstd libzstd-dev
下载NEMU源码
git clone https://github.com/OpenXiangShan/NEMU.git
进入目录
cd NEMU/
配置环境变量(/home/test/NEMU换成自己NEMU源码目录)
export NEMU_HOME=/home/test/NEMU
配置NEMU编译为单独可执行程序
make riscv64-benos_defconfig # riscv64-benos_defconfig需放入NEMU/configs/
- 一种是,编译为可执行程序,编译后生成
NEMU/build/riscv64-nemu-interpreter
,可以独立运行riscv代码,比如:make riscv64-xs_defconfig。- 另一种是,编译为动态库,编译后生成
NEMU/build/riscv64-nemu-interpreter-so
,作为参考模拟器(REF)被调用,比如:make riscv64-xs-ref_defconfig。
打开配置界面(若无修改,则跳过)
make menuconfig
通过配置界面,所做的修改,会被保存到.config文件中。
执行编译
make -j`nproc`
执行
make clean
,可以清除编译结果。
执行make clean-all
,清除编译结果和.config文件。
在NEMU/build目录下,生成了riscv64-nemu-interpreter。
3.2 解决NEMU编译报错
3.2.1 找不到readline/readline.h
报错: fatal error : readline/readline.h : No such file or directory…
解决办法: apt install libreadline-dev
3.2.2 找不到path_manager.h
报错: path_manager.h:24:10: fatal error: filesystem: No such file or directory
解决办法: 安装gcc8和g++8
sudo apt install gcc-8 sudo apt install g++-8 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 800 --slave /usr/bin/g++ g++ /usr/bin/g++-8 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 700 --slave /user/bin/g++ g++ /usr/bin/g++-7 sudo update-alternatives --config gcc
最后一条命令,是选择系统默认GCC编译器,这里选择第0项,“0 /usr/bin/gcc-8 800 auto mode”。
4 NEMU运行MySBI+BenOS
将benos_payload.bin,拷贝至riscv64-nemu-interpreter所在目录
cp benos_payload.bin ../NEMU/build/
在NEMU中,运行MySBI+BenOS
cd ../NEMU/build/ ./riscv64-nemu-interpreter -b benos_payload.bin
命令参数妙用:
-b
:表示直接执行;如果去掉,会进入NEMU调试器,可以对固件代码单步调试。-l
:表示将打印内容,输出到日志文件;比如:-l nemu.log
。
我们的BenOS,通过串口打印出了信息:Welcome RISC-V!
BenOS代码kernel.c,实现代码,如下所示:
#include "uart.h" void kernel_main(void) {
uart_init(); uart_send_string("Welcome RISC-V!\r\n"); while (1) {
; } }
5 使用gdb调试NEMU
5.1 重新编译NEMU
上述步骤编译的NEMU,有代码优化,调试起来不方便,我们这里需要去掉优化,并且附带调试信息。
步骤如下:
make clean make menuconfig
配置以下选项,使其附带调试信息:
- Build Options -> Optimization Level:选择O0,表示编译器不优化
- Build Options -> Enable link-time optimization:取消选中,表示禁用链接时优化
- Build Options -> Enable debug information:选中,表示使能调试信息
make -j`nproc`
编译报一大堆错误,如下:
src/isa/riscv64/instr/decode.c: In function ‘table_csrrw’: src/isa/riscv64/instr/decode.c:26:1: error: ‘%s’ directive output may be truncated writing up to 39 bytes into a region of size between 33 and 72 [-Werror=format-truncation=] def_all_THelper(); ^~~~~~~~~~~~~~~~~~
看了下,错误全是一样的。
原因: Makefile文件中,设置的编译等级比较高,使用-werror选项,导致如果出现任何警告都将视为错误,所以就会导致编译失败。
解决办法: 在Makefile中,将-werror删除,重新编译。
这里,我们删除NEMU/scripts/build.mk中,所有-Werror选项,如下所示:
CFLAGS := -O2 -MMD -Wall -Werror $(INCLUDES) $(CFLAGS) CXXFLAGS := -O2 -MMD -Wall -Werror --std=c++17 $(XINCLUDES) $(CFLAGS)
再次编译,依旧一大堆警告,但是不报错,最后编译成功。
5.2 gdb调试
gdb调试NEMU:
cd NEMU/build/ gdb --args ./riscv64-nemu-interpreter -b benos_payload.bin
出现gdb报错,如下:
dictionary.c:690: internal-error: void insert_symbol_hashed(dictionary*, symbol*): Assertion `SYMBOL_LANGUAGE (sym) == DICT_LANGUAGE (dict)->la_language' failed.
报错原因: 这是gdb的一个bug,可参考:https://sourceware.org/bugzilla/show_bug.cgi?id=23999。
解决办法: 升级gdb。我这里从gdb8.1.1,升级到gdb10.2后,解决此问题。
升级gdb10.2,步骤如下:
# 下载GDB源代码 wget http://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.gz # 解压缩 tar -xzf gdb-10.2.tar.gz # 进入目录 cd gdb-10.2/ # 配置安装 ./configure make -j`nproc` # 安装到系统路径 sudo make install
默认安装到/usr/local/bin目录下,将该目录加入环境变量:
vim ~/.bashrc export PATH=/usr/local/bin:$PATH # 在文件的末尾添加本行 source ~/.bashrc
查看版本gdb -v
输入r
运行,可以在nemu-main.c:24处停住,然后按Ctrl+Alt+A
,显示如下:
gdb调试NEMU代码成功。
6 通过NEMU调试指令
NEMU中运行benos_payload.bin时,可通过如下命令,调试指令:
./riscv64-nemu-interpreter benos_payload.bin
注意:不带-b选项
si
命令,表示单步执行。
我们可以继续单步,就可以从benos_payload.bin中,第一条指令,依次往下执行了。
每一步会显示出机器码和对应汇编。
NEMU调试MySBI+BenOS固件代码成功。
参考链接:
- 《香山处理器仿真环境搭建》
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/121935.html