从零学习开发一个RISC-V操作系统(三)丨嵌入式操作系统开发的常用概念和工具

news2025/2/28 0:01:26

本篇文章的内容

  • 一、嵌入式操作习系统开发的常用概念和工具
    • 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.c
	gcc hello.c -o hello

  Makefile中还有其他的元素,例如缺省规则、伪规则、行注释等。它们的格式如下:

# 缺省规则,当make的缺省规则(默认规则)不满足当前工程的需求时,可以重写缺省规则以覆盖原有的默认规则
.DEFAULT_GOAL := all
all :

# 伪规则,它的作用是有同名的文件与make clean操作冲突,产生歧义,-f为强制删除
.PHONY : clean
clean:
		rm -f *.o

  对于一个工程,假设其含有main.cfile1.cfile2.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.c

file1.o: file1.c
	$(CC) -c file1.c

file2.o: file2.c
	$(CC) -c file2.c

  或者采用以下省略写法。注意,省略写法使Makefile文件编写更简单,但是可以说可读性极差,笔者认为应该谨慎使用,不要出错。但是采用省略的灵活写法带来的优势也是很大的,如果按如下的写法,那么在工程中每次添加新的.c文件时,仅需要在OBJ后添加对应的.o即可。

  • $@:代指目标,即冒号:之前的内容
  • $^:代指所有的依赖
  • %.o:所有的.o文件,%.c同理
  • $<:依赖中的第一个
CC = gcc
TARGET = hello
OBJ = main.o file1.o file2.o

CCFLAGS = -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

  原创笔记,码字不易,欢迎点赞,收藏~ 如有谬误敬请在评论区不吝告知,感激不尽!博主将持续更新有关嵌入式开发、机器学习方面的学习笔记。


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

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

相关文章

Gnuplot:安装与使用备忘

异常信息 问题起源于 signalp-4.1 调用 gnuplot 进行画图&#xff0c;在画图的时候提示不支持 png 格式结果&#xff1a; $ gnuplotG N U P L O TVersion 5.0 patchlevel 0 last modified 2015-01-01Copyright (C) 1986-1993, 1998, 2004, 2007-2015Thomas Williams, Coli…

服务网格的工作原理:解析服务网格的核心组件和通信模式

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

实用!Python大型Excel文件处理:快速导入、导出与批量处理

Python 是一种功能强大的编程语言&#xff0c;它提供了丰富的库和工具&#xff0c;使得处理大型 Excel 文件变得容易和高效。下面将介绍如何使用 Python 快速导入、导出和批量处理大型 Excel 文件。下面是一些建议和实践经验&#xff0c;希望能对你有所帮助。 一、Excel 文件处…

【C语言】求一个整数的二进制序列中1的个数的三种方法

方法一&#xff1a;逐位%2法 该方法的初步测试代码如下: int NumberOf1(int n) {int count 0;while (n){if (n % 2 1){count;}n n / 2;}return count; } 众所周知&#xff0c;数据在内存里以补码的形式存储&#xff0c;这是为了简化计算机的结构设计&#xff0c;同时也提…

SpringBoot集成Prometheus实现监控

SpringBoot配置Prometheus pom.xml 引入监控以及prometheus依赖 <dependency><groupId>io.micrometer</groupId><artifactId>micrometer-registry-prometheus</artifactId></dependency><dependency><groupId>org.springfram…

Excel——时间戳与标准北京时间的互相转换

一、背景 在excel中将13位毫秒级别的时间戳转换为标准的日期格式(yyyy-mm-dd hh:mm:ss.000)&#xff0c;使用如下模板 TEXT(<source_cell>/1000/8640070*36519,"yyyy-mm-dd hh:mm:ss.000") 在excel中将10位秒级别的时间戳转换为标准的日期格式(yyyy-mm-dd h…

【华为云云耀云服务器L实例评测】- 云原生实践,快捷部署人才招聘平台容器化技术方案!

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

WebGL 选中一个表面

目录 选中一个表面 示例程序&#xff08;PickFace.js&#xff09; 代码详解 示例效果 选中一个表面 ​​​​​​​WebGL 选中物体_山楂树の的博客-CSDN博客可以使用同样的方法来选中物体的某一个表面。这一节在PickObject程序的基础上编写了PickFace程序&#xff0c;后…

