系统调用(RISC-V)
睡不醒的鲤鱼 2021-05-22 操作系统 uCore
# 一、概述
应用程序要输出字符串时,会触发系统调用 write()
,操作系统服务的应用编程接口通常由高级语言编写(C、go 和 rust 等),程序通常访问高层次的 API 接口。
三种最常用的应用程序编程接口:
- Win API:用于 Windows 32 / 64;
- POSIX API:用于 POSIX-based OS;
- Java API:用于 JAVA 虚拟机 (JVM)。
# 1.1 系统调用实现概述
- 用户态:通过函数库来管理;
- 内核态:对应系统调用号,实现系统调用功能。
# 1.2 系统调用和函数调用的不同
系统调用
- RISC-V 中,
ecall
和sret
指令用于系统调用 - 有堆栈切换和特权级的转换
- 开销:超过函数调用
- 切换内核堆栈
- 验证参数
- 可能切换页表
- 需要拷贝数据
函数调用
- RISC-V 中,
call
和ret
指令用于系统调用 - 无堆栈切换和特权级的转换
- 开销:低于系统调用
# 二、具体实现
- std lib 发出系统调用请求
- 发出设置系统调用号和参数,发出
ecall
- 发出设置系统调用号和参数,发出
- 硬件设置
sepc
:保存请求后的指令地址pc
:设置为stvec
scause
:设置为ecall from u-mode
sstatus
:SIE
位置零以禁用中断stval
:保存相关的附加信息
- 软件保存被打断现场
- 执行软件实现的中断服务例程
- 软件恢复现场
- 应用程序继续执行