RISC-V 指令集
ISC-V 原子操作
RV32A有两种类型的原子操作:
- 内存原子操作(AMO)
- 加载保留/条件存储(load reserved/store conditional)
RISC-V的原子指令中包含两部分,分别是LR/SC指令和AMO指令。
为了实现操作的原子性特征,在使用LR/SC指令时必须成对调用。当运行LR指令的过程中(即在执行该指令的时候),处理器会设置相应的标志位字段,并用于检测内存地址是否有其他Hart操作正在进行以及是否存在中断异常,并判断是否已经执行了MRET指令。只要出现上述情况中的任何一种,则会导致SC指令无法完成正常的任务流程并终止其执行过程。遵循这一原则机制可以确保程序的操作是安全可靠的并符合严格的同步规范要求
该指令是一个常用的缩写形式,在计算机体系结构中被广泛采用。其全名为 Load Reserved(留 reserve load)或保留加载(Reserved Load)) , 即其名称为这一操作功能的具体描述。 而另一重要的CPU指令 SC(Set Carry Flag or Store Conditionally), 其缩写展开式为 Store Conditional(条件存储或条件存入)* , 其名称解释为 '条件存储' 。
尽管LR/SC这类总线/存储一致性(SC)操作在实际应用中往往显得略显复杂,在这种情况下


