添加trap的处理

ch2
zhangxinyu 1 year ago
parent fd355ae2b6
commit c96b6233bf

@ -11,6 +11,7 @@ pub mod sbi;
pub mod batch;
pub mod sync;
pub mod trap;
pub mod syscall;
// 汇编脚本引入, 调整内核的内存布局之后, 会跳入到 rust_main中执行
global_asm!(include_str!("entry.asm"));
@ -35,6 +36,7 @@ pub fn rust_main(){
println!("sbss: {:#x}, ebss: {:#x}", sbss as usize, ebss as usize);
println!("boot_stack_top_bound: {:#x}, boot_stack_lower_bound: {:#x}", boot_stack_top_bound as usize, boot_stack_lower_bound as usize);
trap::init();
batch::init();
batch::run_next_app();
}

@ -1,2 +1,66 @@
mod context;
use core::arch::global_asm;
use riscv::register::{
mtvec::TrapMode,
scause::{self, Exception, Trap},
stval, stvec,
};
pub use context::TrapContext;
use crate::batch::run_next_app;
use crate::println;
use crate::syscall::syscall;
// 引入陷入保存寄存器需要的汇编代码
global_asm!(include_str!("trap.S"));
/// 初始化stvec 寄存器, 这个寄存器保存陷入时, 入口函数的地址
pub fn init() {
extern "C" {
fn __alltraps();
}
unsafe {
stvec::write(__alltraps as usize, TrapMode::Direct);
}
}
// 这个函数是 trap.S 中__alltraps 保存完所有寄存器在内核栈 之后会进入到这里
#[no_mangle]
pub fn trap_handler(trap_context: &mut TrapContext) -> &mut TrapContext {
let scause = scause::read(); // trap 发生的原因
let stval = stval::read(); // trap的附加信息
// 根据发生的原因判断是那种类别
match scause.cause() {
// 用户态发出的系统调用
Trap::Exception(Exception::UserEnvCall) => {
trap_context.sepc += 4; // +4 是因为我们需要返回 ecall指令的下一个指令
trap_context.x[10] = syscall(trap_context.x[17], [trap_context.x[10], trap_context.x[11], trap_context.x[12]]) as usize;
}
// 访问不允许的内存
Trap::Exception(Exception::StoreFault) | Trap::Exception(Exception::StorePageFault) => {
println!("[kernel] PageFault in application, kernel killed it.");
run_next_app();
}
// 非法指令
Trap::Exception(Exception::IllegalInstruction) => {
println!("[kernel] IllegalInstruction in application, kernel killed it.");
run_next_app();
}
// 未知错误
_ => {
panic!(
"Unsupported trap {:?}, stval = {:#x}!",
scause.cause(),
stval
);
}
}
trap_context
}

@ -38,7 +38,7 @@ __alltraps: # __alltraps 符号的实现
sd t2, 2*8(sp) # trap context
# trap_handler(cx: &mut TrapContext)
mv a0, sp # TrapContext a0
call trap_handler # trap_handler #
call trap_handler # trap_handler
__restore: # __restore
# case1:

Loading…
Cancel
Save