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进行获取哦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/201707.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu部署jmeter与ant

为了整合接口自动化的持续集成工具,我将jmeter与ant都部署在了Jenkins容器中,并配置了build.xml 一、ubuntu部署jdk 1:先下载jdk-8u74-linux-x64.tar.gz,上传到服务器,这里上传文件用到了ubuntu 下的 lrzsz。 ubunt…

文件基础知识

计算机中的流:在C语言中将通过输入/输出设备(键盘、内存、显示器、网络等)之间的数据传输抽象表述为“流”。 1、文本流和二进制流 在文本流中输入输出的数据是一系列的字符,可以被修改在二进制流中输入输出数据是一系列字节&am…

C++初阶(十三)vector

📘北尘_:个人主页 🌎个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上,不忘来时的初心 文章目录 一、vector的介绍二、vector的模拟实现1、模拟实现2、测试结果 一、vector的介绍 vector的文…

基于YOLOv5的人群计数系统设计系统

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介系统概述系统功能核心技术系统架构系统优势 二、功能三、系统四. 总结  总结 一项目简介 基于YOLOv5的人群计数系统设计是一个非常有趣且具有挑战性的项目…

html5各行各业官网模板源码下载(1)

文章目录 1.来源2.源码模板2.1 HTML5白色简洁设计师网站模板 作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/134682321 html5各行各业官网模板源码下载,这个主题覆盖各行业的html官网模板,效果模…

软件设计师——法律法规(一)

📑前言 本文主要是【法律法规】——软件设计师法律法规的题目,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是听风与他🥇 ☁️博客首页:CSDN主页听风与他 🌄每日…

【LeetCode刷题】数组篇1

🎇数组简单题Part 🌈 开启LeetCode刷题之旅 🌈 文章目录 🎇数组简单题Part🍰1.两数之和👑思路分析1.暴力法2.哈希表法 🍰26.删除有序数组中的重复项👑思路分析1.双指针2.利用vector…

微信小程序上传报错TypeError: Failed to fetch

上传之后报message:TypeError: Failed to fetch这个错误。 关掉项目 > 选择项目的ide界面右上有个齿轮设置 > 代理

【面试】css预处理器之sass(scss)

目录 为什么引入css预处理器 可读性 嵌套:关系明朗 选择器 属性 伪类‘’ 变量:语义明确 默认变量:美元符号 $ 变量名:值 !default 全局变量::global { $global-x: } 变量插值:#{} map键值对:$…

函数保留凸性的一些运算,限制为一条线

凸优化在学术研究中非常重要,经常遇到的问题是证明凸性。常规证明凸性的方式是二阶导数的黑塞矩阵为半正定,或者在一维函数时二阶导数大于等于零。但很多时候的数学模型并不那么常规、容易求导的,若能够知道一些保留凸性的运算,将…

Zemax光学设计——单透镜设计

单透镜系统参数: 入瞳直径:20mm F/#(F数):10 全视场:10 波长:587nm 材料:BK7 优化方向:最佳均方根光斑直径 设计步骤 一、单透镜系统参数 步骤一:入…

红黑树的插入

一.红黑树的特征 红黑树是二叉搜索树红黑树分为内部结点和外部结点,将空指针视为外部结点,其它结点视为内部结点根结点和外部结点都是黑色从根结点到外部结点的路径上不能有连续的红结点从根结点到外部结点的路径上黑结点的数目相同从根结点到外部结点的最长路径的长度不超过最…

Spring Framework远程代码执行漏洞 CVE-2022-22965 漏洞复现

Spring Framework远程代码执行漏洞 CVE-2022-22965 漏洞复现和相关利用工具 名称: Spring Framework 远程命令执行漏洞 描述: Spring core是Spring系列产品中用来负责发现、创建并处理bean之间的关系的一个工具包,是一个包含Spring框架基本的核心工具包&#xff0…

爬虫代理技术与构建本地代理池的实践

爬虫中代理的使用: 什么是代理 代理服务器 代理服务器的作用 就是用来转发请求和响应 在爬虫中为何需要使用代理? 隐藏真实IP地址:当进行爬取时,爬虫程序会发送大量的请求到目标网站。如果每个请求都使用相同的IP地址&#xff…

深入Python元编程:了解声明与初始化定制元类

更多资料获取 📚 个人网站:ipengtao.com 简介 在Python中,元编程是指在运行时创建或定制类的编程。元类是Python中最强大的元编程工具之一,允许您控制类的创建过程。元类是类的类,它控制类的实例化,允许您…

【软件测试学习】—软件测试模型(二)

【软件测试学习】—软件测试模型(二) 我 | 在这里 👩‍🦰👩‍🦰 读书 | 长沙 ⭐计算机科学与技术 ⭐ 本科 【2024届】 🎃🎃 爱好 | 旅游、跑步、网易云、美食、摄影 🎖️…

修复 MyBatis 中空值引起的 SQL 语法错误

修复 MyBatis 中空值引起的 SQL 语法错误 背景 最近在查看别人的项目代码时&#xff0c;遇到了一个问题&#xff1a;数据库中的数据为空。在调试过程中&#xff0c;发现问题出现在调用 MyBatis 中的方法&#xff1a;listByIds(Collection<? extends Serializable> idL…

QML Column Row 属性 pyside6

在 QML 中&#xff0c;Column 和 Row 是常用的布局元素&#xff0c;用于水平&#xff08;Row&#xff09;和垂直&#xff08;Column&#xff09;排列它们的子元素。以下是这两个元素的主要属性列表&#xff1a; Column 属性 spacing: 子元素之间的垂直间隔。width 和 height:…

F22服装管理软件系统 前台任意文件上传漏洞复现

0x01 产品简介 F22服装管理软件系统是广州锦铭泰软件科技有限公司一款专为服装行业开发的综合性管理软件。该产品旨在帮助服装企业实现全面、高效的管理&#xff0c;提升生产效率和经营效益。 0x02 漏洞概述 F22服装管理软件系统UploadHandler.ashx接口处存在任意文件上传漏洞…

Web实现悬浮球-可点击拖拽禁止区域

这次要实现的是这种效果&#xff0c;能够在页面上推拽和点击的&#xff0c;拖拽的话&#xff0c;就跟随鼠标移动&#xff0c;点击的话&#xff0c;就触发新的行为&#xff0c;当然也有指定某些区域不能拖拽&#xff0c;接下来就一起来看看有什么难点吧~ 需要监听的鼠标事件 既…
最新文章