網(wǎng)站網(wǎng)址怎么找電商運營培訓班多少錢
前言
最近在對RISC-V架構(gòu)比較感興趣,正好手頭有《RISC-V體系結(jié)構(gòu)編程與實踐》的書籍,就打算跟隨笨叔將這塊的知識學習起來,最開始當然是需要搭建一個基礎(chǔ)的實驗平臺,本來笨叔是貼心的提供了VMare的環(huán)境,奈何天生叛逆的我就不下他的大鏡像(我就不說我百度網(wǎng)盤沒會員),就拿手頭的wsl搭建了一套基于vscode的調(diào)試環(huán)境,可以直接一鍵調(diào)試,感覺還是蠻方便的。這里就進行一下記錄。
參考連接:
優(yōu)雅的調(diào)試在vscode上完美調(diào)試xv6
笨叔RISC-V官方示例代碼倉庫
文章目錄
- 前言
- WSL基礎(chǔ)環(huán)境的安裝
- 環(huán)境搭建
- 1. 基礎(chǔ)軟件包安裝
- 2.示例源碼的下載
- 問題解決
- PMP未開啟導致無法進入benos
- VScode調(diào)試問題
- 理解調(diào)試方法
- 配置lanuch.json
- 配置tasks.json
- 成果展示
- 小插曲
- .S文件不能打斷點
- 最后
WSL基礎(chǔ)環(huán)境的安裝
我曾經(jīng)寫過兩篇文章來完善這塊內(nèi)容,可以參考:
利用windows自帶的虛擬機安裝ubuntu的記錄用來完成基礎(chǔ)環(huán)境的安裝
[linux學習記錄]win下子系統(tǒng)ubuntu體驗記錄用來記錄其中遇到的問題以及對應的解決方案,會不定時更新
境搭建
1. 基礎(chǔ)軟件包安裝
QEMU Virt實驗平臺模擬的是一款通用的RISC-V開發(fā)板。
軟件環(huán)境:
- WSL(ubuntu22.04)
- qemu(QEMU emulator version 6.2.0 (Debian 1:6.2+dfsg-2ubuntu6.15))
- riscv64-linux-gnu-gcc-9 (Ubuntu 9.5.0-1ubuntu1~22.04) 9.5.0
- gdb-multiarch(GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1)
安裝參考指令:
sudo apt install qemu-system-misc libncurses5-dev build-essential git bison flex libssl-dev
sudo apt install gcc-9-riscv64-linux-gnu
sudo ln -s /usr/bin/riscv64-linux-gnu-gcc-9 /usr/bin/riscv64-linux-gnu-gcc #切換默認版本
sudo apt install gdb-multiarch
其他版本比較叛逆直接安裝,但是對于gcc的版本還是要慎重,之前編譯oe的5.10內(nèi)核的時候如果用過高的編譯器版本會導致鏈接出現(xiàn)問題,所以此處盡量與笨叔要求一致。
2.示例源碼的下載
git clone 笨叔RISC-V官方示例代碼倉庫
大致命令如下:
git clone https://github.com/runninglinuxkernel/riscv_programming_practice
cd riscv_programming_practice/chapter_2/benos
make
即可完成基礎(chǔ)命令的執(zhí)行。
運行命令如下:
make debug
然后就會看到如下的畫面
這個其實是可以正常跑并且進入到sbi內(nèi)了,只不過按照笨叔的說明文檔,我們遇到了PMP未開啟的問題導致無法進入到benos內(nèi)。所以接下來我們有兩個問題待解決:
- 如何解決PMP問題
- 如何使用vscode進行調(diào)試
問題解決
PMP未開啟導致無法進入benos
根據(jù)笨叔的介紹:
那我們就以毒攻毒,把第十章的一部分代碼直接CV過來不就好了?雖然我看不懂但是CV我在行(不是),這塊其實就先解決問題,等到學到了再認真研究就好了,初學者Hello個world還是有必要的。
根據(jù)我的觀察大概需要改4個文件:
//include/asm/csr.h
+/* Machine Memory Protection
+ * 暫時支持8個pmpcfg
+*/
+#define RISCV_XLEN 64
+#define MAX_CSR_PMP 8
+#define CSR_PMPCFG0 0x3a0
+#define CSR_PMPADDR0 0x3b0
+#define CSR_PMPADDR1 0x3b1
+#define CSR_PMPADDR2 0x3b2
+#define CSR_PMPADDR3 0x3b3
+#define CSR_PMPADDR4 0x3b4
+#define CSR_PMPADDR5 0x3b5
+#define CSR_PMPADDR6 0x3b6
+#define CSR_PMPADDR7 0x3b7
+#define PMP_R 0x01UL
+#define PMP_W 0x02UL
+#define PMP_X 0x04UL
+#define PMP_A 0x18UL
+#define PMP_A_TOR 0x08UL
+#define PMP_A_NA4 0x10UL
+#define PMP_A_NAPOT 0x18UL
+#define PMP_L 0x80UL
+#define PMP_RWX (PMP_R | PMP_W | PMP_X)
+#define PMP_SHIFT 2
+#ifdef __ASSEMBLY__
+#define __ASM_STR(x) x
+#else
+#define __ASM_STR(x) #x
+#endif
#define read_csr(csr) \({ \register unsigned long __v; \
- __asm__ __volatile__ ("csrr %0, " #csr \
+ __asm__ __volatile__ ("csrr %0, " __ASM_STR(csr) \: "=r" (__v) : \: "memory"); \__v; \#define write_csr(csr, val) \({ \unsigned long __v = (unsigned long)(val); \
- __asm__ __volatile__ ("csrw " #csr ", %0" \
+ __asm__ __volatile__ ("csrw "__ASM_STR(csr)", %0" \: : "rK" (__v) \: "memory"); \})
上面其實是diff的部分輸出,就是在對應文件進行修改,+就是增加,-就是刪除,對照修改即可。
另外需要將第十章的sbi_lib.c
以及sbi_lib.h
拷貝到對應目錄,以及對sbi_main.c進行如下修改:
//sbi/sbi_main.c{unsigned long val;+ /*
+ * 配置PMP
+ * 所有地址空間都可以訪問
+ */
+ sbi_set_pmp(0, 0, -1UL, PMP_RWX);
+ sbi_set_pmp(1, 0x80000000, 0x40000, PMP_RWX);
其中sbi_set_pmp
函數(shù)也需要從第十章的sbi_main.c
內(nèi)拷貝而來。
如果嫌棄麻煩的話也可以訪問我的gitee分支: https://gitee.com/gaoxinglei/risc-v_practice
VScode調(diào)試問題
由于我是采用WSL的實驗方式,VScode采用ssh遠程連接,需要以下插件:
- Remote-SSH(Host用于連接WSL)
- C/C++(Ubuntu22.04 用于代碼高亮跳轉(zhuǎn)等)
理解調(diào)試方法
書上以及相關(guān)資料采用的其實是使用gdb-multiarch
選擇選擇對應的elf進行調(diào)試的,使用remote的方式ip+port的形式。一般的調(diào)試形式如下:
gdb-multiarch benos.elf
target remote localhost:1234
然后我們可以配置這些手動的過程到launch.json
,并且觀察也更加方便。
配置lanuch.json
理解了上面的過程我們再來看這份lanuch.json就更加方便了
//launch.json
{"version": "0.2.0","configurations": [{"name": "riscvkernel","type": "cppdbg","request": "launch","program": "${fileDirname}/../benos.elf","args": [],"stopAtEntry": true,"cwd": "${workspaceFolder}","miDebuggerServerAddress": "127.0.0.1:1234","miDebuggerPath": "gdb-multiarch","environment": [],"externalConsole": false,"MIMode": "gdb","preLaunchTask": "riscvbuild","setupCommands": [{"description": "pretty printing","text": "-enable-pretty-printing","ignoreFailures": true,},],},]
}
其中的miDebuggerServerAddress
就是對應我們qemu的地址,然后miDebuggerPath
來選擇我們的gdb工具。program
對應我們的命令后接的要調(diào)試的程序,我們這里選擇benos.elf
,如果需要調(diào)試書籍里面的sbi
也可以換成對應的文件,再建一個調(diào)試即可,具體參考我的gitee。這里我發(fā)現(xiàn)參考代碼都是源碼上一級就是Makefile,所以我可以簡單的寫成../benos.elf
這種形式,其他的可能需要思考更合理的判斷方式。但注意到我們其實還有一個preLaunchTask
預處理,這塊就是幫助我們敲make解放雙手。
配置tasks.json
上面說到的preLaunchTask
,其實就是在這里進行定義的,具體內(nèi)容如下:
// tasks.json
{"version": "2.0.0","tasks": [{"label": "riscvbuild","type": "shell","isBackground": true,"command": "cd ${fileDirname}/..;make;make debug","problemMatcher": [{"pattern": [{"regexp": ".","file": 1,"location": 2,"message": 3}],"background": {"beginsPattern": ".*-kernel benos.elf -S -s","endsPattern": "."}}]}]
}
主要注意label要和launch.json文件進行對應,command就是編譯指令,我們這里也是因為目錄層級簡單可以這么簡單書寫。
beginsPattern
是屏幕識別到相關(guān)代碼才開始調(diào)試,否則認為編譯失敗,類似于下圖:
就是未識別到對應信息,我們這里采用Makefile會輸出的一句話即可
成果展示
經(jīng)過上面的配置,我們就可以對遠程gdb進行調(diào)試了,也符合我們?nèi)粘5氖褂昧晳T。
小插曲
這個地方不定時更新遇到的問題
.S文件不能打斷點
需要打開這個設(shè)置,注意打開的是WSL的設(shè)置而不是本地設(shè)置哦。
最后
相關(guān)源碼可以在 https://gitee.com/gaoxinglei/risc-v_practice進行獲取哦