Nuclei QEMU User Guide - riscv-mcu/qemu GitHub Wiki

NUCLEI QEMU 用户手册

1.简介

NUCLEI QEMU是基于开源项目QEMU,添加NUCLEI处理器的支持。可以非常方便的将能够运行在Nuclei DDR200T/MCU200T开发板上的程序直接在NUCLEI QEMU上运行。

NUCLEI QEMU特性:

1.支持NUCLEI 全系列的处理器平台模拟

2.提供Linux和Windows平台可执行程序,方便使用

3.支持NUCLEI完整的软件生态,包括NUCLEI SDK,NMSIS,NUCLEI LINUX SDK等等。

4.可以模拟一些基本的外设,比如elic,plic,uart,gpio等,方便驱动程序的开发

5.支持GDB调试功能,分析程序运行更加高效

6.程序无需修改直接可以运行在NUCLEI QEMU上

2.NUCLEI QEMU的参数说明

NUCLEI QEMU已经支持当前nuclei大多数的处理器型号,并会持续更新,支持更多的最新处理器的型号。下面展示了支持的CPU型号的情况。

qemu_support

在qemu中,主要支持两种不同的机器模型,分别是nuclei_n和nuclei_u。

其中nuclei_n主要是用于运行不起用mmu的情况时,处理器运行的程序,比如对应的nuclei-sdk,nmsis等等软件生态,运行编译的程序是rtos或者裸机程序。

nuclei_u则主要针对于运行Linux情况下时的情况,所以nuclei_u主要针对运行nuclei-linux-sdk中的情况。下面列出nuclei_n与nuclei_u支持的nuclei core的列表。

一条最基本的指令如下所示:

qemu-system-riscv32 -M nuclei_n,download=ddr -cpu nuclei-n307 -kernel nuclei-sdk/application/baremetal/helloworld/helloworld.elf -serial stdio -nodefaults -nographic

qemu主程序:

qemu-system-riscv32qemu-system-riscv64两个可以执行的程序。

程序名称 说明
qemu-system-riscv32 执行32位程序,对应nuclei n级别处理器
qemu-system-riscv64 执行64位程序,对应nuclei nx与ux级别处理器

qemu对应的机器:

命令中用-M进行选择,对应NUCLEI的处理器有nuclei_nnuclei_u

qemu机器类型 说明
nuclei_n 对应不开启mmu的处理器程序,主要针对裸机代码或者RTOS
nuclei_u 需要开启mmu,主要用于运行Linux
gd32vf103v_eval gd32vf103 eval开发板
gd32vf103v_rvstar gd32vf103 rvstar开发板

后面携带download的选项,表示编译出的固件是默认运行Nuclei DDR200T/MCU200T哪一种存储固件介质中。其中download的下载支持如下几种:

download参数 说明
ddr 编译运行在ddr中的固件选择该参数
flash 编译运行在flash中的固件选择该参数
flashxip 编译运行在flashxip中的固件选择该参数
ilm 编译运行在ilm中的固件选择该参数,默认值

qemu对应的cpu类型:

NUCLEI QEMU支持nuclei不同类型的CORE,下面列出一些对应关系。

qemu_map_0917

图片展示了qemu对应的机器类型与CORE的关系。

注意:gd32vf103v_eval与gd32vf103v_rvstar可以不用指定download与-cpu,实例:qemu-system-riscv32 -M gd32vf103v_rvstar -kernel nuclei-sdk/application/baremetal/helloworld/helloworld.elf -serial stdio -nodefaults -nographic

扩展指令:

对于core使能了p扩展,或者使能了v扩展的情况,需要在-cpu的选项中加上ext=p|v选项,具体实例:qemu-system-riscv32.exe -M nuclei_n,download=ilm -cpu nuclei-n307fd,ext=pv -kernel application/baremetal/helloworld/helloworld.elf -serial stdio -nodefaults -nographic。程序若使能了b,k,p,v扩展,则运行qemu时也需要加上 ext=b|k|p|v,进行扩展组合选择。

