interrupt.c

pintos中的中断有256个即0-255. void *frame_pointer; 是一个frame总会有个指针 void (*eip) (void); 下一个执行的指令的地址。 void *esp; stack pointer 栈指针 IDT(Interrupt Descriptor Table)是一个描述interrupt的数组,即idt[INTR_CNT]; PIC(可编程中断控制器):外设发出中断请求需要PIC进行处理。 当发生中断时先调用intrNN_stub();这是用汇编写的。接着调用intr_entry();即把intr_frame放入栈中。最后调用intr_handler()执行特定注册过的中断。 intr_handler();返回后则恢复现场,即把栈中的CPU寄存器的值都恢复。 intr_frame里面的都是CPU寄存器的值,我们在中断时所要做的事就是保存现场,而这就是一个现场,我们只要把这个放入栈中即可。 static intr_handler_func *intr_handlers[INTR_CNT];这个就是对应每个中断处理函数。 static unsigned int unexpected_cnt[INTR_CNT];这个是记录了每个中断里没有注册中断处理函数的计数。 static bool yield_on_return;一般外部中断是不能yield或sleep。 intr_init() 函数把中断的一些基本配置都配好了。0-19都是有原因的中断,20以上就是unknown。 //------------------------------------------------------------------------------------------------------------------------------------------- static void register_handler (uint8_t vec_no, int dpl, enum intr_level level, intr_handler_func *handler, const char *name) { ASSERT (intr_handlers[vec_no] == NULL); if (level == INTR_ON) idt[vec_no] = make_trap_gate (intr_stubs[vec_no], dpl); else idt[vec_no] = make_intr_gate (intr_stubs[vec_no], dpl); intr_handlers[vec_no] = handler; intr_names[vec_no] = name; } 这个函数的意思是vec_no的中断调用了这个函数,调用handler这个函数的前提是vec_no的中断执行程序还没有被注册。 这样这个函数就可以把handler注册为中断处理程序,dpl(descriptor privilege level)只有两种取值,第一种为3,意思是允许用户模式中断,第二种0,意思是禁止中断。 如果level是打开中断,则把idt[vec_no]描述为make_trap_gate.并且把intr_handler[vec_no]赋值,name也赋值。 void intr_register_ext (uint8_t vec_no, intr_handler_func *handler, const char *name) { ASSERT (vec_no >= 0x20 && vec_no = 0x20 && vec_no vec_no >= 0x20 && frame->vec_no vec_no]; //内部中断只需执行这个handler即可。 if (handler != NULL) handler (frame); else if (frame->vec_no == 0x27 || frame->vec_no == 0x2f) { /* There is no handler, but this interrupt can trigger spuriously due to a hardware fault or hardware race condition. Ignore it. */ } else unexpected_interrupt (frame); //没有注册handler /* Complete the processing of an external interrupt. */ if (external) { ASSERT (intr_get_level () == INTR_OFF); ASSERT (intr_context ()); in_external_intr = false; //退出外部中断 pic_end_of_interrupt (frame->vec_no); //设置pic if (yield_on_return) //外部中断一定不会执行这句话 thread_yield (); } } //------------------------------------------------------------------- static void unexpected_interrupt (const struct intr_frame *f) { /* Count the number so far. */ unsigned int n = ++unexpected_cnt[f->vec_no]; /* If the number is a power of 2, print a message. This rate limiting means that we get information about an uncommon unexpected interrupt the first time and fairly often after that, but one that occurs many times will not overwhelm the console. */ if ((n & (n - 1)) == 0) printf ("Unexpected interrupt %#04x (%s)/n", f->vec_no, intr_names[f->vec_no]); } 这个函数只是把frame中对应的vec_no的unexpected_cnt数组加一。

你可能感兴趣的:(interrupt)