greatbridf 3 жил өмнө
parent
commit
06c0d7de96

+ 8 - 0
include/kernel/interrupt.h

@@ -62,6 +62,14 @@ void int13_handler(
     uint16_t cs,
     uint32_t eflags);
 
+void int14_handler(
+    ptr_t addr,
+    struct regs_32 s_regs,
+    uint32_t error_code,
+    ptr_t eip,
+    uint16_t cs,
+    uint32_t eflags);
+
 void irq0_handler(void);
 void irq1_handler(void);
 void irq2_handler(void);

+ 18 - 0
src/asm/interrupt.s

@@ -5,9 +5,27 @@
 .globl int13
 .type  int13 @function
 int13:
+    xchgw %bx, %bx
     pushal
     call int13_handler
     popal
+
+# remove the 32bit error code from stack
+    addl $4, %esp
+    iret
+
+.globl int14
+.type  int14 @function
+int14:
+    xchgw %bx, %bx
+    pushal
+    movl %cr2, %eax
+    pushl %eax
+    call int14_handler
+    popal
+
+# remove the 32bit error code from stack
+    addl $4, %esp
     iret
 
 .globl irq0

+ 33 - 0
src/kernel/interrupt.c

@@ -30,6 +30,7 @@ void init_idt()
 
     // handle general protection fault (handle segmentation fault)
     SET_IDT_ENTRY_FN(13, int13, 0x08);
+    SET_IDT_ENTRY_FN(14, int14, 0x08);
     // SET_IDT_ENTRY(0x0c, /* addr */ 0, 0x08);
 
     // 0x08 stands for kernel code segment
@@ -57,6 +58,7 @@ void init_idt()
     asm_load_idt(idt_descriptor);
 }
 
+// general protection
 void int13_handler(
     struct regs_32 s_regs,
     uint32_t error_code,
@@ -86,6 +88,37 @@ void int13_handler(
     asm_hlt();
 }
 
+// page fault
+void int14_handler(
+    ptr_t addr,
+    struct regs_32 s_regs,
+    uint32_t error_code,
+    ptr_t eip,
+    uint16_t cs,
+    uint32_t eflags)
+{
+    char buf[512] = { 0 };
+
+    vga_printk("---- PAGE FAULT ----\n", 0x0fu);
+
+    snprintf(
+        buf, 512,
+        "eax: %x, ebx: %x, ecx: %x, edx: %x\n"
+        "esp: %x, ebp: %x, esi: %x, edi: %x\n"
+        "eip: %x, cs: %x, error_code: %x   \n"
+        "eflags: %x, addr: %x              \n",
+        s_regs.eax, s_regs.ebx, s_regs.ecx,
+        s_regs.edx, s_regs.esp, s_regs.ebp,
+        s_regs.esi, s_regs.edi, eip,
+        cs, error_code, eflags, addr);
+    vga_printk(buf, 0x0fu);
+
+    vga_printk("----   HALTING SYSTEM   ----", 0x0fu);
+
+    asm_cli();
+    asm_hlt();
+}
+
 void irq0_handler(void)
 {
     inc_tick();