开发一个RISC-V上的操作系统(一)—— 环境搭建

news2024/11/16 1:23:53

在前面我们使用Verilog实现了一个简易的RISC-V处理器,并且能烧录到板子上跑一些简单C程序,传送门:

RISC-V处理器的设计与实现(一)—— 基本指令集_risc_v处理器_Patarw_Li的博客-CSDN博客

RISC-V处理器的设计与实现(二)—— CPU框架设计_Patarw_Li的博客-CSDN博客

RISC-V处理器的设计与实现(三)—— 上板验证_Patarw_Li的博客-CSDN博客

接下来我会开始编写一个riscv上的简易操作系统,然后放到我们做的riscv处理器上运行,参考的资料和视频链接如下:

[完结] 循序渐进,学习开发一个RISC-V上的操作系统 - 汪辰 - 2021春 

riscv-operating-system-mooc: 开放课程《循序渐进,学习开发一个 RISC-V 上的操作系统》配套教材代码仓库。mirror to https://github.com/plctlab/riscv-operating-system-mooc

一、开发环境配置

使用的开发环境如下:

$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04.2 LTS
Release:	20.04
Codename:	focal

$ uname -r
5.15.0-76-generic

安装Ubuntu 20.04官方提供的 GNU工具链和 QEMU 模拟器:

sudo apt update
sudo apt install build-essential gcc make perl dkms git gcc-riscv64-unknown-elf gdb-multiarch qemu-system-misc

其中 gcc-riscv64-unknown-elf 就是我们的交叉编译工具,可以把程序编译成riscv上的可执行文件; gdb为debug工具;qemu是一个模拟器,可以模拟出riscv系统。

二、测试

在配置好开发环境后,我们可以用一个程序来测试一下,下面是前面用到的led流水灯程序,我们会在Ubuntu上把这个C程序利用交叉编译工具链编译成二进制.bin文件,然后通过串口将.bin文件烧录到处理器的rom中:

// led流水灯程序
int main(){
    int* point;
    int sum1 = 1; // 0001
    int sum2 = 2; // 0010
    int sum4 = 8; // 1000
    point = (int*) 0x00000000;
    *point = sum1;

    while(1){
        // 第一个灯亮起
        *point = sum1;
        for(int i = 0; i < 1000000; i++); // delay

        // 第二个灯亮起
        *point = sum2;
        for(int i = 0; i < 1000000; i++); // delay

        //第四个灯亮起
        *point = sum4;
        for(int i = 0; i < 1000000; i++); // delay
    }
    return 0;
}

然后我们需要编译我们的led程序: 

riscv64-unknown-elf-gcc -c -nostdlib -march=rv32i -mabi=ilp32 led_ctr.c -o main.o
  • -c 选项是编译、汇编到目标代码,但不进行链接。
  • -nostdlib 告诉编译器不要把标准库编译进去。
  • -march=rv32i -mabi=ilp32 用于指定指令集架构和 ABI,因为我们只实现了部分整数指令,所以使用rv32i。

编译后,我们可以得到 main.o,它是一个 ELF 文件。我们只需要 .text 部分的机器指令,所以用 objcopy 对它进行处理:

riscv64-unknown-elf-objcopy -O binary -j .text main.o main.bin
  • -O binary 选项用于输出纯二进制文件。
  • -j .text 是告诉它只保留 .text 部分。

经过处理,生成的二进制文件只含有机器指令。但此时的程序并不能直接运行。我们用 objdump 进行反编译,看看生成的汇编是怎么样的: 

riscv64-unknown-elf-objdump -D -b binary main.bin -mriscv

然后编写串口上位机发送Python程序(串口发送程序已经更新至gitee仓库:cpu_prj: 一个基于RISC-V指令集的CPU实现):

import serial
 
try:
    ser = serial.Serial("COM3", 9600, timeout=0.5)
    if ser.is_open:
        print("COM3" + " open success!")
        with open('./main.bin', 'rb') as f:
            a = f.read()
        print("sending bin file")
        count = ser.write(a)
        print("send over, the number of byte: ", count)
 
except Exception as e:
    print("---error---: ", e)

