当前位置: 首页 > news >正文

VSCODE+QEMU+WSL调试RISCV代码(SBI、kernel)

在这里插入图片描述

前言

最近在对RISC-V架构比较感兴趣,正好手头有《RISC-V体系结构编程与实践》的书籍,就打算跟随笨叔将这块的知识学习起来,最开始当然是需要搭建一个基础的实验平台,本来笨叔是贴心的提供了VMare的环境,奈何天生叛逆的我就不下他的大镜像(我就不说我百度网盘没会员),就拿手头的wsl搭建了一套基于vscode的调试环境,可以直接一键调试,感觉还是蛮方便的。这里就进行一下记录。
参考连接:
优雅的调试在vscode上完美调试xv6
笨叔RISC-V官方示例代码仓库


文章目录

  • 前言
  • WSL基础环境的安装
  • 环境搭建
    • 1. 基础软件包安装
    • 2.示例源码的下载
  • 问题解决
    • PMP未开启导致无法进入benos
    • VScode调试问题
      • 理解调试方法
      • 配置lanuch.json
      • 配置tasks.json
      • 成果展示
    • 小插曲
      • .S文件不能打断点
    • 最后


WSL基础环境的安装

我曾经写过两篇文章来完善这块内容,可以参考:
利用windows自带的虚拟机安装ubuntu的记录用来完成基础环境的安装
[linux学习记录]win下子系统ubuntu体验记录用来记录其中遇到的问题以及对应的解决方案,会不定时更新
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/95c97de674eb434da495e9cef2202a7a.png在这里插入图片描述


环境搭建

1. 基础软件包安装

QEMU Virt实验平台模拟的是一款通用的RISC-V开发板。
软件环境:

  • 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内核的时候如果用过高的编译器版本会导致链接出现问题,所以此处尽量与笨叔要求一致。

2.示例源码的下载

git clone 笨叔RISC-V官方示例代码仓库
大致命令如下:

git clone https://github.com/runninglinuxkernel/riscv_programming_practice
cd riscv_programming_practice/chapter_2/benos
make

即可完成基础命令的执行。
运行命令如下:

make debug

然后就会看到如下的画面
在这里插入图片描述
这个其实是可以正常跑并且进入到sbi内了,只不过按照笨叔的说明文档,我们遇到了PMP未开启的问题导致无法进入到benos内。所以接下来我们有两个问题待解决:

  1. 如何解决PMP问题
  2. 如何使用vscode进行调试

问题解决

PMP未开启导致无法进入benos

根据笨叔的介绍:
在这里插入图片描述
那我们就以毒攻毒,把第十章的一部分代码直接CV过来不就好了?虽然我看不懂但是CV我在行(不是),这块其实就先解决问题,等到学到了再认真研究就好了,初学者Hello个world还是有必要的。
根据我的观察大概需要改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函数也需要从第十章的sbi_main.c内拷贝而来。
如果嫌弃麻烦的话也可以访问我的gitee分支: https://gitee.com/gaoxinglei/risc-v_practice


VScode调试问题

由于我是采用WSL的实验方式,VScode采用ssh远程连接,需要以下插件:

  • Remote-SSH(Host用于连接WSL)
  • C/C++(Ubuntu22.04 用于代码高亮跳转等)

理解调试方法

书上以及相关资料采用的其实是使用gdb-multiarch选择选择对应的elf进行调试的,使用remote的方式ip+port的形式。一般的调试形式如下:

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对应我们的命令后接的要调试的程序,我们这里选择benos.elf,如果需要调试书籍里面的sbi也可以换成对应的文件,再建一个调试即可,具体参考我的gitee。这里我发现参考代码都是源码上一级就是Makefile,所以我可以简单的写成../benos.elf这种形式,其他的可能需要思考更合理的判断方式。但注意到我们其实还有一个preLaunchTask预处理,这块就是帮助我们敲make解放双手。

配置tasks.json

上面说到的preLaunchTask,其实就是在这里进行定义的,具体内容如下:

// 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是屏幕识别到相关代码才开始调试,否则认为编译失败,类似于下图:
在这里插入图片描述
就是未识别到对应信息,我们这里采用Makefile会输出的一句话即可

成果展示

经过上面的配置,我们就可以对远程gdb进行调试了,也符合我们日常的使用习惯。
在这里插入图片描述

小插曲

这个地方不定时更新遇到的问题

.S文件不能打断点

