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

RISC-V ISA 基本介绍
历史简介
自由(Free)与开放(Open)

-
RISC-V 念作 “risk-five”,代表着Berkeley所研发的第五代精简指令集。
-
该项目2010年始于加州大学伯克利(Berkeley)分校,希望选择一款 ISA 用于科研与教学。经过前期多年的的研究和选型,最终决定放弃使用现成的 X86 和 ARM 等 ISA,而是自己从头研发一款:
- X86:太复杂,IP问题。
- ARM:一样的复杂,而且在2010年之前还不支持64位,以及同样的IP问题。
-
主要研发人员
- Andrew Waterman,Yunsup Lee,David Patterson,Krste Asanovic

RISC-V 究竟是什么
-
一款高质量,免许可证,开放的RISC ISA。
-
一套由非盈利的RISC-V基金会维护的标准:https://riscv.org/ 。
-
适用于所有类型的计算机系统:从微控制器到超级计算机。
-
RISC-V不是一家公司,也不是一款 CPU 实现。

发展现状


特点
- 简单
- 清晰的分层设计
- 模块化
- 稳定
- 社区化
RISC-V ISA规范一览

RISC-V ISA
ISA 命名格式:RV [###] [abc…xyz]
- RV:用于标识 RISC-V体系架构的前缀,既 RISC-V 的缩写。
- [###] :{32, 64, 128} 用于标识处理器的字宽,也就是处理器的寄存器的宽度(单位为bit)。
- [abc…xyz] :标识该处理器支持的指令集模块集合。
- 例子:RV32IMA,RV64GC
模块化的 ISA
-
增量式 ISA :计算机体系结构的传统方法,同一个体系架构下的新一代处理器不仅实现了新的 ISA 扩展,还必须实现过去的所有扩展,目的是为了保持向后的二进制兼容性。典型的,以 80X86 为代表。

-
模块化 ISA:由 1 个基本整数指令集 + 多个可选的扩展指令集组成。基础指令集是固定的,永远不会改变。
RISC ISA = 1个基本整数指令集 + 多个可选的扩展指令集
-
基本整数(Integer)指令集
- 唯一强制要求实现的基础指令集,其他指令集都是可选的扩展模块。

-
扩展模块指令集:
- RISC-V 允许在实现中以可选的形式实现其他标准化和非标准化的指令集扩展。
- 特定组合“IMAFD”被称为“通用(General)”组合,用英文字母G表示。

-
例子:
- RV32I:最基本的 RISC-V 实现。
- RV32IMAC:32位实现,支持 Integer + Multiply + Atomic + Compressed 。
- RV64GC:64位实现,支持 IMAFDC 。
通用寄存器(General Purpose Register)

- RISC-V 的 Unprivileged Specification 定义了32个通用寄存器,以及一个PC
- 对 RV32I/RV64I/RV128I 都一样。
- 如果实现支持 F/D 扩展则需要额外支持32个 浮点(Float Point)寄存器。
- RV32E 将32个通用寄存器缩减为16个。
- 寄存器的宽度由 ISA 指定
- RV32的寄存器宽度为 32 位,RV64的寄存器宽度为64位,依次类推。
- 每个寄存器具体编程时有特定的用途以及各自的别名。由RISC-V Application Binary Interface(ABI)定义。
Hart
-
HART = HARdware Thread
- 一个处理器有多个执行流(硬件线程),跟多核的效果有点像。

特权级别(Privileged Level)

-
RISC-V 的 Privileged Specification 定义了三个特权级别(privilege level)
-
Machine 级别是最高的级别,所有的实现都需要支持。
-
可选的 Debug 级别(用于调试CPU)

Control and Status Registers(CSR)

- 不同的特权级别下时分别对应各自的一套 Register(CSR),用于控制(Control)和获取相应 Level 下的处理器工作状态。
- 高级别的特权级别下可以访问低级别的 CSR ,譬如Machine Level 下可以访问 Supervisor/User Level 的CSR,以此类推,但反之不可以。
- RISC-V 定义了专门用于操作 CSR 的指令(【参考1】中定义的 “Zicsr” 扩展)。
- RISC-V 定义了特定的指令可以用于在不同特权级别之间进行切换(【参考1】中定义的 ECALL/EBREAK)。
内存管理与保护
-
物理内存保护(Physical Memory Protection,PMP)
- 允许M模式指定U模式可以访问的内存地址。
- 支持 R/W/X,以及 Lock。

-
虚拟内存(Virtual Memory)
- 需要支持 Supervisor Level
- 用于实现高级的操作系统特性(Unix/Linux)
- 多种映射方式 Sv32/Sv39/Sv48

异常和中断
- 异常(Exception):“an unusal condition occurring at run time associated with an instruction in the current RISC-V hart”,执行完异常后,回到出现异常的那条指令,再次运行那条指令,然后继续往下运行。
- 中断(Interrupe):“an external asynchronous event that may cause a RISC-V hart to experience an unexpected transfer of control”,执行完中断后,回到中断出现的后一条语句,继续往下执行。

编译与链接
GCC 介绍
简介
GCC(GNU Compiler Collection)
- https://gcc.gnu.org/
- 由 GNU 开发的,遵循 GPL 许可证发行的编译器套件。
- 支持 C/C++、Objective-C、Fortran、Ada 和 Go 语言等多种语言前端,已被移植到多种计算机体系架构上,如 x86、ARM、RISC-V 等。
- GCC的初衷是为 GNU 操作系统专门编写一款编译器,现以被大多数“Unix-like”操作系统(如Linux、BSD、MacOS等)采纳为标准编译器。
命令格式
gcc [options] [filenames]
| 常用选项 | 含义 |
|---|---|
| -E | 只做预处理 |
| -c | 只编译不链接,生成目标文件“.o” |
| -S | 生成汇编代码 |
| -o file | 把输出生成到由 file 指定文件名的文件中 |
| -g | 在输出的文件中加入支持调试的信息 |
| -v | 显示输出详细的命令执行过程信息 |
主要执行步骤

- 编译(cc1,这里针对 C 语言,不同的语言由自己的编译器):编译器完成“预处理” 和 “编译”。
- “预处理”指处理源文件中以“#”开头的预处理指令,譬如 #include、#define等;
- “编译” 则针对预处理的结果进行一系列的词法分析、语法分析、语义分析、优化后生成汇编指令,存放在 .o 为后缀的目标文件中。
- 汇编(as):汇编器将汇编语言代码转换为机器(CPU)可以执行的指令。
- 链接(ld):链接器将汇编器生成的目标文件和一些标准库(譬如 libc)文件组合,形成最终可执行的应用程序。
涉及的文件类型
- .c:C源文件
- .cc/.cxx/.cpp:C++ 源文件
- .s/.S:汇编语言源文件,大S包含预处理程序,小s不包含预处理的汇编
- .h:头(header)文件
- .o:目标(object)文件
- .a/.so:编译后的静态库(archive)文件和共享库(shared object)文件
- a.out:可执行文件
针对多个源文件的处理

ELF 介绍
简介
-
ELF(Executable Linkble Format)是一种Unix-like系统上的二进制文件格式标准。
-
ELF标准中定义的采用 ELF 格式的文件分为4类:
ELF文件类型 说明 实例 可重定位文件(Relocatable File) 内容包含了代码和数据,可以被链接成可执行文件或共享目标文件。 Linux上的 .o 文件 可执行文件(Executable File) 可以直接执行的程序 Linux上的 a.out 共享目标文件(Shared Ob

本文详细介绍了RISC-V架构的发展背景、核心特性、ISA模块、编译链接过程,以及嵌入式开发中的关键概念,包括汇编语言、编译器工具链、调试器和模拟器的使用。深入讲解了汇编指令和函数调用约定,适合初学者循序渐进地学习RISC-V编程。
最低0.47元/天 解锁文章
1992

被折叠的 条评论
为什么被折叠?