# 如果报错ModuleNotFoundError: No module named 'serial',则执行 pip install pyserial

将编译好的.bin文件移动到和串口发送程序同目录下,记得修改串口,我这里用的串口为COM3,将烧录了riscv处理器的开发板与pc连接,然后点击运行,然后点击板子上的复位按键,即可看到3个流水灯开始轮流闪烁:

知道如何烧录程序到处理器上的话,之后操作系统的开发和验证都会方便很多。

三、开发前需要了解的知识

在进行操作系统的开发前,你应该要熟悉如下知识:

  1. 交叉编译
  2. 调试器GDB
  3. 模拟器QEMU
  4. 项目构造工具Make

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

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

相关文章

电子器件系列41:扁平高压电阻

这种电阻和其他的高压电阻不同&#xff0c;不是绕线电阻而是陶瓷电阻 找到一个大神&#xff0c;他的专栏也得很详细了&#xff0c;贴在这里 https://blog.csdn.net/wkezheng/category_12059870.html 阻容感基础03&#xff1a;电阻器分类&#xff08;1&#xff09;-片式电阻器…

如何快速判断是否在容器环境

在渗透测试过程中&#xff0c;我们的起始攻击点可能在一台虚拟机里或是一个Docker环境里&#xff0c;甚至可能是在K8s集群环境的一个pod里&#xff0c;我们应该如何快速判断当前是否在容器环境中运行呢&#xff1f; 当拿到shell权限&#xff0c;看到数字和字母随机生成的主机名…

软考A计划-系统集成项目管理工程师-项目范围管理(二)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…

HTML、Markdown、Word、Excel等格式的文档转换为PDF

工具&#xff1a;gotenberg&#xff0c;docker部署 github&#xff1a;https://github.com/gotenberg/gotenberg 文档&#xff1a;https://gotenberg.dev/docs/about https://gotenberg.dev/docs/modules/libreoffice docker运行&#xff1a; docker run -d --rm -p 3000:30…

kubernete部署prometheus监控sring-boot程序

目录 1、kubernete集群环境以及prometheus基础环境 2、kubernetes监控集群内部的spring-boot程序 2.1、application.yml系统配置&#xff0c;endpoints相关设置 2.2、引入监控的相关依赖文件 pom.xml &#xff0c;主要是spring-boot-starter-actuator和micrometer-registr…

ModaHub魔搭社区:向量数据库Milvus产品问题(二)

目录 为什么向量距离计算方式是内积时&#xff0c;搜索出来的 top1 不是目标向量本身&#xff1f; 对集合分区的查询是否会受到集合大小的影响&#xff0c;尤其在集合数据量高达一亿数据量时&#xff1f; 如果只是搜索集合中的部分分区&#xff0c;整个集合的数据会全部加载…

表单(form) post 方式提交时的编码与乱码(上)

在上一篇章中谈论了表单以 get 提交时的编码与乱码问题, 这一章中将讨论以 post 方式提交时的编码与乱码问题. 在前面也同时提到, 表单有一个叫 enctype 的属性, 它有两个值, application/x-www-form-urlencoded 和 multipart/form-data. 这一属性实际只对 post 方式起作用, …

@Configuration 和 @Component 的区别 ,别再瞎用了!

一句话概括就是 Configuration 中所有带 Bean 注解的方法都会被动态代理&#xff0c;因此调用该方法返回的都是同一个实例。 理解&#xff1a;调用Configuration类中的Bean注解的方法&#xff0c;返回的是同一个示例&#xff1b;而调用Component类中的Bean注解的方法&#xff…

List, Set, Ordered-SetHash

前言 本文小结Redis中List&#xff0c;Set&#xff0c;ZSet和Hash四种数据类型的&#xff0c;基本特点&#xff0c;使用场景和实现方式。 一、List 1. 基本特点 a. 作为数组&#xff0c;基于下标索引操作, 但支持正向索引和反向索引; b. 作为链表, 支持高效插入&#xff1b…

信息安全-应用安全-定制化白盒检测 | 越权漏洞治理分享

