riscv-xv6單步除錯1
阿新 • • 發佈:2021-03-29
序
過了兩個月,現在準備重新看xv6的原始碼,除錯的時候卻死活記不起來自己當初是怎麼除錯的,遂明白寫部落格記錄的重要性,打算這次看原始碼的時候,把容易遺忘的東西都記錄下來,留待後觀吧。
xv6除錯方法
在xv6原始碼有Makefile的路徑上,一個終端輸入
make cpus=1 qemu-gdb
然後在另一個終端輸入
gdb-multiarch
特別注意這裡用的是gdb-multiarch(花了好多時間就是找不到合適的gdb,MIT的教學視訊裡面的riscv64-linux-gnu-gdb在我的linux上找不到這玩意)。該路徑下有一個.gdbinit的初始化檔案,gdb-multiarch會讀取這個檔案然後自動連線之前的gdb,然後就可以正常除錯了。
xv6的單步除錯
從入口點entry.S的彙編程式碼開始。
_entry: # set up a stack for C. # stack0 is declared in start.c, # with a 4096-byte stack per CPU. # sp = stack0 + (hartid * 4096) la sp, stack0 li a0, 1024*4 csrr a1, mhartid addi a1, a1, 1 mul a0, a0, a1 add sp, sp, a0 # jump to start() in start.c call start
初始情況entry.S被載入到地址0x80000000。這裡的la是一條偽指令,由aupic和addi組合而成,實際效果相當於,sp = stack + pc。gdb顯示如下:
在執行auipc指令之後,sp的值變為0x80009000,因此auipc指令的作用是 rd = sp + (立即數 << 12)。接著的li也是一條偽指令,在gdb中對應指令lui。lui指令的作用是rd = 立即數 << 12。
csrr偽指令用於讀取CSR到目的暫存器rd。mhartid感覺可以簡單地理解為cpu編號的標識?下面是文件中的描述。
實際上通過print可以知道此時mhartid=0。我想這個作用在於多個cpu啟動時為每個cpu建立一個不同的棧吧。
小結關鍵詞:
gdb除錯核心方法,la指令,mhartid含義,aupic,lui指令。