Xv6异常处理(二):内核异常
kernelvec汇编函数
与用户异常不同,当内核发生异常(中断/异常),将首先跳转到kernelve汇编函数(用户异常是uservec)。该汇编函数执行如下操作:
- 保存内核context到内核栈上(用户是保存到trapframe页)
- 调用kerneltrap内核异常处理程序
- 恢复内核context,注意因为操作系统调度原因,此时内核可能运行在与发生异常前不同的CPU上,因此不用恢复tp寄存器
- 执行sret指令返回内核发生异常前的地方
.globl kerneltrap
.globl kernelvec
.align 4
kernelvec:# make room to save registers.addi sp, sp, -256# save caller-saved registers.sd ra, 0(sp)sd sp, 8(sp)sd gp, 16(sp)sd tp, 24(sp)sd t0, 32(sp)sd t1, 40(sp)sd t2, 48(sp)sd a0, 72(sp)sd a1, 80(sp)sd a2, 88(sp)sd a3, 96(sp)sd a4, 104(sp)sd a5, 112(sp)sd a6, 120(sp)sd a7, 128(sp)sd t3, 216(sp)sd t4, 224(sp)sd t5, 232(sp)sd t6, 240(sp)# call the C trap handler in trap.ccall kerneltrap# restore registers.ld ra, 0(sp)ld sp, 8(sp)ld gp, 16(sp)# not tp (contains hartid), in case we moved CPUsld t0, 32(sp)ld t1, 40(sp)ld t2, 48(sp)ld a0, 72(sp)ld a1, 80(sp)ld a2, 88(sp)ld a3, 96(sp)ld a4, 104(sp)ld a5, 112(sp)ld a6, 120(sp)ld a7, 128(sp)ld t3, 216(sp)ld t4, 224(sp)ld t5, 232(sp)ld t6, 240(sp)addi sp, sp, 256# return to whatever we were doing in the kernel.sret