中断处理和系统调用

关于中断和系统调用处理我们使用了rcore社区的TrapFrame开源库

NUDT-OS是x64架构的,由于采用了syscall快速系统调用指令,系统调用控制流和中断控制流不同。本章分别介绍中断和系统调用的控制流和处理过程。

TrapFrame库将中断和系统调用控制流封装在了UserContext.run()方法中,我们这里不对代码作出解释,只是概述性地描述控制流。

下图来自TrapFrame库

控制流

UserContext.run()方法用UserContext中的寄存器来恢复线程并进入用户态执行,直到发生中断或者系统调用。这时控制流返回Rust,我们需要手动处理中断或系统调用,调用handle_user_trap()函数。

可以把中断和系统调用分成下面几种情况:

  • 用户态中断:控制流返回Rust(也就是手动调用UserContext.run()之后)
  • 内核态发生中断:直接跳转到手动编写的trap_handler
  • 用户态系统调用:控制流返回Rust
#[no_mangle]
/// 中断处理入口,由汇编直接调用无需手动调用
pub extern "C" fn trap_handler(tf: &mut TrapFrame) {
    handle_trap(Some(tf), None, None);
}

/// 处理用户态的中断或系统调用
/// 若是系统调用则context中的trap_num一定为100
/// 若是中断则trap_num从context中获取
pub fn handle_user_trap(thread: Arc<Thread>, context: &UserContext) {
    handle_trap(None, Some(thread), Some(context));
}

可见不管是内核还是用户中断/系统调用最终都进入到handle_trap()函数,我们在下一节说明这个函数