NEMU模拟器源码编译与使用
- 1 NEMU介绍
- 2 NEMU编译
- 3 NEMU使用
- 3.1 下载MySBI+BenOS
- 3.2 使用riscv64-benos_defconfig编译NEMU
- 3.3 编译MySBI+BenOS
- 3.4 运行MySBI+BenOS
- 4 解决NEMU编译报错
- 4.1 找不到readline/readline.h
- 4.2 找不到path_manager.h
1 NEMU介绍
NEMU(NJU Emulator)最早是由南京大学实现的一个用于教学的计算机指令集体系结构(ISA)模拟器,香山处理器团队基于2019版的NEMU进行增强和维护,用于香山处理器前期RISC-V指令集和体系结构的模拟。
因此,NEMU也称为香山模拟器,NEMU支持x86、mips32、RV32和RV64等指令集体系结构。
2 NEMU编译
安装依赖包
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-xs_defconfig
NEMU有两种工作模式:
- riscv64-xs_defconfig:作为单独可执行程序编译,生成的文件是build/riscv64-nemu-interpreter;
- riscv64-xs-ref_defconfig:作为golden model模式编译,生成的文件是build/riscv64-nemu-interpreter-so。
在执行make xxx_defconfig时,会在源码目录下自动创建.config文件,这是源码的编译配置文件。
可执行程序附带调试信息(可选)
make menuconfig
配置以下选项,使其附带调试信息:
- Build Options -> Optimization Level:选择O0,表示编译器不优化
- Build Options -> Enable link-time optimization:取消选中,表示禁用链接时优化
- Build Options -> Enable debug information:选中,表示使能调试信息
执行编译
make -j
在NEMU/build目录下,生成了riscv64-nemu-interpreter。
执行make run
,启动模拟器,如下所示:
此外,执行make clean
,可以清除编译结果。
执行make clean-all
,清除编译结果和.config文件。
3 NEMU使用
3.1 下载MySBI+BenOS
这里,我们以《RISC-V体系结构编程与实践》中第2章,提供的MySBI+BenOS实验代码为例,进行说明。
关于MySBI+BenOS实验代码的更多说明,可参考《RISC-V体系结构编程与实践》第2章 搭建RISC-V实验环境。
- benos目录下为实验代码,包含MySBI(相当于BIOS)和BenOS;这个超精简BIOS和超精简OS,仅仅几行代码,越简单越易学;
- riscv64-benos_defconfig为NEMU的编译配置文件,这个应该是该实验代码的作者,定制修改过的,可以正确跑实验代码。
因为,我使用上节中make riscv64-xs_defconfig配置,编译生成的riscv64-nemu-interpreter,来跑实验代码,会报错。
3.2 使用riscv64-benos_defconfig编译NEMU
因此,我们需要使用make riscv64-benos_defconfig
,然后make -j
,生成的riscv64-nemu-interpreter。
3.3 编译MySBI+BenOS
我们需要将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中运行。
拷贝至riscv64-nemu-interpreter所在目录
cp benos_payload.bin ../NEMU/build/
3.4 运行MySBI+BenOS
在NEMU中,运行MySBI+BenOS
cd ../NEMU/build/
./riscv64-nemu-interpreter -b benos_payload.bin
运行效果,如下所示:
我们的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,它是不合格的,太简陋了!
但是,作为一个实验代码,它是优秀的,极其简单!!!
4 解决NEMU编译报错
4.1 找不到readline/readline.h
报错: fatal error : readline/readline.h : No such file or directory…
解决办法: apt install libreadline-dev
4.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”。
参考链接:《香山处理器仿真环境搭建》