NEMU模拟器源码编译与使用

本文详细介绍了NEMU模拟器的编译过程,包括依赖包安装、源码获取、配置与编译,以及如何使用riscv64-benos_defconfig针对MySBI+BenOS实验进行定制。还解决了编译过程中遇到的常见错误,如readline.h和path_manager.h缺失问题。
摘要由CSDN通过智能技术生成


本文属于 《RISC-V指令集差分测试(DiffTest)系列教程》之一,欢迎查看其它文章。

1 NEMU介绍

NEMU(NJU Emulator)最早是由南京大学实现的一个用于教学的计算机指令集体系结构(ISA)模拟器,香山处理器团队基于2019版的NEMU进行增强和维护,用于香山处理器前期RISC-V指令集和体系结构的模拟。

因此,NEMU也称为香山模拟器,NEMU支持x86、mips32、RV32和RV64等指令集体系结构。

香山官方文档:https://xiangshan-doc.readthedocs.io/zh-cn/latest/
NEMU仓库:https://github.com/OpenXiangShan/NEMU

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 编译

我们需要将MySBI+BenOS,编译为RISC-V格式的可执行程序,因此需要使用RISC-V交叉编译器。
编译器安装,可参考《TinyEMU之Linux Kernel编译》

这里,我们安装的编译器为: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/configs目录下,有很多xxx_defconfig文件,这是源码的编译配置文件。
在执行make xxx_defconfig时,会将xxx_defconfig文件,复制到源码目录下,并改名为.config。
NEMU有两种编译工作模式:

  • 一种是,编译为可执行程序,编译后生成NEMU/build/riscv64-nemu-interpreter,可以独立运行riscv代码,比如:make riscv64-xs_defconfig。
  • 另一种是,编译为动态库,编译后生成NEMU/build/riscv64-nemu-interpreter-so,作为参考模拟器(REF)被调用,比如:make riscv64-xs-ref_defconfig。

riscv64-xs_defconfig、riscv64-xs-ref_defconfig这2个配置文件,是香山模拟器提供的,仅针对于香山处理器配置。
如果模拟其他处理器,需要有对应的其他配置文件,比如:这里我们运行MySBI+BenOS,就需要使用riscv64-benos_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) {
		;
	}
}

作为一个OS,它是不合格的,太简陋了!
但是,作为一个实验代码,它是优秀的,极其简单!!!

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
在这里插入图片描述

再次调试NEMU,可以在nemu-main.c:24打断点,如下:
在这里插入图片描述

输入r运行,可以在nemu-main.c:24处停住,然后按Ctrl+Alt+A,显示如下:
在这里插入图片描述

gdb调试NEMU代码成功。

6 通过NEMU调试指令

NEMU中运行benos_payload.bin时,可通过如下命令,调试指令:

./riscv64-nemu-interpreter benos_payload.bin

注意:不带-b选项

进入NEMU调试界面,如下:
在这里插入图片描述

si命令,表示单步执行。
我们可以继续单步,就可以从benos_payload.bin中,第一条指令,依次往下执行了。
每一步会显示出机器码和对应汇编。

NEMU调试MySBI+BenOS固件代码成功。


参考链接:

  • 12
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
NJU ICS课程实验PA(Programming Assignment),实现NEMU,一个简化的i386模拟器。由C语言编写,以用户软件的形态运行,能够执行i386指令集程序。.zip 源码是经过本地编译可运行的,下载完成之后配置相应环境即可使用源码功能都是经过老师肯定的,都能满足要求,有需要放心下载即可 源码是经过本地编译可运行的,下载完成之后配置相应环境即可使用源码功能都是经过老师肯定的,都能满足要求,有需要放心下载即可 源码是经过本地编译可运行的,下载完成之后配置相应环境即可使用源码功能都是经过老师肯定的,都能满足要求,有需要放心下载即可 项目资源具有较高的学习借鉴价值,也可直接拿来修改复现。可以在这些基础上学习借鉴进行修改和扩展,实现其它功能。可下载学习借鉴,你会有所收获。 项目资源具有较高的学习借鉴价值,也可直接拿来修改复现。可以在这些基础上学习借鉴进行修改和扩展,实现其它功能。可下载学习借鉴,你会有所收获。 项目资源具有较高的学习借鉴价值,也可直接拿来修改复现。可以在这些基础上学习借鉴进行修改和扩展,实现其它功能。可下载学习借鉴,你会有所收获。 可下载学习借鉴,你会有所收获。可下载学习借鉴,你会有所收获。可下载学习借鉴,你会有所收获。# 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。2. 部分字体以及插图等来自网络,若是侵权请联系删除。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百里杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值