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.mzph.cn/news/182855.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

消息中间件——RabbitMQ(七)高级特性 2

前言 上一篇消息中间件——RabbitMQ(七)高级特性 1中我们介绍了消息如何保障100%的投递成功?,幂等性概念详解,在海量订单产生的业务高峰期,如何避免消息的重复消费的问题?,Confirm确认消息、Return返回消息。这篇我们…

作为用户,推荐算法真的是最优解么?

前言 众所周知,随着互联网技术的发展,推荐算法也越来越普及。无论是购物网站、社交媒体平台还是在线影视平台,推荐算法已成为用户获取相关信息的主要途径。据悉,近期GitHub决定结合算法推荐,将“Following”和“For Yo…

uniapp打包ios有时间 uniapp打包次数

我们经常用的解决方案有,分包,将图片上传到服务器上,减少插件引入。但是还有一个方案好多刚入门uniapp的人都给忽略了,就是在源码视图中配置,开启分包优化。 1.分包 目前微信小程序可以分8个包,每个包的最大存储是2M,也就是说你文件总体的大小不能超过16M,每个包的大…

刷题学习记录

[SWPUCTF 2021 新生赛]sql 进入环境 查看源码,发现是get传参且参数为wllm fuzz测试,发现空格,,and被过滤了 同样的也可以用python脚本进行fuzz测试 import requests fuzz{length ,,handler,like,select,sleep,database,delete,h…

【MySQL】常用内置函数:数值函数 / 字符串函数 / 日期函数 / 其他函数

文章目录 数值函数round():四舍五入ceiling():上限函数floor():地板函数abs():计算绝对值rand():生成0-1的随机浮点数 字符串函数length():获取字符串中的字符数upper() / lower():将字符串转化…

ThinkPHP的方法接收json数据问题

第一次接触到前后端分离开发,需要在后端接收前端ajax提交的json数据,开发基于ThinkPHP3.2.3框架。于是一开始习惯性的直接用I()方法接收到前端发送的json数据,然后用json_decode()解析发现结果为空!但是打印出还未解析的值却打印得…

MySQL事务日志

文章目录 1. redo日志 1. redo日志 口述:redo log 日志其实保证了ACID中的持久性,就是说当事务commit后,那么相应的修改呀更新这些操作其实都会记录到redo log中,其实这里的操作还是区别于redis中的aof中,它不是具体的…

文件中找TopK问题

目录 1.解题思路2.创建一个文件并在文件中写入数据3.为什么要建立小堆而不建立大堆?4.如何在现有的数据中建立适合的大堆?5.代码实现 1.解题思路 TopK问题即是在众多数据中找出前K大的值,则可以根据堆的性质来实现,但在使用堆之前…

Guacamole简介及centos7下搭建教程

简介 Guacamole是一款开源的远程桌面框架,它允许用户通过Web浏览器远程访问计算机资源。 官网地址:Apache Guacamole™ 官方文档:Installing Guacamole natively — Apache Guacamole Manual v1.5.3 架构 组件描述客户端浏览器用户通过支…

数据结构 / day02作业

1. 有若干个学校人员的信息,包括学生和教师。 其中学生的数据包括:姓名、性别、职业s/S、分数。 教师的数据包括:姓名、性别、职业t/T、职务。 1,定义指针指向堆区内存 2.循环输入 3.计算老师的个数 4.计算学生的平均值 5.循环输出 6释放堆区空间 #inc…

不同类型的开源许可证

不同类型的开源许可证 什么是开源许可证 最简单的解释是,开源许可证是计算机软件和其他产品的许可证,允许在定义的条款和条件下使用、修改或共享源代码、蓝图或设计。开源并不意味着该软件可以根据需要使用、复制、修改和分发。根据开源许可证的类型&a…

【unity实战】基于权重的随机事件(附项目源码)

文章目录 前言开始一、简单的使用二、完善各种事件1. 完善生成金币事件2. 完善生成敌人事件敌人3. 完善生成药水事件 最终效果参考源码完结 前言 随机功能和UnityEvent前面其实我们都已经做过了,但是随机UnityEvent事件要怎么使用呢?这里就来举一个例子…

由于找不到steam_api64.dll如何修复?steam_api64.dll丢失多种解决方法

steam_api64.dll文件介绍 steam_api64.dll是Steam平台的一个关键组件,主要用于支持Steam客户端和相关游戏的应用程序。这个文件缺失或损坏会导致Steam及相关游戏无法正常运行。它位于Steam安装目录的bin子文件夹中。 steam_api64.dll丢失的原因 系统误删&#xf…

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

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

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

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

.net core 封装一个统一的返回结果

public class ApiResponse<T> { public bool Success { get; set; } public T? Data { get; set; } public string? Message { get; set; } public ApiResponse(bool success, T? data, string errorMessage "") { …

矩阵快速幂及应用实战[C/C++]

矩阵快速幂 矩阵快速幂可以用来优化递推问题&#xff0c;如状态机DP&#xff0c;需要一丢丢线性代数里面矩阵的概念&#xff0c;只需要知道简单的矩阵乘法&#xff0c;结合我们普通的二分快速幂就能很快的掌握矩阵快速幂。 问题引入 三步问题。有个小孩正在上楼梯&#xff0c;楼…

一文学会Aiohttp

一、什么是aiohttp库 aiohttp库官网&#xff1a;https://docs.aiohttp.org/en/stable/ aiohttp是一个Python的HTTP客户端/服务器框架&#xff0c;它基于asyncio库实现异步编程模型&#xff0c;可以支持高性能和高并发的HTTP通信。aiohttp用于编写异步的Web服务器、Web应用程序…

【Vulnhub 靶场】【Coffee Addicts: 1】【简单-中等】【20210520】

1、环境介绍 靶场介绍&#xff1a;https://www.vulnhub.com/entry/coffee-addicts-1,699/ 靶场下载&#xff1a;https://download.vulnhub.com/coffeeaddicts/coffeeaddicts.ova 靶场难度&#xff1a;简单 - 中等 发布日期&#xff1a;2021年5月20日 文件大小&#xff1a;1.3 …

【数值计算方法(黄明游)】常微分方程初值问题的数值积分法:欧拉方法(向后Euler)【理论到程序】

文章目录 一、数值积分法1. 一般步骤2. 数值方法 二、欧拉方法&#xff08;Euler Method&#xff09;1. 向前欧拉法&#xff08;前向欧拉法&#xff09;2. 向后欧拉法&#xff08;后向欧拉法&#xff09;a. 基本理论b. 算法实现 常微分方程初值问题的数值积分法是一种通过数值方…