初始化中断向量表
在实模式中,已经初始化了 IDT,不过现在我们要对保护模式再做一次这样的工作。由于这段代码比较长,放在了单独的函数里。485 setup_idt:
# 默认中断处理例程,后面有定义,做一件事情:如果开启了 CONFIG_PRINTK,就通过 printk 输出内核信息。
486 lea ignore_int,%edx
# 这里是内核代码段,注意已经是保护模式了,所以要用代码段选择子
487 movl $(__KERNEL_CS << 16),%eax
488 movw %dx,%ax /* selector = 0x0010 = cs */
489 movw $0x8E00,%dx /* interrupt gate - dpl=0, present */
490
# 载入 IDT 表的首地址
491 lea idt_table,%edi
# 共有 256 个中断向量
492 mov $256,%ecx
493 rp_sidt:
# 这是一个循环,用默认中断处理例程初始化 256 个中断向量
494 movl %eax,(%edi)
495 movl %edx,4(%edi)
496 addl $8,%edi
497 dec %ecx
498 jne rp_sidt
499
# 设置几个已定义的中断向量
# 宏定义
500 .macro set_early_handler handler,trapno
501 lea \handler,%edx
502 movl $(__KERNEL_CS << 16),%eax
503 movw %dx,%ax
504 movw $0x8E00,%dx /* interrupt gate - dpl=0, present */
505 lea idt_table,%edi
506 movl %eax,8*\trapno(%edi)
507 movl %edx,8*\trapno+4(%edi)
508 .endm
509 # 预先设置的中断向量
510 set_early_handler handler=early_divide_err,trapno=0# 被零除
511 set_early_handler handler=early_illegal_opcode,trapno=6# 操作码异常
512 set_early_handler handler=early_protection_fault,trapno=13# 保护错误
513 set_early_handler handler=early_page_fault,trapno=14# 缺页异常
514# 后面一段代码定义了这四个中断向量的中断处理例程。
# 它们都调用了 early_fault,即将当前状态、中断向量号等信息通过 early_printk 或 printk 输出。
515 ret