http://jyywiki.cn/OS/2022/slides/18.slides

unix-v6-book.pdf

<aside> 📖 xv6: UNIX v6 的现代 “克隆”

xv6: a simple, Unix-like teaching operating system

接近完整的 UNIX Shell 体验

在 xv6 的地址空间中有两个独特的 page,

它们由操作系统分配,用户进程无权访问。

Untitled

RISC-V user-level ecall 指令

  1. 关闭中断
  2. 复制 pcsepc
  3. 设置 sstatus 的 SPP bit 为当前模式
  4. 设置 scause 为 trap 的原因 (ecall, 8)
  5. 转换为到 supervisor mode
  6. 跳转到 $stvec (pc = stvec)
    1. trap 设置为 0x3ffffff000, 可读可执行,用户无法访问

Trampoline 跳板

提高程序的权限,但要跳到特定的地方 ⇒ Trampoline

Trampoline: 对 ecall 瞬间的状态做快照

  1. 填充 struct trapframe (proc.h)

    1. 利用 sscratch (S-mode scratch) 保存所有寄存器

      为了保存全部寄存器结构,我们还需要一个通用寄存器来存储目标位置。因此 kernel 预留了一个 sscratch 寄存器,操作前先与 a0 交换 (用于备份 a0),再利用 a0 填充 struct trapframe

  2. 切换到内核栈 (相当于切换到进程对应的 “内核线程”, L2)

  3. 切换到内核地址空间

    1. 修改 satp (S-mode address translation and protection)

      对应 x86 里的 cr3

    2. sfence.vma 确保指令执行

  4. 跳转到 tf->kernel_trap

    1. 痛苦时间解除,进入 C 代码