需要打开这个设置,注意打开的是WSL的设置而不是本地设置哦。
在这里插入图片描述

最后

相关源码可以在 https://gitee.com/gaoxinglei/risc-v_practice进行获取哦

相关文章:

VSCODE+QEMU+WSL调试RISCV代码(SBI、kernel)

前言 最近在对RISC-V架构比较感兴趣,正好手头有《RISC-V体系结构编程与实践》的书籍,就打算跟随笨叔将这块的知识学习起来,最开始当然是需要搭建一个基础的实验平台,本来笨叔是贴心的提供了VMare的环境,奈何天生叛逆的…...

二叉树(判断是否为对称二叉树)

题目(力扣): 观察题目,只需判断该二叉树是否对称。 判断二叉树是否对称,就可以换位去判断该二叉树的左子树和右子树是否对称。 这时就可以写一个辅助函数来方便判断。 该函数是判断两颗树是否镜像对称,这…...

STM32开发学习(地址映射)

LED灯代码: #define PERIPH_BASE ((unsigned int)0x40000000)#define AHB1PERIPH_BASE (PERIPH_BASE 0x00020000)#define GPIOF_BASE (AHB1PERIPH_BASE 0x1400)#define GPIOF_MODER *(unsigned int*)(GPIOF_BASE0x00) #define GPIOF_BSRR *(uns…...

证明E(X+Y) =E(X) + E(Y)