qemu选择执行的程序:

通过对参数传递-kernel,后面携带需要运行的固件程序即可。

3.快速上手说明

下面演示运行qemu执行nuclei sdk中的程序和运行nuclei-linux-sdk的例子。

3.1 获取可以运行的qemu程序

nuclei qemu可以通过下面的渠道获取

1.通过芯来官方网站上获取最新的版本

2.Nuclei Studio IDE中的目录NucleiStudio\tools\qemu找到对应的qemu程序

3.2 运行nuclei sdk的程序

Windows上运行:

在windows上编译nuclei sdk的文档可以参考:Nuclei SDK:Quick Startup

按照上述步骤设置环境变量后,通过输入

# 确保当前在Nuclei-SDK根目录下
cd application/baremetal/helloworld
# 编译
make SOC=demosoc BOARD=nuclei_fpga_eval CORE=n307fd DOWNLOAD=ilm all

其中需要关注的是CORE为n307fdDOWNLOAD=ilm

通过下面的qemu执行指令,可以看到正常的输出结果。

现已经集成到Nuclei-SDK >= 0.3.7 的Build System中,针对上面的示例运行 make SOC=demosoc BOARD=nuclei_fpga_eval CORE=n307fd DOWNLOAD=ilm run_qemu 即可

qemu-system-riscv32.exe -M nuclei_n,download=ilm -cpu nuclei-n307fd -kernel helloworld.elf -serial stdio -nodefaults -nographic
Nuclei SDK Build Time: Jun  2 2021, 16:51:43
Download Mode: ILM
CPU Frequency 3392641105 Hz
MISA: 0x4010112d
MISA: RV32IMACFDU
0: Hello World From Nuclei RISC-V Processor!
1: Hello World From Nuclei RISC-V Processor!
2: Hello World From Nuclei RISC-V Processor!
3: Hello World From Nuclei RISC-V Processor!
4: Hello World From Nuclei RISC-V Processor!
5: Hello World From Nuclei RISC-V Processor!
6: Hello World From Nuclei RISC-V Processor!
7: Hello World From Nuclei RISC-V Processor!
8: Hello World From Nuclei RISC-V Processor!
9: Hello World From Nuclei RISC-V Processor!
10: Hello World From Nuclei RISC-V Processor!
11: Hello World From Nuclei RISC-V Processor!
12: Hello World From Nuclei RISC-V Processor!
13: Hello World From Nuclei RISC-V Processor!
14: Hello World From Nuclei RISC-V Processor!
15: Hello World From Nuclei RISC-V Processor!
16: Hello World From Nuclei RISC-V Processor!
17: Hello World From Nuclei RISC-V Processor!
18: Hello World From Nuclei RISC-V Processor!
19: Hello World From Nuclei RISC-V Processor!

Linux上运行:

在windows上编译nuclei sdk的文档可以参考:Nuclei SDK:Quick Startup

设置完成环境变量后,输入

# 确保当前在Nuclei-SDK根目录下
cd application/baremetal/helloworld
# 编译
make SOC=demosoc BOARD=nuclei_fpga_eval CORE=n307fd DOWNLOAD=ilm all

编译成功后,控制台输入

现已经集成到Nuclei-SDK >= 0.3.7 的Build System中,针对上面的示例运行 make SOC=demosoc BOARD=nuclei_fpga_eval CORE=n307fd DOWNLOAD=ilm run_qemu 即可

qemu-system-riscv32 -M nuclei_n,download=ilm -cpu nuclei-n307fd -kernel helloworld.elf -serial stdio -nodefaults -nographic

即可看到qemu执行程序的结果,其中-kernel表示执行的程序。