计算机毕业设计 基于SSM+Vue的物资存储系统(以消防物资为例)的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

docker安装使用xdebug

docker安装使用xdebug 1、需要先安装PHP xdebug扩展 1.1 到https://pecl.php.net/package/xdebug下载tgz文件&#xff0c;下载当前最新稳定版本的文件。然后把这个tgz文件放到php/extensions目录下&#xff0c;记得install.sh中要替换解压的文件名&#xff1a; installExtensio…

uniapp 离线打包 plus.runtime.install 安装页面不弹起

uniapp 离线打包 plus.runtime.install 安装页面不弹起 updateVersion(webview : any, eventTitle : string, eventContent : string) {const loading plus.nativeUI.showWaiting(准备下载);var dtask plus.downloader.createDownload(eventContent,{method: GET,timeout: 5…

银行存款问题:整存零取

整存零取月息为0.63%&#xff0c;每年底取出1000&#xff0c;五年刚好取完&#xff0c;计算最初存入金额。 (本笔记适合基本熟悉一门编程语言的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程…

Ae 效果:CC Wide Time

时间/CC Wide Time Time/CC Wide Time CC Wide Time &#xff08;CC 宽泛时间&#xff09;能够将前后不同时间的帧叠加在一起&#xff0c;从而创建移动物体的运动轨迹&#xff0c;实现重影、运动模糊、光影跟随等效果。 可以配合其它的效果使得本效果有更多的可控性。 比如&…

py实验一

2、九九乘法表。 编写程序&#xff0c;输出九九乘法表。 源代码&#xff1a; for a in range(1, 10): for b in range(1, a1): print(f"{a}*{b}{a * b}", end" ") print() 列出测试数据和实验结果截图&#xff1a; 3、编写程序&#xff0…

progeny PROGENy

单细胞之富集分析-6&#xff1a;PROGENy - 简书 (jianshu.com) #request 2 .libPaths(c( "/home/data/t040413/R/x86_64-pc-linux-gnu-library/4.2","/home/data/t040413/R/yll/usr/local/lib/R/site-library", "/home/data/refdir/Rlib/", &qu…

tdesign的文件上传(微信小程序+idea的springboot)

目录 1. springboot后端 1.1 FileController.java 1.2 listener文件的ErpApplicationListener.java 1.3 【重点&#xff01;】FileServiceImpl层 1.4 IFileService 1.5 StringUtil通用类 1.6 主程序加一个监听器 1.7 application.yml文件 2. 微信小程序端 2.1 TDesign的…

数据结构与算法——13.队列的拓展

这篇文章主要讲一下双端队列&#xff0c;优先队列&#xff0c;阻塞队列等队列的拓展内容。 目录 1.队列拓展概述 2.双端队列的链表实现 3.双端队列的数组实现 4.优先队列无序数组实现 5.阻塞队列 6.总结 1.队列拓展概述 首先来看一张图&#xff0c;来大致了解一下他们的…

TorchLens--可视化任何PyTorch模型

0. 简介 PyTorch是一个深度学习框架&#xff0c;它使用张量&#xff08;tensor&#xff09;作为核心数据结构。在可视化PyTorch模型时&#xff0c;了解每个张量运算的意义非常重要。张量运算作为神经网络模型中的基本操作。它们用于处理输入数据、执行权重更新和生成预测结果。…

Python:获取当前目录下所有文件夹名称及文件夹下所有文件名称

获取当前目录下所有文件夹名称 def get_group_list(folder_path):group_list []for root, dirs, files in os.walk(folder_path):for dir in dirs:group_list.append(dir)return group_list获取文件夹下所有文件名称 def get_file_list(folder_path, group_name):file_list …

【zookeeper】基于Linux环境安装zookeeper集群

前提&#xff0c;需要有几台linux机器&#xff0c;我们可以准备好诸如finalshell来连接linux并且上传文件&#xff1b; 其次Linux需要安装上ssh&#xff0c;并且在/etc/hosts文件中写好其他几台机器的名字和Ip 127.0.0.1 localhost localhost.localdomain localhost4 localh…