xv6-k210/doc/内核原理-系统调用.md

55 lines
4.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# System Call
System Call即系统调用以下简称syscall用于在用户程序中执行一些特权模式下才能完成的操作如I/O操作
对于处理器而言syscall是一种同步发生的事件在基于RISC-V的操作系统中由`ecall`指令Environment Call产生。
当系统调用事件结束后处理器将返回到ecall指令的下一条指令继续执行。
原版xv6的文档将“system call”、“exception”和“interrupt”统称为“trap”。这可能与我们平常使用的术语有一定出入需要注意。
在RISC-V指令集手册的1.6节中对“exception”、“interrupt”和“trap”的定义是这样的
> We use the term <u>*exception*</u> to refer to an unusual condition occurring at run time associated with
an instruction in the current RISC-V hart. We use the term <u>*interrupt*</u> to refer to an external
asynchronous event that may cause a RISC-V hart to experience an unexpected transfer of control.
We use the term <u>*trap*</u> to refer to the transfer of control to a trap handler caused by either an
exception or an interrupt.
从这个角度来看trap在RISC-V的语境下指的是控制权的转换也就是特权级的转换。
## 在RISC-V中请求系统调用
在RISC-V的用户程序中使用`ecall`指令请求syscall。操作系统提供不同功能的syscall对应不同的请求调用号。
因此请求前,需要向`a7`寄存器中写入所请求的syscall的调用号。以下为一个请求8号调用的例子
```
li a7, 8
ecall
```
## 系统调用的处理过程
Syscall涉及到特权态的转换需要经过trap过程。对于用户程序而言一般是从用户模式U模式陷入到监管模式S模式
我们知道操作系统中有中断向量表保存着各类异常与中断的处理例程的入口syscall的处理例程自然也在其中。
而对于不同类型的调用请求syscall的处理例程也有相应的系统调用表保存不同类型的系统调用功能函数的入口。
根据用户事先写入寄存器的系统调用号syscall的处理例程调用相应的功能函数完成系统调用随后返回至原先的特权态。
那么,执行`ecall`指令后,系统中发生了什么呢?其实不仅是系统调用,异常与各类中断发生后,首先都会经过这一过程——特权态的转换。
在RISC-V中各个特权级都有一组状态与控制寄存器CSRs当在U模式下中断发生时除了时钟中断RISC-V硬件系统会自动完成下列操作
1. 如果发生的是设备中断,且`sstatus`寄存器的`SIE`位为0即中断关闭则不继续下列的操作也就是暂时忽略这个中断
2. 关闭外部设备中断,即将`sstatus`寄存器的`SIE`位设为0
3. 拷贝`pc`寄存器的值至`sepc`寄存器;
4. 保存当前的特权态信息至`sstatus`寄存器的`SPP`字段;
5. 设置`scause`寄存器其值表示trap产生的原因
6. 将特权态设置为S模式
7. 将`stvec`寄存器的值存入`pc`寄存器(`stvec`寄存器存放S模式的中断处理函数的入口地址
8. 从新的`pc`值指向的指令继续执行。
执行上述步骤后处理机就进入了S模式。此时操作系统可能还需要进行一些额外操作以应对S模式下再次发生trap事件。
之后,根据`scause`寄存器,判断发生的是异常、中断或是系统调用,并进行相应的处理。处理完毕后,就执行`sret`指令返回U模式。
`sret`指令会执行若干相反的操作,例如将`sepc`的值写回`pc`、更新`sstatus`寄存器的`SIE`字段等使处理机恢复到原本U模式的执行状态。
<br>
<br>
# 参考文档
+ [*xv6: a simple, Unix-like teaching operating system*](https://pdos.csail.mit.edu/6.S081/2020/xv6/book-riscv-rev1.pdf)
+ [*The RISC-V Instruction Set Manual Volume I: Unprivileged ISA*](https://github.com/riscv/riscv-isa-manual/releases/download/draft-20210212-c879d5a/riscv-spec.pdf)
+ [《RISC-V手册——一本开源指令集的指南》](http://riscvbook.com/chinese/RISC-V-Reader-Chinese-v2p1.pdf)