Nuclei SDK Build Time: Jun  2 2021, 18:03:13
Download Mode: ILM
CPU Frequency 142755758 Hz
MISA: 0x4010112d
MISA: RV32IMACFDU
0: Hello World From Nuclei RISC-V Processor!
1: Hello World From Nuclei RISC-V Processor!
2: Hello World From Nuclei RISC-V Processor!
3: Hello World From Nuclei RISC-V Processor!
4: Hello World From Nuclei RISC-V Processor!
5: Hello World From Nuclei RISC-V Processor!
6: Hello World From Nuclei RISC-V Processor!
7: Hello World From Nuclei RISC-V Processor!
8: Hello World From Nuclei RISC-V Processor!
9: Hello World From Nuclei RISC-V Processor!
10: Hello World From Nuclei RISC-V Processor!
11: Hello World From Nuclei RISC-V Processor!
12: Hello World From Nuclei RISC-V Processor!
13: Hello World From Nuclei RISC-V Processor!
14: Hello World From Nuclei RISC-V Processor!
15: Hello World From Nuclei RISC-V Processor!
16: Hello World From Nuclei RISC-V Processor!
17: Hello World From Nuclei RISC-V Processor!
18: Hello World From Nuclei RISC-V Processor!
19: Hello World From Nuclei RISC-V Processor!

需要注意的是,在nuclei sdk中对应的CORE的类别,比如n307fd,那么在qemu中对应的-cpu的类型为nuclei-n307fd。

更多Nuclei SDK编译的问题参考Nuclei SDK Document

3.3 运行nuclei linux sdk的程序

NUCLEI QEMU目前也能够正常支持运行Linux的程序。当前可以正常运行Nuclei Linux SDK

Nuclei Linux SDK 已经集成如何在QEMU上运行,请参见 https://github.com/Nuclei-Software/nuclei-linux-sdk#booting-linux-on-nuclei-qemu

通过输入下面的命令进行编译

cd nuclei-linux-sdk

git submodule init

git submodule update

编译opensbi

make opensbi

编译Linux kernel

make linux

制作rootfs

make bootimages

运行下面的脚本即可

qemu-system-riscv64  -M nuclei_u  -nographic -m 256M -icount shift=0 -bios work/opensbi/platform/nuclei/demosoc/firmware/fw_jump.bin -kernel work/linux/arch/riscv/boot/Image -initrd work/initramfs.cpio.gz

Linux程序可正常运行。

linux_run

用户名:root

密码:nuclei

4.qemu的gdb调试功能

NUCLEI QEMU支持GDB调试功能,通过断点,单步运行,内存dump,寄存器查看等功能,对程序的运行有非常直观的观察。

通过调试RT-Thread的程序来演示qemu上GDB的演示。

编译rtthread固件

make SOC=demosoc BOARD=nuclei_fpga_eval CORE=n307fd DOWNLOAD=ilm PROGRAM=application/rtthread/msh/ all

接着打开调试端口

qemu-system-riscv32 -M nuclei_n,download=ilm -cpu nuclei-n307fd -kernel application/rtthread/msh/msh.elf -serial stdio -nodefaults -nographic -s -S

另外再开一个命令行终端,输入下列命令

riscv-nuclei-elf-gdb application/rtthread/msh/msh.elf

然后输入

target remote localhost:1234

可以打开gdb调试界面

gdb

通过输入b main表示将main函数处打断点。

通过输入c让程序正常向下运行。

gdb 调试常用命令

打开汇编显示

set disassemble-next-line on

汇编级别单步跳转

si

C语言级别单步跳转

n

设置断点

b

查看寄存器

info register <register name> 

查看所有寄存器

info register all

5.常用命令

1.打开qemu gdb前端

-s -S

用gdb后端连接时,只需要target remote localhost:1234

2.查看支持的机器类型

qemu-system-riscv64 -M ?

3.查看支持的cpu类型

qemu-system-riscv64 -M nuclei_n -cpu ?

4.查看qemu版本号

qemu-system-riscv64 --version

5.导出设备树文件

qemu-system-riscv64 -nographic -machine virt,dumpdtb=virt.dtb