Spinlock:
自旋锁(spin lock)的状态有两种:
- 0: lock is unlocked/free/released 未加锁
- 1: lock is locked/held/acquired 加锁
锁的结构体:
typedef struct {
u32 locked; ///< data inside atomic_t, is the lock held?
} atomic_t;
代码解读
其中变量 locked 只有 0 或者 1,用于指示是否加锁。
在实际的实现中,RISC-V架构支持一项原子化的指令(AMOSWAP),允许多个进程(Core)同时访问共享内存锁定变量。
初始化锁:
static inline void spinlock_init(atomic_t *p)
{
p->locked = 0;
}
代码解读
获取锁:
// Acquire the lock.
// Loops (spins) until the lock is acquired.
static inline void spinlock_lock(atomic_t *p)
{
// On RISC-V, sync_lock_test_and_set turns into an atomic swap:
// a5 = 1
// s1 = &p->locked
// amoswap.w.aq a5, a5, (s1)
while(__sync_lock_test_and_set(&p->locked, 1) != 0);
// Tell the C compiler and the processor to not move loads or stores
// past this point, to ensure that the critical section's memory
// references happen strictly after the lock is acquired.
// On RISC-V, this emits a fence instruction.
__sync_synchronize();
}
代码解读
释放锁:
static inline void spinlock_unlock(atomic_t *p)
{
// Tell the C compiler and the CPU to not move loads or stores
// past this point, to ensure that all the stores in the critical
// section are visible to other CPUs before the lock is released,
// and that loads in the critical section occur strictly before
// the lock is released.
// On RISC-V, this emits a fence instruction.
__sync_synchronize();
// Release the lock, equivalent to lk->locked = 0.
// This code doesn't use a C assignment, since the C standard
// implies that an assignment might be implemented with
// multiple store instructions.
// On RISC-V, sync_lock_release turns into an atomic swap:
// s1 = &p->locked
// amoswap.w zero, zero, (s1)
__sync_lock_release(&p->locked);
}
代码解读
xv6源码阅读系列(3)锁的实现
xv6源码解析1:从启动角度看xv6! - 知乎 (zhihu.com)
在RISC-V体系中,栈的设计遵循向下延伸的原则,在这一架构下,低地址端对应栈底位置,而高地址端则对应于栈顶区域.其中,sp的计算公式为sp = stack0 + (hartid × 4096),用于将计算出的高地址值加载至sp寄存器.
当RISC-V型计算机开机启动时,在其电源开启后会自动初始化自身并运行一个位于只读内存中的 Boot Loader程序。该 Boot Loader程序将在开机后自动启动初始化流程,并将XV6内核加载至物理内存地址 以内。值得注意的是, Boot Loader不会从 开始加载内核, 因为 至 地址范围内的设备包含了 I/O 设备。
当处于machine模式时,在内核文件系统中从entry点(位于kernel/entry.S)启动并执行基于x86架构的操作系统内核组件xv6。让我们深入分析这段代码的结构和功能机制。
.section .text
.global _entry
_entry:
# set up a stack for C.
# stack0 is declared in start.c,
# with a 4096-byte stack per CPU.
# sp = stack0 + (hartid * 4096)
la sp, stack0
li a0, 1024*4
csrr a1, mhartid
addi a1, a1, 1
mul a0, a0, a1
add sp, sp, a0
# jump to start() in start.c
call start
spin:
j spin
代码解读
可以看到,在这段汇编代码中执行了一系列操作来启动xv6内核功能。具体来说,在kernel/start.c文件中定义了初始栈stack0的空间分配机制。
__attribute__ ((aligned (16))) char stack0[4096 * NCPU];
代码解读
在上述汇编代码中,请注意注释中标有一个 identifier(标识符),其实在这里指的是 hart 的编号(编号)。什么是 hart?它是一种由RISC-V处理器提供的抽象概念——Hardware Thread(简称为HTh),通常被翻译为硬件线程。我们不必去关注它与 hart、core 或 CPU 之间的具体区别(这些细节对操作系统来说无关紧要),在这里我们可以将这三者视为同一概念——即把 hartid 视为 cpuid 的一个组成部分即可。
__sync_synchronize();
代码解读
该函数标识内存屏障,并阻止编译器或CPU跨越屏障重新排列load和store指令。也就是说,在这条语句前后将读写指令进行了隔离。这是因为,在编译过程中编译器可能会进行一些优化操作。使用该语句类似于插入一个互斥锁机制。
深入探索Xv6操作系统的内核(第一章节)_唱丶跳与 Rap 的 博客
深入探索Xv6操作系统的内核(第一章节)_唱丶跳与 Rap 的 博客
Xv6操作系统导论(第2章)_唱丶跳与Rap联合打造的个人博客站
Xv6操作系统导论(第三章):深入探讨Xv6操作系统的核心内容及其实现细节
《Xv6操作系统导论》(第4章):个人博客站介绍了一款新版本的操作系统软件——Xv6,并详细阐述了其内核设计的基本原则。该软件在虚拟化技术领域的发展现状及其实现原理均得到了充分探讨,并深入分析了内存管理机制的设计思路与其实现细节。此外,在教学与研究方面也进行了理论与实践相结合的方式展开
基于Xv6的操作系统引论(第五章)由[唱丶跳和Rap]在博主上发布
Xv6操作系统(第六章)_唱丶跳与Rap的文章
基于Xv6的操作系统入门学习指南(第七章):唱丶跳和Rap的博客
Xv6操作系统概述(第八章)/yinhe ren ke yuan/_Blog.html
GitHub - mit-pdos/xv6-riscv: x86 architecture based on RISC-V instruction set
xv6: a straightforward, Unix-based teaching operating system (mit.edu))
1、RISC-V规范
了解RISC-V相关内容,RISC-V的规范是肯定要读的,这个是绕不过去的。
规范地址:[Specifications – RISC-V International (riscv.org)](https://riscv.org/technical/specifications/ "Specifications – RISC-V International riscv.org")
2、《计算机组成与设计——硬件/软件接口》 RISC-V版本

中文版

3、《The RISC-V Reader: An Open Architecture Atlas》
这本书已经由包云岗等几位老师翻译成中文了,可以免费下载,地址:
An in-depth guide to the architecture of The RISC-V Reader, serving as a comprehensive resource for understanding its design principles and implementation details. (https://riscvbook.com/chinese/ "An in-depth guide to the architecture of The RISC-V Reader, serving as a comprehensive resource for understanding its design principles and implementation details." )
An Introduction to Assembly Programming with RISC-V
RISC-V Assembly Programming (riscv-programming.org)
RISC-V 官方文档请见:
- ABI:GitHub - riscv-non-isa/rismc-psabi-doc: RISC-V ELF psABI相关文档;
- ASM:[rscvnonsia-RISCV-RSIMASMDOC at master · rscvnonsia/RISCV-RSIMASMDOC](https://link.zhihu.com/?target=https%3A//github.com/rs CV-nonsia/risCVRSIMASMDOC/blob/master/docs/asmdoc "rs CV-nonsia/risCVRSIMASMDOC").
ISA 描述了计算机指令的基本功能与组织方式。涵盖的主要方面包括指令的行为、编码方案以及其可能访问的各种资源(如 CPU 寄存器)。这些程序能够运行于任何具备兼容 ISA 系统的设备中。
随着时代的演进,ISA技术通常会经历更新与发展。然而,这些基于ISA的设计者们努力使得较为现代化的新一代 Isa 集成系统能够与以往的经典isa架构保持兼容性,从而确保那些经过 old-isa 编程开发出的各种 legacy code 能够在当前采用 new-isa 系统架构的新 CPU 上继续运行良好。具体来说,基于 80386isa 的程序也能被支持采用相同或任意其他兼容 isa 标准(如 80486isa) 的任何处理器所执行
RV32IISA规定了指令使用32位编码。因此规定系统假设存在一个字节寻址型主存(byte addressable memory),每个指令占用四个内存单元。此外还规定这些指令按照在主存中的出现顺序依次执行。
RISC-V汇编语言第三课:编译与连接
知乎上的这篇关于RISC-V汇编语言入门的文章深入探讨了该技术体系的构成要素及其规范体系构建思路
深入解析RISC-V汇编语言(第六章) — RV32I指令系统 - 知乎平台 (www.zhihu.com)
RISC-V体系结构编程与实践

计算机体系结构简明教程(RISC-V版) 蒋本珊 PDF电子版
链接:https://pan.baidu.com/s/1s6kM6RqjxI1HUVp0NUzqFA?pwd=4dav
提取码:4dav 作者:诗音碧霄 https://www.bilibili.com/read/cv23040111 出处:bilibili

