从零学习开发一个RISC-V操作系统(三)丨嵌入式操作系统开发的常用概念和工具
本篇文章的内容
- 一、嵌入式操作习系统开发的常用概念和工具
- 1.1 本地编译和交叉编译
- 1.2 调试器GDB(The GNU Project Debugger)
- 1.3 QEMU模拟器
- 1.4 项目构造工具Make
本系列是博主参考B站课程学习开发一个RISC-V的操作系统的学习笔记,计划从RISC-V的底层汇编指令学起,结合C语言,在Ubuntu 20.04上开发一个简易的操作系统。一个目的是通过实践操作学习和了解什么是操作系统,第二个目的是为之后学习RISC-V的集成电路设计打下一定基础。本系列持续不定期更新,分享出来和大家一同交流进步。
博主是微电子科学与工程专业的学生,对软件和操作系统难免有理解不到位的地方。如有谬误敬请不吝告知,不胜感激。
参考课程及文章:
【Bilibili】[完结] 循序渐进,学习开发一个RISC-V上的操作系统 - 汪辰 - 2021春
一、嵌入式操作习系统开发的常用概念和工具
嵌入开发是一种比较综合性的技术,它不单指纯粹的软件开发技术,也不单是一种硬件配置技术;它是在特定的硬件环境下针对某款硬件进行开发,是一种系统级别的与硬件结合比较紧密的软件开发技术。
一般来说,我们在主机(Host PC)上对程序进行编辑和编译,通过特定的手段将主机和目标板(Target Board)进行连接,例如WIFI、互联网、有线连接等,使程序在特定的目标板上运行。程序运行在特定的硬件上,操作系统运行的机器也当然要运行在没有操作系统的硬件上。编写操作系统同样是嵌入式开发的一种。
1.1 本地编译和交叉编译
参与编译和运行的机器根据其角色可以分成以下三类:
- 构建(build) 系统:执行编译构建动作(编译器可执行程序)的计算机。例如编写GCC工具的计算机。
- 主机(host) 系统:运行 build 系统生成的可执行程序的计算机系统。
- 目标(target) 系统:特别地,当以上生成的可执行程序是 GCC 时,我们用 target 来描述用来运行 GCC 将生成的可执行程序的计算机系统。
所以,我们可以对本地编译和交叉编译两种工作环境作如下定义:
- 本地(native)编译:build、host、ratget三个系统在同一台机器上。例如在本地编写的C语言程序在本地运行。
- 交叉(cross)编译:build和host系统在同一台机器上,但是和target系统是分离的。例如在PC上编写的程序烧录到单片机上运行。
例如,如果要查看gcc实际是什么,可以执行如下操作:
$ whereis gcc
gcc: /usr/bin/gcc /usr/lib/gcc /usr/share/gcc /mnt/c/Program Files (x86)/mingw64/bin/gcc.exe /usr/share/man/man1/gcc.1.gz
$ ls -l /usr/bin/gcc
lrwxrwxrwx 1 root root 5 Mar 20 2020 /usr/bin/gcc -> gcc-9
$ ls -l /usr/bin/gcc-9
lrwxrwxrwx 1 root root 22 Oct 24 2022 /usr/bin/gcc-9 -> x86_64-linux-gnu-gcc-9
$ ls -l /usr/bin/x86_64-linux-gnu-gcc-9
-rwxr-xr-x 1 root root 1158288 Oct 24 2022 /usr/bin/x86_64-linux-gnu-gcc-9
可以看到,执行gcc
后,程序实际执行的程序是x86_64-linux-gnu-gcc-9
。GCC被多层符号变量封装在一起了,供用户使用。
GNU 交叉编译工具链(Toolchain)
- 命名格式: arch-vendor-os1-[os2-]XXX
例子:
- x86_64-linux-gnu-gcc
- riscv64-unknown-elf-gcc
- riscv64-unknown-elf-objdum
1.2 调试器GDB(The GNU Project Debugger)
GDB即GNU 项目调试器,用于查看另一个程序在执行过程中正在执行的操作,或该程序崩溃时正在执行的操作。
被调试的程序可能与 GDB 在同一台计算机上执行,也可能在另一台计算机(远程)上或者在模拟器上执行。GDB 支持调试多种语言:譬如:Assembly,C,Go,Rust,…
- 重新编译程序并在编译选项中加入 “-g”
$ gcc -g test.c
- 运行 gdb 和程序
$ gdb a.out
- 设置断点
(gdb) b 6
- 运行程序
(gdb) r
- 程序暂停在断点处,执行查看
(gdb) p xxx
- 继续、单步或者恢复程序运行
(gdb) s/n/c
1.3 QEMU模拟器
QEMU 是一套由 (Fabrice Bellard) 编写的以 GPL 许可证分发源码的计算机系统模拟软件,在 GNU/Linux 平台上使用广泛。
- 支持多种体系架构。譬如:IA-32 (x86),AMD 64,MIPS 32/64, RISC-V 32/64 等等。
QEMU 有两种主要运作模式:
- User mode:直接运行应用程序。
- System mode。模拟整个计算机系统,包括中央处理器及其他周边设备。
1.4 项目构造工具Make
make是一种自动化工程管理工具。当工程文件量很大的时候,在Linux系统中每一次编译文件都要手动输入命令。如果文件有一千个,一万个,那我们每次编译输入的指令就及其庞大,对开发效率的影响很大(当然,在这里我们可以对每个文件先编译而不连接,生成很多的*.o
文件,在编译时将所有的*.o
文件连接,但这样的方法远没有编写Makefile优雅)。所以,我们可以编写一个每次编译自动执行的脚本文件,这个文件满足一定的格式,这就是Makefile格式。Makefile配合make,用于描述构建工程过程中所管理的对象以及如何构造工程的过程。make找到Makefile有如下两种方式:
- 隐式查找:当前目录下自动按顺序找寻文件名为“GNUmakefile”、“makefile”、“Makefile”的文件
- 显式查找:
-f
,例如使用make -f Makefile
来编译工程
Makefile由一条或多条规则(rule)组成,这是make中最核心的一点。每一条规则由如下的三要素构成:
- target:目标,可以是 obj 文件,也可以是可执行文件
- prerequisites: 生成 target 所需要的依赖
- command:为了生成 target 需要执行的命令,可以有多条
一个简单的Makefile规则如下:
target...:prerequisites...command......
例如,对于目标hello
,其依赖于文件hello.c
,我们在此基础上添加指令,可以编写如下的Makefile文件:
hello: hello.cgcc hello.c -o hello
Makefile中还有其他的元素,例如缺省规则、伪规则、行注释等。它们的格式如下:
# 缺省规则,当make的缺省规则(默认规则)不满足当前工程的需求时,可以重写缺省规则以覆盖原有的默认规则
.DEFAULT_GOAL := all
all :# 伪规则,它的作用是有同名的文件与make clean操作冲突,产生歧义,-f为强制删除
.PHONY : clean
clean:rm -f *.o
对于一个工程,假设其含有main.c
、file1.c
、file2.c
,则可以编写如下的Makefile文件。它的好处是当单独修改工程中的某个文件,重新编译时只会编译修改过的文件,可以大大节省编译时间。
CC = gcc
TARGET = hello
OBJ = main.o file1.o file2.o$(TARGET) : $(OBJ)$(CC) -o $(TARGET) $(OBJ)main.o: main.c$(CC) -c main.cfile1.o: file1.c$(CC) -c file1.cfile2.o: file2.c$(CC) -c file2.c
或者采用以下省略写法。注意,省略写法使Makefile文件编写更简单,但是可以说可读性极差,笔者认为应该谨慎使用,不要出错。但是采用省略的灵活写法带来的优势也是很大的,如果按如下的写法,那么在工程中每次添加新的.c
文件时,仅需要在OBJ
后添加对应的.o
即可。
$@
:代指目标,即冒号:
之前的内容$^
:代指所有的依赖%.o
:所有的.o
文件,%.c
同理$<
:依赖中的第一个
CC = gcc
TARGET = hello
OBJ = main.o file1.o file2.oCCFLAGS = -c -Wall$(TARGET) : $(OBJ)$(CC) -o $@ $^%.o: %.c$(CC) $(CCFLAGS) $< -o $@.PHONY : clean
clean:rm -f *.o
甚至可以有更加灵活的写法,采用如下的写法,每一次添加新的.c
文件后甚至都不需要更改Makefile文件了:
CC = gcc
TARGET = hello
SRC = $(wildcard *.c)
OBJ = $(patsubst %.c, %.o, $(SRC))CCFLAGS = -c -Wall$(TARGET) : $(OBJ)$(CC) -o $@ $^%.o: %.c$(CC) $(CCFLAGS) $< -o $@.PHONY : clean
clean:rm -f *.o
原创笔记,码字不易,欢迎点赞,收藏~ 如有谬误敬请在评论区不吝告知,感激不尽!博主将持续更新有关嵌入式开发、机器学习方面的学习笔记。
相关文章:
![](https://img-blog.csdnimg.cn/790555ce97f348ccb1cf9f59683489da.png#pic_center)
从零学习开发一个RISC-V操作系统(三)丨嵌入式操作系统开发的常用概念和工具
本篇文章的内容 一、嵌入式操作习系统开发的常用概念和工具1.1 本地编译和交叉编译1.2 调试器GDB(The GNU Project Debugger)1.3 QEMU模拟器1.4 项目构造工具Make 本系列是博主参考B站课程学习开发一个RISC-V的操作系统的学习笔记,计划从RISC…...
![](https://img-blog.csdnimg.cn/62e919d4e5e44d72a6b267e4a16df931.png)
小米机型解锁bl 跳“168小时”限制 操作步骤分析
写到前面的安全提示 了解解锁bl后的风险: 解锁设备后将允许修改系统重要组件,并有可能在一定程度上导致设备受损;解锁后设备安全性将失去保证,易受恶意软件攻击,从而导致个人隐私数据泄露;解锁后部分对系…...
![](https://www.ngui.cc/images/no-images.jpg)
基础练习 回文数
问题描述 1221是一个非常特殊的数,它从左边读和从右边读是一样的,编程求所有这样的四位十进制数。 输出格式 按从小到大的顺序输出满足条件的四位十进制数。 solution1 #include <stdio.h> int main(){int n 1000, n1, n2, n3, n4;while(n &…...
![](https://img-blog.csdnimg.cn/ab373fe3503942e293792da43e475c1d.webp)
解决Spring Boot 2.7.16 在服务器显示启动成功无法访问问题:从本地到服务器的部署坑
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...
![](https://www.ngui.cc/images/no-images.jpg)
洛谷P5661:公交换乘 ← CSP-J 2019 复赛第2题
【题目来源】https://www.luogu.com.cn/problem/P5661https://www.acwing.com/problem/content/1164/【题目描述】 著名旅游城市 B 市为了鼓励大家采用公共交通方式出行,推出了一种地铁换乘公交车的优惠方案: 1.在搭乘一次地铁后可以获得一张优惠票&…...
![](https://img-blog.csdnimg.cn/e71aa30eb78a427d97c262e95da4b59b.png)
mysql优化之索引
索引官方定义:索引是帮助mysql高效获取数据的数据结构。 索引的目的在于提高查询效率,可以类比字典。 可以简单理解为:排好序的快速查找数据结构 在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这种数据…...
![](https://img-blog.csdnimg.cn/161eec2e78394b95b016cbfa9964027b.png)
文件系统详解
目录 文件系统(1) 第一节文件系统的基本概念 一、文件系统的任务 二、文件的存储介质及存储方式 三、文件的分类 第二节 文件的逻辑结构和物理结构 一、文件的逻辑结构 二、文件的物理结构 文件系统(2) 第三节 文件目…...
![](https://img-blog.csdnimg.cn/383f8d4c8c1849d0bf682c61f053e7c7.png)
有名管道及其应用
创建FIFO文件 1.通过命令: mkfifo 文件名 2.通过函数: mkfifo #include <sys/types.h> #include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode); 参数: -pathname:管道名称的路径 -mode:文件的权限&a…...
![](https://www.ngui.cc/images/no-images.jpg)
加州大学伯克利分校 计算机科学专业
加州大学伯克利分校 计算机科学专业 cs 61a cs 61b cs61c...
![](https://img-blog.csdnimg.cn/img_convert/6b06b8891e32feb4c9ef1b1f85eb8d05.png)
一个关于 i++ 和 ++i 的面试题打趴了所有人
前言 都说大城市现在不好找工作,可小城市却也不好招人。 我们公司招了挺久都没招到,主管感到有些心累。 我提了点建议,是不是面试问的太深了,在这种小城市,能干活就行。 他说自己问的面试题都很浅显,如果答…...
![](https://img-blog.csdnimg.cn/836562506e334b51b993a5428bafdd26.png)
程序员的快乐如此简单
最近在GitHub上发起了一个关于Beego框架的小插件的开源仓库,这一举动虽然看似微小,但其中的快乐和意义却是无法用言语表达的。 Beego是一个开源的Go语言Web框架,它采用了MVC架构模式,并集成了很多常用的功能和中间件。小插件是指…...
![](https://www.ngui.cc/images/no-images.jpg)
浅谈云原生Cloud Native
目录 1.云原生是什么2.云原生与传统软件有什么区别3.云原生有哪些代表性的技术 1.云原生是什么 云原生(Cloud Native)是一种构建和运行应用程序的方法,可以充分利用云计算模型的优势。云原生是一种面向服务的架构(SOA)…...
![](https://img-blog.csdnimg.cn/d3b05ed9aeef43ae88f178cc1cab7e9e.png)
解决react报错“JSX 表达式必须具有一个父元素“
现象如下: 原因: 新插入的dom元素跟已有的dom元素平级了,必须创建一个共有的根元素 解决办法: 使用<> </>标签作为根元素,把所有子元素包裹起来 <> ....原代码 </> 问题解决!…...
![](https://img-blog.csdnimg.cn/1210d1f7cc104c6595abe41f44c9689f.png)
Spring学习笔记7 Bean的生命周期
Spring学习笔记6 Bean的实例化方式_biubiubiu0706的博客-CSDN博客 Spring其实就是一个管理Bean对象的工厂.它负责对象的创建,对象的销毁. 这样我们才可以知道在哪个时间节点上调用了哪个类的哪个方法,知道代码该写在哪里 Bean的生命周期之粗略5步 Bean生命周期的管理可以参考S…...
![](https://www.ngui.cc/images/no-images.jpg)
React 如何导出excel
在现代的Web开发中,数据导出是一个非常常见的需求。而在React应用中,我们经常需要将数据导出为Excel文件,以便用户可以轻松地在本地计算机上查看和编辑。本文将介绍如何在React应用中实现导出Excel文件的功能。 章节一:安装依赖 …...
![](https://img-blog.csdnimg.cn/6487e859c4c74bb5b95e116e225f3824.png)
Texlive2020 for win10 宏包更新
用命令提示符更新texlive的宏包,这个方法非常简单实用 1.以管理员身份打开命令提示符 2.系统自动选择镜像网站 tlmgr option repository ctan 3.更新宏包 tlmgr update --self --all 其中–self参数表示升级tlmgr本身,–all表示升级所有宏包,这样就可以将所有宏包更新了 4.列…...
![](https://img-blog.csdnimg.cn/b7c0619ce8fc49d1962475625d5571ce.png#pic_center)
Ps 在用鼠标滚轮缩放图片时,速度太快?
1.原因 在于安装了第三方鼠标优化软件Mos,它起着对第三方鼠标全局浏览效果的优化,使浏览更加顺滑,而不精确,消除了mac使用第三方鼠标浏览页面时的卡顿问题。这也使得像ps、ai这类软件,在进行页面缩放时,变得…...
![](https://img-blog.csdnimg.cn/bfcda002b5594620afc7abbbd032830b.png)
基于docker进行Grafana + prometheus实现服务监听
基于docker进行Grafana Prometheus实现服务监听 Grafana安装Prometheus安装Jvm监控配置服务器主机监控(基础cpu,内存,磁盘,网络) Grafana安装 docker pull grafana/grafanamkdir /server/grafanachmod 777 /server/grafanadocker run -d -p…...
![](https://www.ngui.cc/images/no-images.jpg)
模型层及ORM介绍
模型层及ORM介绍 模型层 负责跟数据库之间进行通信 配置MySQL,下载MySQLclient 创建数据库 进入mysql数据库执行create database 数据库名 default charset utf8通常数据库名跟项目名保持一致settings.py里进行数据库的配置修改 DATABASES 配置项的内容&#x…...
![](https://www.ngui.cc/images/no-images.jpg)
QQ邮箱怎么设置SMTP接口服务器?
在现如今信息快速传递的时代,邮件已成为我们工作、学习和生活中必不可少的一部分。而作为每位用户必备的一款邮箱,QQ邮箱一直以其稳定、高效、安全的特点深受大家的青睐。但是你是否觉得每次发邮件都需要打开QQ邮箱网页,进行繁琐的操作很是麻…...
![](https://img-blog.csdnimg.cn/6207cba5760d49b59109dcba53493631.png)
【操作系统笔记四】高速缓存
CPU 高速缓存 存储器的分层结构: 问题:为什么这种存储器层次结构行之有效呢? 衡量 CPU 性能的两个指标: 响应时间(或执行时间):执行一条指令平均时间 吞吐量,就是 1 秒内 CPU 可以…...
![](https://www.ngui.cc/images/no-images.jpg)
uniapp获取openid
要获取用户的openid,需要使用微信小程序的登录API。以下是一个简单的示例代码: // 在page中引入wx-login组件 import wxLogin from /components/wx-loginexport default {components: { wxLogin },data() {return {openid: }},methods: {// wxLogin组件…...
![](https://www.ngui.cc/images/no-images.jpg)
测试工程师面试之设计测试用例
以下的问题答案,仅供参考,如小伙伴们有更好的答案,欢迎大家评论区留言,谢谢大家 测试工程师面试之设计测试用例 1、请说一说简单用户界面登陆过程都需要做哪些分析2、 请对此系统设计测试用例:一个系统,多个…...
![](https://img-blog.csdnimg.cn/64f8c96c417047bb83bfa488498d347f.png)
html页面仿word文档样式(vue页面也适用)
目录 文章title: 标题: 正文: 完整代码: 页面效果: 文章title: <div><h3 style"display: flex;justify-content: center; align-items: center; color: #000;">实验室招新报名公…...
![](https://www.ngui.cc/images/no-images.jpg)
如何在控制台打印sql语句
步骤一: log4j2.xml中做以下配置 <logger name"xxx.infrastructure.mysql.mapper"level"debug" additivity"false"><appender-ref ref"Console"/></logger>步骤二:IDEA下载Free Mybatis Plu…...
![](https://www.ngui.cc/images/no-images.jpg)
【Vue3 源码解析】reactive 全家桶
// 泛型约束:只能传入引用类型 export function reactive<T extends object>(target: T): UnwrapNestedRefs<T> // 判断只读,否则创建reactive响应式对象 export function reactive(target: object) {// if trying to observe a readonly pr…...
![](https://www.ngui.cc/images/no-images.jpg)
目标检测YOLO实战应用案例100讲-基于YOLO的遥感目标检测(续)
目录 3.4 YOLOv3 3.5 YOLOv4 3.6 YOLOv5 改进的YOLOv4算法 4.1 Triple Loss损失函数的应用...
![](https://www.ngui.cc/images/no-images.jpg)
7.5 通过API判断进程状态
进程状态的判断包括验证进程是否存在,实现方法是通过枚举系统内的所有进程信息,并将该进程名通过CharLowerBuff转换为小写,当转换为小写模式后则就可以通过使用strcmp函数对比,如果发现继承存在则返回该进程的PID信息,…...
![](https://img-blog.csdnimg.cn/7697572d16e144079ab5ca45a8257fb4.png)
你写过的最蠢的代码是?
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页: 🐅🐾猫头虎的博客🎐《面试题大全专栏》 🦕 文章图文并茂🦖…...
![](https://www.ngui.cc/images/no-images.jpg)
MySQL与PostgreSQL对比
MySQLPostgreSQL数据类型支持支持JSON,但不如PostgreSQL支持更多的数据类型,如数组、hstore、JSON、JSONB、范围类型等扩展性有一些扩展性,但不如PostgreSQL支持自定义数据类型、函数、操作符,具有强大的扩展性SQL兼容性遵循SQL标…...
![](/images/no-images.jpg)
保定做网站的公司/免费发布信息的平台
作为一名产品经理,最奢侈的愿望是什么?“有一个自己能控制的团队去实现心目中的产品”,应该不仅仅是我有这个想法吧。按照比较流行的说法,产品经理是只负责产品规划与管理、不直接负责团队管理的“经理”,但却身负推动…...
![](/images/no-images.jpg)
建设项目招标在什么网站公示/英文seo是什么意思
最近发现centos7 的/etc/rc.local不会开机执行,于是认真看了下/etc/rc.local文件内容的就发现了问题的原因了 ?1234567891011#!/bin/bash# THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES## It is highly advisable to create own systemd services or udev rules…...
![](/images/no-images.jpg)
做云盘网站哪个好/百度推广销售
JavaScrip中如何实现继承 Java中实现继承通过关键字extands来实现的,而javascrip中没有该关键字,通过以下方法可以实现继承关系: 先定义一个父类 //定义一个动物类function Animal(name){this.namename || Animal;this.sleepfunction(){do…...
![](/images/no-images.jpg)
wordpress取消页尾/今日国际新闻大事件
http://poj.org/problem?id2184 dp[s]表示当TSs时,TF的最大值。 背包容量?——我们要找到它的最大值,不断分开累加正s和负s即可。 if (s > 0) {for (j Max; j > Min; --j)dp[j s] max(dp[j s], dp[j] f);///dp[s]表示当TSs时&…...
![](https://img-blog.csdnimg.cn/img_convert/9e68fd2640766d752550dce6c636fd13.png)
做一元购网站 要多少钱/百度双十一活动
mysql 安装双击d:\websoft\mysql-essential-5.1.63-win32.msi 就开始安装了 看图操作出现上面的界面,不要点cancel 那是取消, 等等选择“custom”然后点“next” 出现下面的界面这个是选择mysql 安装的位置,默认在c盘,我们点“cha…...
![](https://img-blog.csdnimg.cn/20200913125555956.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzMzc1NTk4,size_16,color_FFFFFF,t_70#pic_center)
wordpress程序版本/怎么推广游戏代理赚钱
文章目录0 效果1 实现1.1 创建名称和位置1.2 关联信号和槽函数1.3 编写事件0 效果 开始: 中间步骤 结束: 1 实现 1.1 创建名称和位置 在ui设计界面新建需要的菜单名称 1.2 关联信号和槽函数 找到对象的名称 在类的构造函数中编写函数&#x…...