RISC-V体系结构编程与实践(第2版)
上QQ阅读APP看书,第一时间看更新

2.2 搭建实验环境

2.2.1 实验2-1:输出“Welcome to RISC-V!”

1.实验目的

了解并熟悉如何在NEMU和QEMU模拟器上运行最简单的BenOS程序。

2.实验详解

在Linux主机中安装相关工具。

$ sudo apt-get install qemu-system-misc libncurses5-dev gcc-riscv64-linux-gnu build-essential git bison flex libssl-dev

(1)在QEMU上运行BenOS

在Linux主机上使用make命令编译BenOS[1]


[1]请参考“本书约定”一章获取下载配套参考代码的方法。

$ cd riscv_programming_practice/chapter_2/benos
$ export board=qemu
$ make clean
$ make
 CC   build_src/uart_c.o
 CC   build_src/kernel_c.o
 AS   build_src/boot_s.o
 LD build_src/benos.elf
 OBJCOPY benos.bin
 CC   build_sbi/sbi_main_c.o
 AS   build_sbi/sbi_boot_s.o
 AS   build_sbi/sbi_payload_s.o
 LD build_sbi/mysbi.elf
 OBJCOPY mysbi.bin
 LD build_sbi/benos_payload.elf
 OBJCOPY benos_payload.bin

要想编译能在QEMU模拟器[2]上运行的可执行二进制文件,需要先设置board=qemu。


[2]本书使用的QEMU版本默认为Ubuntu 20.04自带的版本(4.2.1),如读者使用高版本QEMU时遇到问题,请参考本章实验代码中的说明文件:riscv_programming_practice/chapter_2/必读.txt。

直接输入make run命令并运行。

rlk@master:benos$ make run
qemu-system-riscv64 -nographic -machine virt -m 128M  -bios mysbi.bin -kernel benos.elf
 
Welcome RISC-V!

QEMU输出“Welcome RISC-V!”。要关闭QEMU,可以先按 “Ctrl +A”键,松开,再快速按 “X”键。

(2)在NEMU上运行BenOS

在Linux主机上使用make命令编译BenOS。

$ cd riscv_programming_practice/chapter_2/benos
$ export board=nemu
$ make clean
$ make
 CC   build_src/uart_c.o
 CC   build_src/kernel_c.o
 AS   build_src/boot_s.o
 LD build_src/benos.elf
 OBJCOPY benos.bin
 CC   build_sbi/sbi_main_c.o
 AS   build_sbi/sbi_boot_s.o
 AS   build_sbi/sbi_payload_s.o
 LD build_sbi/mysbi.elf
 OBJCOPY mysbi.bin
 LD build_sbi/benos_payload.elf
 OBJCOPY benos_payload.bin

要想编译能在NEMU模拟器上运行的可执行二进制文件,需要先设置board=nemu。如果想查看更多编译日志,可以使用make V=1命令。编译完成之后会生成以下5个文件。

benos.bin:BenOS可执行文件。

benos.elf:BenOS带调试信息的可执行与可链接格式(Executable and Linkable Format,ELF)文件。

mysbi.bin:MySBI固件的可执行文件。

mysbi.elf:MySBI带调试信息的ELF文件。

benos_payload.bin:把benos.bin和mysbi.bin整合到一个可执行二进制文件中。

直接输入make run命令并运行。

rlk@master:benos$ make run
riscv64-nemu-interpreter -b benos_payload.bin
 
Welcome to riscv64-NEMU!
For help, type "help"
Welcome RISC-V!

NEMU输出“Welcome RISC-V!”,如图2.1所示。

图2.1 NEMU的输出结果

2.2.2 实验2-2:单步调试BenOS和MySBI

本小节提供两种单步调试BenOS和MySBI的方法。一种是使用QEMU与GDB工具,另一种是使用NEMU内置的单步调试功能。

1.使用QEMU与GDB工具

以实验2-1为例,使用make debug命令在终端启动QEMU虚拟机的gdbserver。

$ cd riscv_programming_practice/chapter_2/benos
$ make debug

或者直接使用如下命令启动gdbserver。

$ qemu-system-riscv64 -nographic -machine virt -m 128M -bios mysbi.bin -kernel benos.elf -S -s

在另一个终端使用如下命令启动GDB工具。

$ gdb-multiarch --tui benos.elf

在GDB命令行中执行如下命令。

(gdb) target remote localhost:1234
(gdb) b _start
Breakpoint 1 at 0x80200000: file src/boot.S, line 6.
(gdb) c

此时,使用GDB工具单步调试BenOS,如图2.2所示。

图2.2 使用GDB工具单步调试BenOS

另外,也可以通过GDB工具调试MySBI固件。为了在终端启动QEMU虚拟机的gdbserver,使用make debug命令。

$ cd riscv_programming_practice/chapter_2/benos
$ make debug

在另一个终端使用如下命令启动GDB工具,这时候需要加载MySBI固件的ELF文件。

$ gdb-multiarch --tui mysbi.elf

在GDB命令行中执行如下命令。

(gdb) target remote localhost:1234
(gdb) b _start
Breakpoint 1 at 0x80000000: file sbi/sbi_boot.S, line 6.
(gdb) c

此时,使用GDB工具进行单步调试,如图2.3所示。

图2.3 单步调试

2.NEMU内置的单步调试功能

NEMU内置了简易调试器(Simple Debugger,SDB)。SDB是NEMU中一个非常重要的基础设施,可以获取程序的执行信息,以协助调试。SDB支持的命令如表2.4所示。

表2.4 SDB支持的命令

在Linux主机终端,使用make debug命令启动SDB。

$ cd riscv_programming_practice/chapter_2/benos
$ make debug
riscv64-nemu-interpreter benos_payload.bin
Welcome to riscv64-NEMU!
For help, type "help"
(nemu)

在SDB命令行中输入“help”,查看帮助信息,如图2.4所示。

图2.4 查看帮助信息

输入“si”,进行单步调试,如图2.5所示。

图2.5 进行单步调试

另外,还可以通过监视点命令设置断点,不过目前只支持为地址设置断点。例如,在0x8020 0000地址处设置断点。

$ make debug
 
(nemu) w $pc==0x80200000  //设置断点
Set watchpoint #0
(nemu) c                  //继续执行,此时NEMU停在断点处
Hint watchpoint 0 at address 0x00000000800000a8, expr = $pc==0x80200000
old value = 0x0000000000000000
new value = 0x0000000000000001
(nemu) si                 //单步执行
0x0000000080200000:   73 10 40 10                     csrrw  $0,0x104,$0
 
Hint watchpoint 0 at address 0x0000000080200000, expr = $pc==0x80200000
old value = 0x0000000000000001
new value = 0x0000000000000000