从头开发一个RISC-V的操作系统(四)嵌入式开发介绍
文章目录
- 前提
- 嵌入式开发
- 交叉编译
- GDB调试,QEMU,MAKEFILE
- 练习
目标:通过这一个系列课程的学习,开发出一个简易的在RISC-V指令集架构上运行的操作系统。
前提
这个系列的大部分文章和知识来自于:[完结] 循序渐进,学习开发一个RISC-V上的操作系统 - 汪辰 - 2021春,以及相关的github地址。
在这个过程中,这个系列相当于是我的学习笔记,做个记录。
嵌入式开发
搞过51,32单片机的同学应该能明白什么是嵌入式开发。嵌入式开发是一种系统级别的与硬件结合比较紧密的软件开发结束。
交叉编译
参与编译与运行的机器根据角色可以分为三类:
- 构建(build)系统:执行编译构建动作的计算机
- 主机(host)系统:运行build系统生成可执行程序的计算机系统
- 目标(target)系统:特别地,当以上生成的可执行程序是GCC时,我们用target来描述用来运行GCC生成的可执行程序的计算机系统。
那么交叉编译就是:build == host != target
大白话就是:你编出来的可执行文件是在另一个不同的系统上运行的。所以你要用可以编译出在目标系统可运行的执行文件的编译器。比如如果你在x86上使用gcc编译出的程序,它只能在x86上运行,无法在risc-v上运行。要想编译出的程序可以在risc-v上运行,你就要使用risc-v的编译器。
GDB调试,QEMU,MAKEFILE
GDB调试这里不多阐述,因为我也不太懂,还在学习阶段,后面可能会出一两期关于gdb的博客。这里可以参考视频。这三者都是工具,网上有很多资料供大家学习。
练习
-
编写一个简单的打印 “hello world!” 的程序源文件:hello.c
#include<stdio.h>void main() {printf("hello world!"); }
-
对源文件进行编译,生成针对支持 rv32ima 指令集架构处理器的目标文件 hello.o。
$riscv64-unknown-elf-gcc -march=rv32ima -mabi=ilp32 -c hello.c -o hello.o $file hello.o hello.o: ELF 32-bit LSB relocatable, UCB RISC-V, version 1 (SYSV), not stripped
因为是交叉编译,所以这里使用的是risc-v上的编译器,-march=rv32ima
指定了程序是运行在risc-v32位整数(i),支持整数乘法和除法(m),原子操作(a)的CPU上,其他的扩展指令集名称如下。使用file
命令就可以看出这个这个hello.o
是risc-v文件。
- 查看 hello.o 的文件的文件头信息。
$riscv64-unknown-elf-readelf -h hello.o
ELF Header:Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32Data: 2's complement, little endianVersion: 1 (current)OS/ABI: UNIX - System VABI Version: 0Type: REL (Relocatable file)Machine: RISC-VVersion: 0x1Entry point address: 0x0Start of program headers: 0 (bytes into file)Start of section headers: 10340 (bytes into file)Flags: 0x0Size of this header: 52 (bytes)Size of program headers: 0 (bytes)Number of program headers: 0Size of section headers: 40 (bytes)Number of section headers: 21Section header string table index: 20
- 查看 hello.o 的 Section header table
$ riscv64-unknown-elf-readelf -S hello.o
There are 21 section headers, starting at offset 0x2864:Section Headers:[Nr] Name Type Addr Off Size ES Flg Lk Inf Al[ 0] NULL 00000000 000000 000000 00 0 0 0[ 1] .text PROGBITS 00000000 000034 000034 00 AX 0 0 4[ 2] .rela.text RELA 00000000 002020 000048 0c I 18 1 4[ 3] .data PROGBITS 00000000 000068 000000 00 WA 0 0 1[ 4] .bss NOBITS 00000000 000068 000000 00 WA 0 0 1[ 5] .rodata PROGBITS 00000000 000068 00000d 00 A 0 0 4[ 6] .debug_info PROGBITS 00000000 000075 000928 00 0 0 1[ 7] .rela.debug_info RELA 00000000 002068 000678 0c I 18 6 4[ 8] .debug_abbrev PROGBITS 00000000 00099d 0001ba 00 0 0 1[ 9] .debug_aranges PROGBITS 00000000 000b57 000020 00 0 0 1[10] .rela.debug_arang RELA 00000000 0026e0 000030 0c I 18 9 4[11] .debug_line PROGBITS 00000000 000b77 00011d 00 0 0 1[12] .rela.debug_line RELA 00000000 002710 000054 0c I 18 11 4[13] .debug_str PROGBITS 00000000 000c94 0004c3 01 MS 0 0 1[14] .comment PROGBITS 00000000 001157 000029 01 MS 0 0 1[15] .debug_frame PROGBITS 00000000 001180 000038 00 0 0 4[16] .rela.debug_frame RELA 00000000 002764 000048 0c I 18 15 4[17] .riscv.attributes RISCV_ATTRIBUTE 00000000 0011b8 000026 00 0 0 1[18] .symtab SYMTAB 00000000 0011e0 0009e0 10 19 156 4[19] .strtab STRTAB 00000000 001bc0 00045f 00 0 0 1[20] .shstrtab STRTAB 00000000 0027ac 0000b5 00 0 0 1
Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings), I (info),L (link order), O (extra OS processing required), G (group), T (TLS),C (compressed), x (unknown), o (OS specific), E (exclude),p (processor specific)
- 对 hello.o 反汇编,并查看 hello.c 的 C 程序源码和机器指令的对应关系。
$riscv64-unknown-elf-objdump -S hello.ohello.o: file format elf32-littleriscvDisassembly of section .text:00000000 <main>:
#include<stdio.h>void main()
{0: ff010113 addi sp,sp,-164: 00112623 sw ra,12(sp)8: 00812423 sw s0,8(sp)c: 01010413 addi s0,sp,16printf("hello world!");10: 000007b7 lui a5,0x014: 00078513 mv a0,a518: 00000097 auipc ra,0x01c: 000080e7 jalr ra # 18 <main+0x18>
}20: 00000013 nop24: 00c12083 lw ra,12(sp)28: 00812403 lw s0,8(sp)2c: 01010113 addi sp,sp,1630: 00008067 ret
相关文章:

从头开发一个RISC-V的操作系统(四)嵌入式开发介绍
文章目录 前提嵌入式开发交叉编译GDB调试,QEMU,MAKEFILE练习 目标:通过这一个系列课程的学习,开发出一个简易的在RISC-V指令集架构上运行的操作系统。 前提 这个系列的大部分文章和知识来自于:[完结] 循序渐进&#x…...

Web漏洞-文件上传常见验证
后缀名:类型,文件头等 后缀名:黑白名单 文件类型:MIME信息 文件头:内容头信息 常见黑名单(明确不允许上传的格式后缀):asp、php、jsp、aspx、cgi、war (如果没有完整…...

如何在 Node.js 中使用 bcrypt 对密码进行哈希处理
在网页开发领域中,安全性至关重要,特别是涉及到用户凭据如密码时。在网页开发中至关重要的一个安全程序是密码哈希处理。 密码哈希处理确保明文密码在数据库受到攻击时也难以被攻击者找到。但并非所有的哈希方法都是一样的,这就是 bcrypt 突…...

嵌入式学习49-单片机2
指令周期 1M 机器周期 12M (晶体震荡器产生) 中断两种方式 …...

汽车EDI:如何与奔驰建立EDI连接?
梅赛德斯-奔驰是世界闻名的豪华汽车品牌,无论是技术实力还是历史底蕴都在全球汽车主机厂中居于领先位置。奔驰拥有多种车型,多元化的产品布局不仅满足了不同用户画像的需求,也对其供应链体系有着极大的考验。 本文将为大家介绍梅赛德斯-奔驰乘…...

性能分析--内存知识
内存相关知识 计算机中与CPU进行数据交换的桥梁。内存的速度,比CPU的速度要慢很多。比磁盘速度要快很多。内存中存放数据,一旦断电就会消失。linux系统的 /proc路径下的文件,都是内存文件。内存大小,一般 是GB为单位。 现在都操作…...

目标检测标签分配策略,难样本挖掘策略
在目标检测任务中,样本的划分对于模型的性能具有至关重要的影响。其中,正样本指的是包含目标物体的图像或区域,而负样本则是不包含目标物体的图像或区域。然而,在负样本中,有一部分样本由于其与正样本在特征上的相似性…...

Java | Leetcode Java题解之第16题最接近的三数之和
题目: 题解: class Solution {public int threeSumClosest(int[] nums, int target) {Arrays.sort(nums);int n nums.length;int best 10000000;// 枚举 afor (int i 0; i < n; i) {// 保证和上一次枚举的元素不相等if (i > 0 && nums…...

FIN和RST的区别,几种TCP连接出现RST的情况
一、RST跟FIN的区别: 正常关闭连接的时候发的包是FIN,但是如果是异常关闭连接,则发送RST包 两者的区别在于: 1.RST不必等缓冲区的包都发出去,直接就丢弃缓存区的包发送RST包。而FIN需要先处理完缓存区的包才能发送F…...

2024/4/1—力扣—删除字符使频率相同
代码实现: 思路: 步骤一:统计各字母出现频率 步骤二:频率从高到低排序,形成频率数组 步骤三:频率数组只有如下组合符合要求: 1, 0...0n 1, n...n (, 0)n...n, 1(, 0) bool equalFrequency(char…...

Spring源码解析-容器基本实现
spring源码解析 整体架构 defaultListableBeanFactory xmlBeanDefinitionReader 创建XmlBeanFactory 对资源文件进行加载–Resource 利用LoadBeandefinitions(resource)方法加载配置中的bean loadBeandefinitions加载步骤 doLoadBeanDefinition xml配置模式 validationMode 获…...

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之四 简单视频倒放效果
Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之四 简单视频倒放效果 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之四 简单视频倒放效果 一、简单介绍 二、简单视频倒放效果实现原理 三、简单视频倒放效果案例实现…...

蓝牙学习十(扫描)
一、简介 从之前的文章中我们知道,蓝牙GAP层定义了四种角色,广播者(Broadcaster)、观察者(Observer)、外围设备(Peripheral)、中央设备(Central)。 之前的学习…...
(26)4.7 字符函数和字符串函数
#include<stdio.h> #include<string.h> #include<assert.h> //int my_strcmp(const char* str1, const char* str2) //{ // assert(str1 && str2);//指针有效性,不能为空指针 // while (*str1 *str2) // { // if (*str1…...

交换机与队列的简介
1.流程 首先先介绍一个简单的一个消息推送到接收的流程,提供一个简单的图 黄色的圈圈就是我们的消息推送服务,将消息推送到 中间方框里面也就是 rabbitMq的服务器,然后经过服务器里面的交换机、队列等各种关系(后面会详细讲&…...
1.docker
Docker 是一种容器化平台,可以在不同的操作系统中轻松运行和管理应用程序。它使用容器技术来打包应用程序及其所有依赖关系,使其可以在任何环境中运行。 Docker 的基本概念包括以下几个部分: 镜像(Image):…...

ThinkPHP审计(2) Thinkphp反序列化链5.1.X原理分析从0编写POC
ThinkPHP审计(2) Thinkphp反序列化链子5.1.X原理分析&从0编写POC 文章目录 ThinkPHP审计(2) Thinkphp反序列化链子5.1.X原理分析&从0编写POC动态调试环境配置Thinkphp反序列化链5.1.X原理分析一.实现任意文件删除二.实现任意命令执行真正的难点 Thinkphp反序列化链5.1.…...

KingbsaeES数据库分区表的详细用法
数据库版本:KingbaseES V008R006C008B0014 简介 分区表是一种将大型数据库表拆分为更小、更可管理的部分的技术。它通过将表数据分散存储到多个物理存储单元中,可以提高查询和数据维护的性能,并优化对大型数据集的处理。本篇文章以kingbase为…...

MySQL 索引底层探索:为什么是B+树?
MySQL 索引底层探索:为什么是B树? 1. 由一个例子总结索引的特点2. 基于哈希表实现的哈希索引3. 高效的查找方式:二分查找4. 基于二分查找思想的二叉查找树5. 升级版的BST树:AVL 树6. 更加符合磁盘特征的B树7. 不断优化的B树&#…...

XML HTTP传输 小结
what’s XML XML 指可扩展标记语言(eXtensible Markup Language)。 XML 被设计用来传输和存储数据,不用于表现和展示数据,HTML 则用来表现数据。 XML 是独立于软件和硬件的信息传输工具。 应该掌握的基础知识 HTMLJavaScript…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...

【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...