Skip to content

模型Model

陷阱入口与系统调用

Trap and system call · 用户态与内核态

把受控特权转移分成硬件入口、软件保存、参数验证与返回,区分普通call、缺页重试和调度切换。

形式陈述 ​

陷阱(trap)是控制转入预先配置的处理入口的机制。同步异常由当前指令触发,外部中断由设备或计时事件触发;系统调用是程序主动请求内核服务的一种受控入口。本页采用OS-16进程模型,内核预先设置唯一可信入口,用户代码不能自行选择一个任意内核地址作为提权后的目标。

OS-16的硬件入口原子保存 (savedPC, cause, previousMode, badVA) 到内核控制记录,转到内核态并跳转入口。它不自动保存所有通用寄存器。入口汇编先取得可信内核栈,再把用户寄存器保存在本线程trap frame中;服务完成后软件恢复这些寄存器,受控返回指令恢复模式与PC。真实ISA保存哪些寄存器、是否自动换栈,须查该ISA,不能由本模型推断。

对缺页等可重启同步故障,硬件提供精确异常状态:故障指令之前的效果已完成,故障指令及其后没有不可撤回的数据效果。OS-16中故障的savedPC指向应重试指令;显式系统调用指令长度固定4B,软件在完成请求后把返回PC设为savedPC+4。中断则保存下一条待执行指令位置。三种返回规则不同。

直觉

普通函数call改变控制流,仍在原特权下使用原地址空间权限。系统调用跨越资源保护边界:调用者能提出请求,却不能把自己的参数当作已经可信的内核指针、权限或长度。

陷阱入口与线程调度也有不同职责。一次查询PID的调用可以进入内核、马上返回同一线程,整个过程中没有切换进程。反过来,定时器中断可能导致内核转而运行另一线程;是否调度是入口后的决策,不是trap的定义。

例子与边界

一次有界write请求 ​

P在PC=0x1020执行OS-16的系统调用指令,寄存器中保存fd=3, buf=0x12F0, n=32。入口保存用户寄存器。内核先验证fd可写,再检查整个用户区间 [0x12F0,0x1310) 可读;它横跨虚页0x12和0x13,不能只检查首字节。若n可能造成定宽溢出,先验证n≤65536−buf,再构造端点。

若0x13是已保留但尚未驻留的合法匿名页,OS-16的拷贝用户内存助手在可睡眠上下文中按既定策略处理该缺页,恢复后完成拷贝。若0x13没有合法映射,助手返回错误,不盲目把用户地址当内核地址读取。本例选择先把32B完整复制到内核暂存区、再修改文件,保证此模型中的用户拷贝失败不造成半次文件更新;这不是POSIX对所有write错误的通用原子性承诺。

请求成功后,返回值寄存器写入32,PC返回0x1024,其他需保留寄存器恢复。若把PC错误恢复到0x1020,程序会再次提交同一请求;若普通缺页也统一加4,则会跳过本应重试的访存。

用户指针会变,检查不能替代受控使用 ​

多线程进程可能在另一个线程检查指针后解除映射。先验证地址、再直接裸读并不能构成通用安全证明;内核需要规定用户拷贝时如何处理变化和故障,必要时锁定映射或捕获异常。OS-16主线限定单线程进程,因此示例没有这种交错,边界扩展时仍须补该协议。

内核也可能处理设备中断。中断处理器不能随意使用被中断线程的用户栈:该栈可无空间、不可写甚至已损坏。可信入口资源是防止一次错误参数变成内核任意内存写的组成部分。

推论与应用

一次系统调用成本可拆成入口/返回、参数验证和拷贝、服务逻辑、可能的I/O等待。固定入口成本不代表整次调用常数时间;拷贝n字节至少有随n增长的工作,阻塞还会产生上下文切换。

语言级异常由语言运行时寻找处理器,通常不改变CPU特权;硬件陷阱由ISA与内核共同处理。语言除法异常有时可借硬件异常实现,但这种实现连接不能把所有throw、普通call与系统调用合为同一个接口。

参考资料
  • Cox、Kaashoek、Morris,xv6教材 rev5,§4.1–4.4;RISC-V硬件入口与软件寄存器保存分工。本文长度、寄存器接口及拷贝策略为OS-16自定。
  • The Open Group,POSIX.1-2024,write,实际文件接口的返回值与错误约束。
关系图谱7 个相邻概念 · 1 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组