中断处理程序
scause
初始化
// kern/init/init.c
#include <trap.h>
int kern_init(void) {
extern char edata[], end[];
memset(edata, 0, end - edata);
cons_init(); // init the console
const char *message = "(THU.CST) os is loading ...\n";
cprintf("%s\n\n", message);
print_kerninfo();
// grade_backtrace();
//trap.h的函数,初始化中断
idt_init(); // init interrupt descriptor table
//clock.h的函数,初始化时钟中断
clock_init();
//intr.h的函数,使能中断
intr_enable();
// LAB1: CAHLLENGE 1 If you try to do it, uncomment lab1_switch_test()
// user/kernel mode switch test
// lab1_switch_test();
/* do nothing */
while (1)
;
}
// kern/trap/trap.c
void idt_init(void) {
extern void __alltraps(void);
//约定:若中断前处于S态,sscratch为0
//若中断前处于U态,sscratch存储内核栈地址
//那么之后就可以通过sscratch的数值判断是内核态产生的中断还是用户态产生的中断
//我们现在是内核态所以给sscratch置零
write_csr(sscratch, 0);
//我们保证__alltraps的地址是四字节对齐的,将__alltraps这个符号的地址直接写到stvec寄存器
write_csr(stvec, &__alltraps);
}
//kern/driver/intr.c
#include <intr.h>
#include <riscv.h>
/* intr_enable - enable irq interrupt, 设置sstatus的Supervisor中断使能位 */
void intr_enable(void) { set_csr(sstatus, SSTATUS_SIE); }
/* intr_disable - disable irq interrupt */
void intr_disable(void) { clear_csr(sstatus, SSTATUS_SIE); }处理
最后更新于