目录 一、背景 二、面临的挑战 三、治理目标 四、解决方案 4.1 系统架构 4.2 鉴权函数 4.3 告警识别 4.4 鉴权分 五、未来的白盒检测方向 六、越权治理 七、小结 一、背景 在漏洞扫描领域&#xff0c;主流的扫描方式分为黑盒扫描和白盒扫描&#xff0c;其中源代码安…

MYSQL-主键外键约束

主键语法: 在创建表指定列数据类型时在后面加(可以结合AUTO_INCREMENT) PRIMARY KEY 主键要短&#xff0c;可唯一标识记录&#xff0c;且永不改变。 外键语法: 第一个column_name是被指定外键的本表列名 table_name是主键的表名 第二个column_name是主键列名 FOREIGN KE…

使用DataX同步数据(小白步骤,一看就懂)

详细文档说明,及图文讲解 ​​​​​​datax的异构数据同步资源-CSDN文库 Datax简介 下载datax软件,从开源镜像下载

python接口自动化(七)--状态码详解对照表(详解)

简介 我们为啥要了解状态码&#xff0c;从它的作用&#xff0c;就不言而喻了。如果不了解&#xff0c;我们就会像个无头苍蝇&#xff0c;横冲直撞。遇到问题也不知道从何处入手&#xff0c;就是想找别人帮忙&#xff0c;也不知道是找前端还是后端的工程师。 状态码的作用是&…

串口接收不定长数据的实现

使用串口进行数据的收发在嵌入式产品中是很常用的一种通信方式&#xff0c;因为串口的简单使用&#xff0c;很容易就被选为产品中数据交互的通信手段。 基于串口进行开发的功能有很多&#xff0c;比如同类/不同类产品之间的通信&#xff0c;RS485通信&#xff0c;RS232通信方式…

(二)线程的六种状态及上下文切换

&#xff08;二&#xff09;线程的六种状态及上下文切换 2.1 操作系统中线程的状态及切换2.2 Java 中线程的六种状态01、NEW&#xff08;线程尚未启动&#xff09;02、RUNNABLE&#xff08;运行中&#xff09;03、BLOCKED&#xff08;阻塞状态&#xff09;04、WAITING&#xff…

移动端微信小程序学习

目录 小程序和web端的不同 小程序的宿主环境 通信 组件 视图容器​编辑 text组件 button image ​编辑 API api三大分类 模板语法 事件绑定 ​编辑 事件传参​编辑 bindinput 条件渲染 列表渲染 ​编辑 全局配置 window 页面配置 网络数据请求 ​编辑 GET请求 POST…

近轴成像的相关性质

本文介绍薄透镜近轴成像的一些性质&#xff0c;所谓近轴成像&#xff0c;就是入射光线非常靠近光轴&#xff0c;意味着入射角很小。在介绍这些性质之前&#xff0c;我们先来看看三角函数的泰勒展开&#xff1a; sin ⁡ θ θ − θ 3 3 ! θ 5 5 ! − θ 7 7 ! . . . \sin{\…

#10047. 「一本通 2.2 练习 3」似乎在梦中见过的样子(内附封面)

题目描述 原题来自&#xff1a;2014 年湖北省队互测 Week2 「Madoka&#xff0c;不要相信 QB&#xff01;」伴随着 Homura 的失望地喊叫&#xff0c;Madoka 与 QB 签订了契约。 这是 Modoka 的一个噩梦&#xff0c;也同时是上个轮回中所发生的事。为了使这一次 Madoka 不再与…

JVM类加载机制-JVM(一)

我们运行一个.class文件&#xff0c;windows下的java.exe调用底层jvm.dll文件创建java虚拟机&#xff08;c实现&#xff09;。创建一个引导类加载器实例&#xff08;c实现&#xff09;C调用java代码Launcher&#xff0c;该类创建其他java类加载器。Launcher.getClassLoader()调…

【算法】最长公共子序列编辑距离(两个序列之间的DP)

文章目录 最长公共子序列&#xff08;LCS&#xff09;编辑距离&#xff08;Edit Distance&#xff09;总结相关题目练习583. 两个字符串的删除操作 https://leetcode.cn/problems/delete-operation-for-two-strings/712. 两个字符串的最小ASCII删除和 https://leetcode.cn/prob…