1.cons_init()
cons_init()->kbd_init()-> kbd_intr()+pic_enable(IRQ_KBD);
kbd_intr()->cons_intr(kbd_proc_data);//mainly init the buffer
keypoint is: pic_enable(IRQ_KBD) -- enable the keyboard interrupt
2. pic_init --- make 8259 work
3. idt_init() in trap.c to initialize IDT
void idt_init(void) {
extern uintptr_t __vectors[];
for(int i=0; i<sizeof(idt)/sizeof(struct gatedesc);i++)
SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL);
// load the IDT
lidt(&idt_pd);
}
4. enable INT
void intr_enable(void) { sti(); }
void intr_disable(void) { cli(); }
when there is an interrupt occurred, here are some steps:
a. vectors.S means IDT (number=256)
# handler
.text
.global __alltraps
.global vector0
vector0:
pushl $0
pushl $0
jmp __alltraps
.global vector1
vector1:
pushl $0
pushl $1
jmp __alltraps
...
it will jmp to __alltraps which is in trapentry.S
b. trapentry.S
#include <memlayout.h>
# vectors.S sends all traps here.
.text
.globl __alltraps
__alltraps:
# push registers to build a trap frame
# therefore make the stack look like a struct trapframe
pushl %ds
pushl %es
pushal
# load GD_KDATA into %ds and %es to set up data segments for kernel
movl $GD_KDATA, %eax
movw %ax, %ds
movw %ax, %es
# push %esp to pass a pointer to the trapframe as an argument to trap()
pushl %esp
# call trap(tf), where tf=%esp
call trap
# pop the pushed stack pointer
popl %esp
# return falls through to trapret...
.globl __trapret
__trapret:
# restore registers from stack
popal
# restore %ds and %es
popl %es
popl %ds
# get rid of the trap number and error code
addl $0x8, %esp
iret
then it will call trap() in trap.c
c. trap.c
static void trap_dispatch(struct trapframe *tf) {
char c;
switch(tf->tf_trapno) {
case IRQ_OFFSET + IRQ_KBD:
c = cons_getc();
cprintf("%s [%03d] %c\n", (tf->tf_trapno != IRQ_OFFSET + IRQ_KBD) ? "serial":"kbd", c, c);
keybuf_push(&kb, c);
break;
default:
cprintf("UNKNOW INT\n");
}
cprintf("time to return\n");
}
void trap(struct trapframe *tf) {
trap_dispatch(tf);
}
the (popl %esp) make it possible that the PC can return to the break point