|
|
@@ -4,13 +4,38 @@
|
|
|
#include "../lib/kernel/print.h"
|
|
|
#include "../lib/kernel/io.h"
|
|
|
|
|
|
-char *intr_name[IDT_DESC_CNT]; // 用于保存异常的名字
|
|
|
-intr_handler idt_table[IDT_DESC_CNT]; // 中断处理函数数组
|
|
|
+#define IDT_DESC_CNT 0x30 // 目前支持的中断数
|
|
|
+#define PIC_M_CTRL 0x20 // 主片的控制端口是 0x20
|
|
|
+#define PIC_M_DATA 0x21 // 主片的数据端口是 0x21
|
|
|
+#define PIC_S_CTRL 0xA0 // 从片的控制端口是 0xA0
|
|
|
+#define PIC_S_DATA 0xA1 // 从片的数据端口是 0xA1
|
|
|
|
|
|
#define EFLAGS_IF 0x200 // eflags寄存器中的if位为1
|
|
|
#define GET_EFLAGS(EFLAG_VAR) asm volatile("pushfl; popl %0" : "=g"(EFLAG_VAR))
|
|
|
|
|
|
-static gate_desc idt[IDT_DESC_CNT]; // 中断描述符表,本质上就是个中断门描述符数组
|
|
|
+/* 中断门描述符结构体 */
|
|
|
+// Example type_attributes values that people are likely to use (assuming DPL is 0):
|
|
|
+// 32-bit Interrupt Gate: 0x8E (p=1, dpl=0b00, type=0b1110 => type_attributes=0b1000_1110=0x8E)
|
|
|
+// 32-bit Trap Gate: 0x8F (p=1, dpl=0b00, type=0b1111 => type_attributes=1000_1111b=0x8F)
|
|
|
+// Task Gate: 0x85 (p=1, dpl=0b00, type=0b0101 => type_attributes=0b1000_0101=0x85)
|
|
|
+typedef struct
|
|
|
+{
|
|
|
+ uint16_t offset_low; // 16位 偏移量的低 16 位 (0..15)
|
|
|
+ uint16_t selector; // 选择器 acode segment selector in GDT or LDT
|
|
|
+ uint8_t dcount; // 置 0
|
|
|
+ uint8_t attribute; // 述符类型 (bit 7:0) gate type, dpl, and p fields
|
|
|
+ uint16_t offset_high; // 16 位 偏移量的高 16 位 (16..31)
|
|
|
+} __attribute__((packed)) gate_desc;
|
|
|
+
|
|
|
+char *intr_name[IDT_DESC_CNT]; // 用于保存异常的名字
|
|
|
+/****************************** 定义中断数组 **********************
|
|
|
+ * 在 kernel.S 中定义的 intrXXentry 只是中断处理程序的入口,
|
|
|
+ * 最终调用的 idt_table 中的处理程序*/
|
|
|
+intr_handler idt_table[IDT_DESC_CNT]; // 中断处理函数数组
|
|
|
+/***************************************************************/
|
|
|
+
|
|
|
+static gate_desc idt[IDT_DESC_CNT]; // 中断描述符表,本质上就是个中断门描述符数组
|
|
|
+extern intr_handler intr_entry_table[IDT_DESC_CNT]; // 声明引用定义在 kernel.S 中的中断处理函数入口数组
|
|
|
|
|
|
/*创建中断门描述符*/
|
|
|
static void make_idt_desc(gate_desc *p_gdesc, uint8_t attr, intr_handler function)
|
|
|
@@ -48,7 +73,8 @@ static void pic_init(void)
|
|
|
outb(PIC_S_DATA, 0x01); // ICW4: 8086 模式, 正常 EOI
|
|
|
|
|
|
/* 打开主片上 IR0, 也就是目前只接受时钟产生的中断*/
|
|
|
- outb(PIC_M_DATA, 0xfe);
|
|
|
+ // outb(PIC_M_DATA, 0xfe);
|
|
|
+ outb(PIC_M_DATA, 0xfd); // 测试键盘,只打开键盘中断,其他全部关闭
|
|
|
outb(PIC_S_DATA, 0xff);
|
|
|
|
|
|
put_str(" pic_init done\n");
|