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

2023-09-21 23:46:50


  本系列是博主参考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

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


更多推荐

JVM--Java类加载器笔记

Java类加载器代码经过编译变成了字节码打包成Jar文件。让JVM去加载需要的字节码,变成持久代/元数据区上的Class对象,接着执行程序逻辑。类声明周期和加载过程步骤:加载->链接(校验->准备->解析)->初始化->使用->卸载加载:根据明确知道的class完全限定名,来获取二进制classfile格式的字节流(找

算法讨论题 —— Java实现两数之和

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。即:每个index上的数字只能用一次。示例给定nums=[2,7,11,15],target=9因为nums[0]+nums[1]=2+7=9所以返回[0,1]解答这个题目的原题是在:力扣(Leet

Zookeeper分布式锁的概念及原理

文章目录1.Zookeeper分布式锁的概念2.分布式锁的实现方式3.Zookeeper分布式锁的原理1.Zookeeper分布式锁的概念分布式锁的概念图如下:一种演变过程。在我们进行单机应用程序开发时,往往会涉及到并发同步的问题,一般都会采用synchronized或者Lock锁的方式来解决多线程间的代码同步问题,这

EM3DANI包详解:使用Julia语言进行3D频域电磁数据建模的终极指南

第一部分:EM3DANI包的简介与安装1.EM3DANI包简介EM3DANI是一个强大的工具包,专门为那些希望使用Julia语言进行频域电磁(CSEM和MT)数据的3D建模的研究者和开发者设计。它支持各向同性和各向异性建模,使得用户可以更加灵活地进行电磁数据的模拟和分析。频域电磁(CSEM和MT)技术在地球物理勘探、矿

Leetcode.2826 将三个组排序

题目链接Leetcode.2826将三个组排序rating:1721题目描述给你一个下标从000开始长度为nnn的整数数组numsnumsnums。从000到n−1n-1n−1的数字被分为编号从111到333的三个组,数字iii属于组nums[i]nums[i]nums[i]。注意,有的组可能是空的。你可以执行以下操作

[C语言]栈与队列——喵喵队,冲冲冲

宝子,你不点个赞吗?不评个论吗?不收个藏吗?最后的最后,关注我,关注我,关注我,你会看到更多有趣的博客哦!!!喵喵喵,你对我真的很重要。目录前言栈栈的实现队列队列的实现总结前言实践,实践,实践,多练几遍力扣,牛客的题。落实到脚下。栈栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作

Ubuntu安装RabbitMQ server - 在外远程访问

文章目录前言1.安装erlang语言2.安装rabbitMQ3.内网穿透3.1安装cpolar内网穿透(支持一键自动安装脚本)3.2创建HTTP隧道4.公网远程连接5.固定公网TCP地址5.1保留一个固定的公网TCP端口地址5.2配置固定公网TCP端口地址前言RabbitMQ是一个在AMQP(高级消息队列协议)基础上完

单例模式的安全写法

要想知道怎么写单例模式,那么必须得知道什么是单例模式。单例模式是一种设计模式,它确保某个类只有一个实例,并且提供一个全局访问该实例的方法。单例模式不会创建实例副本,而是返回对已创建实例的引用。单例模式的创建可以分为两类。第一类是饿汉式单例模式,它在类加载时就创建了唯一的实例对象,并在全局范围内提供访问点。第二类是懒汉式

如何制作一个成功的超市购物小程序

随着互联网的普及和移动支付的便捷性,越来越多的消费者选择在网上购物,这也促使越来越多的商家开始搭建自己的小程序商城。对于超市便利店来说,拥有一个便捷、易用的小程序商城能够吸引更多的消费者,提高销售效率。那么如何快速搭建一个超市便利店小程序呢?下面我们将通过乔拓云平台来介绍这个过程。步骤1:登录乔拓云网后台,进入商城管理

rabbitmq 面试题

1.交换机类型RabbitMQ是一个开源的消息队列系统,它支持多种交换机类型,用于在消息的生产者和消费者之间路由和分发消息DirectExchange(直接交换机):Direct交换机是最简单的交换机类型之一。它将消息按照消息的RoutingKey(路由键)与绑定的队列的RoutingKey进行精确匹配,并将消息发送到

一键自助建站系统源码带安装教程 傻瓜式部署搭建,让您的建站更高效

在这个数字时代,网站已成为企业或个人展示形象、推广业务的重要工具。为了满足这一需求,许多自助建站系统应运而生,大大降低了用户建站的门槛。给大家分享一款傻瓜式部署搭建的一键自助建站系统源码,让您轻松拥有高效建站能力。一、一键自助建站系统源码介绍这款一键自助建站系统源码具有以下特点:简单易用:用户只需通过简单的鼠标点击和输

热文推荐