E(XY) E(X) E(Y)的成立是不需要X和Y相互独立的!!! 离散型随机变量 E ( X Y ) ∑ i 1 n ∑ j 1 m ( x i y j ) P { X x i , Y y j } ∑ i 1 n ∑ j 1 m x i P { X x i , Y y j } ∑ i 1 n ∑ j 1 m y j P { X x i , Y y j …...

ClickHouse入门手册1.0

1、数据类型 1.1 整数类型: ClickHouse中整型数据均为固定长度(可以设置长度参数,但是会被忽略),整型包括有符号整型和无符号整型。 有符号整型:Int8,Int16,Int32,Int64,Int128,Int256 无符号整型:UInt8,UInt16,UI…...

10个火爆的设计素材网站推荐

所谓聪明的女人没有米饭很难做饭,设计师也是如此。如何找到优秀的设计材料是每个设计师的痛点,国内材料网站收费,但也限制使用范围和期限,大多数外国设计网站不能打开或需要特殊互联网使用,有一定的安全风险。 作为一…...

SQL注入 - CTF常见题型

文章目录 题型一 ( 字符型注入 )题型二 ( 整数型注入 )题型三 ( 信息收集SQL注入)题型四 ( 万能密码登录 )题型五 ( 搜索型注入文件读写 )题型六 &#xff08…...

android keylayout键值适配

1、通过getevent打印查看当前keyevent数字对应事件和物理码 2、dumpsys input 查看输入事件对应的 KeyLayoutFile: /system/usr/keylayout/Vendor_6080_Product_8060.kl 3、通过物理码修改键值映射,修改/system/usr/keylayout/目录下的文件...

python读取excel自动化生成sql建表语句和java实体类字段

1、首先准备一个excel文件: idtypenameidint学号namestring姓名ageint年龄sexstring性别weightdecimal(20,4)体重scoredecimal(20,4)分数 2、直接生成java字段和注释: import pandas as pddf pd.read_excel(test.xlsx, sheet_nameSheet1)for i in ran…...

Unity求向量A在平面L上的投影向量

如题&#xff1a;求向量A在平面L上的投影向量(图左) 即求 其实等价于求向量&#xff0c;那在中&#xff0c;,所以只需要求即可 而就是在平面L的法向量的投影坐标&#xff0c;所以代码就是 /// <summary>/// 求向量A在平面B上的投影向量/// </summary>/// <para…...

人机交互2——任务型多轮对话的控制和生成

1.自然语言理解模块 2.对话管理模块 3.自然语言生成模块...

【数据结构】八大排序 (三)

目录 前言&#xff1a; 快速排序 快速排序非递归实现 快速排序特性总结 归并排序 归并排序的代码实现 归并排序的特性总结 计数排序 计数排序的代码实现 计数排序的特性总结 前言&#xff1a; 前文快速排序采用了递归实现&#xff0c;而递归会开辟函数栈帧&#xff0…...

Redis 命令处理过程

我们知道 Redis 是一个基于内存的高性能键值数据库, 它支持多种数据结构, 提供了丰富的命令, 可以用来实现缓存、消息队列、分布式锁等功能。 而在享受 Redis 带来的种种好处时, 是否曾好奇过 Redis 是如何处理我们发往它的命令的呢&#xff1f; 本文将以伪代码的形式简单分析…...

python爬虫进阶教程之如何正确的使用cookie

文章目录 前言一、获取cookie二、程序实现三、动态获取cookie四、其他关于Python爬虫技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料六、Pytho…...

【hacker送书第4期】推荐4本Java必读书籍(各送一本)

第4期图书推荐 Java从入门到精通&#xff08;第7版&#xff09;内容简介参与方式 项目驱动零基础学Java内容简介参与方式 深入理解Java高并发编程内容简介参与方式 Java编程讲义内容简介参与方式 Java从入门到精通&#xff08;第7版&#xff09; 内容简介 《Java从入门到精通&…...

[密码学]DES

先声明两个基本概念 代换&#xff08;substitution&#xff09;,用别的元素代替当前元素。des的s-box遵循这一设计。 abc-->def 置换&#xff08;permutation&#xff09;&#xff0c;只改变元素的排列顺序。des的p-box遵循这一设计。 abc-->bac DES最核心的算法就是…...

15个超级实用的Python操作,肯定有你意想不到的!

文章目录 1&#xff09;映射代理&#xff08;不可变字典&#xff09;2&#xff09;dict 对于类和对象是不同的3) any() 和 all()4) divmod()5) 使用格式化字符串轻松检查变量6) 我们可以将浮点数转换为比率7) 用globals()和locals()显示现有的全局/本地变量8) import() 函数9) …...

GitHub上8个强烈推荐的 Python 项目

文章目录 前言1. Manim2. DeepFaceLab3. Airflow4. GPT-25. XSStrike6. 谷歌图片下载7. Gensim8. SocialMapper总结关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③…...

什么是依赖倒置原则

1、什么是依赖倒置原则 依赖倒置原则&#xff08;Dependency Inversion Principle&#xff0c;DIP&#xff09;是指高层模块不应该依赖于低层模块&#xff0c;它们都应该依赖于抽象。换句话说&#xff0c;具体类之间的依赖关系应该尽可能减少&#xff0c;而抽象类或接口之间的…...

异常数据检测 | Python实现oneclassSVM模型异常数据检测

支持向量机(SVM)的异常检测 SVM通常应用于监督式学习,但OneClassSVM[8]算法可用于将异常检测这样的无监督式学习,它学习一个用于异常检测的决策函数其主要功能将新数据分类为与训练集相似的正常值或不相似的异常值。 OneClassSVM OneClassSVM的思想来源于这篇论文[9],SVM使用…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

未授权访问事件频发,我们应当如何应对?

在当下&#xff0c;数据已成为企业和组织的核心资产&#xff0c;是推动业务发展、决策制定以及创新的关键驱动力。然而&#xff0c;未授权访问这一隐匿的安全威胁&#xff0c;正如同高悬的达摩克利斯之剑&#xff0c;时刻威胁着数据的安全&#xff0c;一旦触发&#xff0c;便可…...

ffmpeg(三):处理原始数据命令

FFmpeg 可以直接处理原始音频和视频数据&#xff08;Raw PCM、YUV 等&#xff09;&#xff0c;常见场景包括&#xff1a; 将原始 YUV 图像编码为 H.264 视频将 PCM 音频编码为 AAC 或 MP3对原始音视频数据进行封装&#xff08;如封装为 MP4、TS&#xff09; 处理原始 YUV 视频…...

MyBatis-Plus 常用条件构造方法

1.常用条件方法 方法 说明eq等于 ne不等于 <>gt大于 >ge大于等于 >lt小于 <le小于等于 <betweenBETWEEN 值1 AND 值2notBetweenNOT BETWEEN 值1 AND 值2likeLIKE %值%notLikeNOT LIKE %值%likeLeftLIKE %值likeRightLIKE 值%isNull字段 IS NULLisNotNull字段…...

jieba实现和用RNN实现中文分词的区别

Jieba 分词和基于 RNN 的分词在技术路线、实现机制、性能特点上有显著差异&#xff0c;以下是核心对比&#xff1a; 1. 技术路线对比 维度Jieba 分词RNN 神经网络分词范式传统 NLP&#xff08;规则 统计&#xff09;深度学习&#xff08;端到端学习&#xff09;核心依赖词典…...