首頁>技術>

本期內容如下:

GDB除錯概述編譯和安裝QEMU除錯演示

在之前的01-05章我們講解了RISC-V ISA相關的知識,對RISC-V也已經有個基本的瞭解,為了加深對RISC-V ISA的理解,光做到看還是不夠的,我們還需要動手去編寫彙編程式碼。

GDB工具用於除錯編譯後的程式碼;QEMU用於模擬RISC-V處理器,這樣我們就可以不需要具體硬體就可以除錯我們的彙編程式碼,對於學習十分方便。

如果,有些人需要在具體硬體上進行模擬除錯,我今後還會寫一篇文章,介紹如何使用JTAG在linux上進行硬體除錯的文章,還請關注。

一、GDB除錯概述

GNU symbolic debugger,簡稱「GDB 偵錯程式」,是 Linux 平臺下最常用的一款程式偵錯程式。GDB 編譯器通常以 gdb 命令的形式在終端(Shell)中使用。作為程式設計師,編寫和除錯程式是必備的技能,為此學好gdb是十分有必要的,還請讀者自行查閱相關文件,在這裡就不對gdb功能進行過多展開了。

在RISC-V的開發過程中,我們用的gdb工具被包含在工具鏈中,檔名類似於riscv-none-embed-gdb。在這裡我們簡單瞭解一下gdb的基本指令。

riscv-none-embed-gdb 執行檔名稱 ---------------gdb載入符號檔案,用於後續的除錯run ----------------此命令使程式開始執行

更多指令參見圖1.

圖1 GDB常用指令

二、編譯,安裝和使用QEMU

由於不同的linux發行版本,在軟體上相容性可能會存在一些問題,這裡僅介紹如何在linux上,進行RISC-V的QEMU編譯和安裝,並沒有提供已經編譯好的qemu-riscv32,我這裡採用的作業系統為deepin-v20,其他linux系統編譯和安裝方法類似。

2.1 QEMU編譯和安裝

具體步驟如下:

sudo apt install libpixman-1-devgit clone https://github.com/riscv/riscv-qemu.gitcd riscv-qemu/git checkout riscv-qemu-3.0./configuremake -j4sudo make install 

當一切都安裝完成後,我們執行qemu-riscv32 --version應當能夠看到如圖2所示的內容。

圖2 qemu-riscv32 版本資訊

2.2 qemu-riscv32的使用

qemu-riscv32指令常用格式如下:

qemu-riscv32 程式名稱 -nographic

如我們已經有一個已經編譯好的riscv32 程式hello,為了在qemu中執行程式,只需要執行如下指令即可。

qemu-riscv32 hello -nographic

如果我們希望聯合riscv-none-embed-gdb,並透過qemu實現除錯,我們可以使用如下指令讓qemu支援gdb單步除錯功能。

qemu-riscv32 -singlestep -g 埠號 程式名 -nographic

如需要對上邊的hello程式進行除錯,我們選的通訊埠為112233,此時指令如下:

qemu-riscv32 -singlestep -g 112233 hello -nographic

三、除錯演示

3.1 編寫彙編檔案hello.S檔案,

該檔案主要實現兩個數相加,加數1放入a1,加數2放入a2,結果a0

  .global _start_start:      li a1,23      li a2,18      add a0,a1,a2loop:      j   loop

3.2 編寫Makefile檔案

Makefile檔案主要是為了方便今後的程式碼編譯,不需要每次都輸入很長的編譯指令,僅需執行make,即可完成程式的編譯。

CC:=riscv-none-embed-gccXFLAGS+= -save-temps -nostdlib -nostartfiles -ffreestanding -static all:	$(CC) $(XFLAGS) -g -o hello hello.Sclean:	rm -rf *.o

riscv-none-embed-gcc為我選用的工具鏈的編譯器名稱,如果你的編譯器為其他,請做相應的修改,gcc是可以直接編譯彙編指令的當然你也可以使用riscv-none-embed-as進行編譯。

3.3 編寫模擬器啟動指令碼sim

sim指令碼不是必須的,之所以這樣寫是為了方便今後快速用qemu載入編譯後的程式,方便除錯exe_name為要執行的程式,這裡實行./sim hello就實現了載入hello程式到qemu模擬器的操作。

function help(){echo "Please input applicantion !"echo "==========="echo "sim  exe_name"}function main(){if [ "$1" == "" ];then	help	returnfiqemu-riscv32 -singlestep -g 12345 $1 nographic}main $1

3.4 完成各檔案的編寫

所有檔案編寫完後,我們將看到如圖3所示的hello工程目錄結構。

圖3 hello檔案目錄

3.5 編譯hello.S檔案

執行make指令,將看到hello檔案被建立了

圖4 make後的檔案列表

3.6 開啟qemu-riscv32模擬器

執行sim hello,qemu-riscv32將會載入hello程式

圖5 執行sim hello操作

3.7 開啟riscv32的gdb工具

1.執行riscv-none-embed-gdb hello,該指令將會把hello檔案載入到gdb中;

2.在gdb控制檯中執行target remote localhost:12345 連線qemu-riscv32模擬器;

3.前兩步完成後便可以開始除錯hello程式了。

圖6 開啟gdb並連結qemu模擬器

3.8 除錯hello程式

具體除錯的過程參見如下gdb除錯log,

Copyright (C) 2019 Free Software Foundation, Inc.                                                                                                      License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law.Type "show copying" and "show warranty" for details.This GDB was configured as "--host=x86_64-unknown-linux-gnu --target=riscv-none-embed".Type "show configuration" for configuration details.For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>.Find the GDB manual and other documentation resources online at:    <http://www.gnu.org/software/gdb/documentation/>.For help, type "help".Type "apropos word" to search for commands related to "word"...Reading symbols from hello...        (gdb) target remote localhost:12345Remote debugging using localhost:12345_start () at hello.S:44           li  a1,23(gdb) list1           .align 42           .global  _start3       _start:4           li  a1,235           li  a2,186           add a0,a1,a2   789       loop:10         j    loop(gdb) break 7Breakpoint 1 at 0x1006a(gdb) break 3Breakpoint 2 at 0x10062: file hello.S, line 5.(gdb) nextBreakpoint 2, _start () at hello.S:55           li  a2,18(gdb) next6           add a0,a1,a2   (gdb) nextloop () at hello.S:1010         j    loop(gdb) info registers ra             0x0      0x0sp             0xffffcda0       0xffffcda0gp             0x0      0x0tp             0x0      0x0t0             0x0      0t1             0x0      0t2             0x0      0fp             0x0      0x0s1             0x0      0a0             0x29     41a1             0x17     23a2             0x12     18a3             0x0      0a4             0x0      0a5             0x0      0a6             0x0      0a7             0x0      0s2             0x0      0s3             0x0      0s4             0x0      0s5             0x0      0s6             0x0      0s7             0x0      0s8             0x0      0s9             0x0      0s10            0x0      0s11            0x0      0t3             0x0      0t4             0x0      0t5             0x0      0t6             0x0      0--Type <RET> for more, q to quit, c to continue without paging--cpc             0x10068  0x10068 <loop>

從gdb除錯過程中可以看到a0的值為41,a1為23,a2為18,也就是說a0=a1+a2,和我們的彙編程式一樣。

至此,一個可以模擬和除錯RISC-V環境就已經搭建完畢了,今後我們便可以在這個環境下學習具體的彙編指令了,透過gdb的info registers指令我們可以實時檢視到RISC-V處理器的所有暫存器資料。

43
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 超大型 Vue+Vant 單頁電商專案ddBuy