Procházet zdrojové kódy

解决了#DE会触发#UD的问题

fslongjin před 3 roky
rodič
revize
d78db8225c

+ 25 - 25
kernel/exception/entry.S

@@ -1,6 +1,6 @@
 #include"../common/asm.h"
 .code64
-.section .text
+//.section .text
 
 R15 =   0x00
 R14 =   0x08
@@ -56,7 +56,7 @@ Restore_all:
 
 ret_from_exception:
     // === 从中断中返回 ===
-    .code64
+
 ENTRY(ret_from_intr)
     jmp Restore_all
 
@@ -64,28 +64,27 @@ ENTRY(ret_from_intr)
 Err_Code:
     // ===== 有错误码的情况下,保存寄存器并跳转服务程序
 
-    pushq %rax
-    movq %es, %rax
-    pushq %rax
-    movq %ds, %rax
-    pushq %rax
-
-    xorq %rax, %rax
-
-    pushq	%rbp
-    pushq	%rdi
-    pushq	%rsi
-    pushq	%rdx
-    pushq	%rcx
-    pushq	%rbx
-    pushq	%r8
-    pushq	%r9
-    pushq	%r10
-    pushq	%r11
-    pushq	%r12
-    pushq	%r13
-    pushq	%r14
-    pushq	%r15
+    pushq	%rax
+	movq	%es,	%rax
+	pushq	%rax
+	movq	%ds,	%rax
+	pushq	%rax
+	xorq	%rax,	%rax
+
+	pushq	%rbp
+	pushq	%rdi
+	pushq	%rsi
+	pushq	%rdx
+	pushq	%rcx
+	pushq	%rbx
+	pushq	%r8
+	pushq	%r9
+	pushq	%r10
+	pushq	%r11
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
 
     cld
     
@@ -99,7 +98,7 @@ Err_Code:
     movq %rsp, %rdi // 把栈指针装入rdi,作为函数的第一个的参数
 
     
-    callq %rdx //调用服务程序 带*号表示调用的是绝对地址
+    callq *%rdx //调用服务程序 带*号表示调用的是绝对地址
     jmp ret_from_exception
 
 // 系统调用入口
@@ -181,6 +180,7 @@ ENTRY(divide_error)
     pushq $0    //由于#DE不会产生错误码,但是为了保持弹出结构的一致性,故也压入一个错误码0
     pushq %rax  // 先将rax入栈
     leaq do_divide_error(%rip), %rax    // 获取中断服务程序的地址
+    
     xchgq %rax, (%rsp)  // 把FUNC的地址换入栈中
     jmp Err_Code
 

+ 7 - 3
kernel/exception/gate.h

@@ -100,9 +100,8 @@ void set_tss_descriptor(unsigned int n, void *addr)
 
     unsigned long limit = 103;
     
-    *(unsigned long *)(phys_2_virt(GDT_Table) + n) = (limit & 0xffff) | (((unsigned long)addr & 0xffff) << 16) | ((((unsigned long)addr >> 16) & 0xff) << 32) | ((unsigned long)0x89 << 40) | ((limit >> 16 & 0xf) << 48) | (((unsigned long)addr >> 24 & 0xff) << 56); /////89 is attribute
-    kdebug("1212");
-    *(unsigned long *)(phys_2_virt(GDT_Table) + n + 1) = (((unsigned long)addr >> 32) & 0xffffffff) | 0;
+    *(unsigned long *)(phys_2_virt(GDT_Table + n)) = (limit & 0xffff) | (((unsigned long)addr & 0xffff) << 16) | ((((unsigned long)addr >> 16) & 0xff) << 32) | ((unsigned long)0x89 << 40) | ((limit >> 16 & 0xf) << 48) | (((unsigned long)addr >> 24 & 0xff) << 56); /////89 is attribute
+    *(unsigned long *)(phys_2_virt(GDT_Table + n + 1)) = (((unsigned long)addr >> 32) & 0xffffffff) | 0;
 }
 
 /**
@@ -160,6 +159,11 @@ void set_system_trap_gate(unsigned int n, unsigned char ist, void *addr)
     _set_gate(phys_2_virt(IDT_Table + n), 0xEF, ist, addr); // p=1,DPL=3, type=F
 }
 
+
+static inline void set_system_intr_gate(unsigned int n,unsigned char ist,void * addr)	//int3
+{
+	_set_gate(phys_2_virt(IDT_Table + n) , 0xEE , ist , addr);	//P,DPL=3,TYPE=E
+}
 /**
  * @brief 初始化TSS表的内容
  *

+ 24 - 26
kernel/exception/irq.c

@@ -46,15 +46,14 @@
 // 构造中断entry
 // 为了复用返回函数的代码,需要压入一个错误码0
 
-#define Build_IRQ(number)                                                     \
-    void IRQ_NAME(number);                                                    \
-    __asm__(SYMBOL_NAME_STR(IRQ) #number "interrupt:   \n\t"                  \
-                                         "pushq $0x00 \n\t" \
-                                         SAVE_ALL_REGS     \
-                                         "movq %rsp, %rdi   \n\t"                \
+#define Build_IRQ(number)                                                         \
+    void IRQ_NAME(number);                                                        \
+    __asm__(SYMBOL_NAME_STR(IRQ) #number "interrupt:   \n\t"                      \
+                                         "pushq $0x00 \n\t" SAVE_ALL_REGS         \
+                                         "movq %rsp, %rdi   \n\t"                 \
                                          "leaq ret_from_intr(%rip), %rax    \n\t" \
-                                         "pushq %rax \n\t"                    \
-                                         "movq	$"#number",	%rsi			\n\t"    \
+                                         "pushq %rax \n\t"                        \
+                                         "movq	$" #number ",	%rsi			\n\t"        \
                                          "jmp do_IRQ    \n\t");
 
 // 构造中断入口
@@ -112,22 +111,23 @@ void (*interrupt_table[24])(void) =
         IRQ0x37interrupt,
 };
 
-
 /**
  * @brief 声明10个IPI消息处理程序,向量号从200(0xc8)开始
- * 
+ *
  */
 
-Build_IRQ(0xc8)
-Build_IRQ(0xc9)
-Build_IRQ(0xca)
-Build_IRQ(0xcb)
-Build_IRQ(0xcc)
-Build_IRQ(0xcd)
-Build_IRQ(0xce)
-Build_IRQ(0xcf)
-Build_IRQ(0xd0)
-Build_IRQ(0xd1)
+/*
+ */
+Build_IRQ(0xc8);
+Build_IRQ(0xc9);
+Build_IRQ(0xca);
+Build_IRQ(0xcb);
+Build_IRQ(0xcc);
+Build_IRQ(0xcd);
+Build_IRQ(0xce);
+Build_IRQ(0xcf);
+Build_IRQ(0xd0);
+Build_IRQ(0xd1);
 
 // 初始化IPI中断服务程序数组
 void (*SMP_interrupt_table[SMP_IRQ_NUM])(void) =
@@ -189,7 +189,7 @@ int irq_unregister(ul irq_num)
     p->parameter = NULL;
     p->flags = 0;
     p->handler = NULL;
-    
+
     return 0;
 }
 
@@ -203,10 +203,8 @@ void irq_init()
 #else
 
     apic_init();
-    kdebug("interrupt_desc=%#018lx",(void*)interrupt_desc);
-    kdebug("irq_init()=%#018lx",(void*)irq_init);
-    
-    memset((void*)interrupt_desc, 0, sizeof(irq_desc_t) * IRQ_NUM);
-    
+
+    memset((void *)interrupt_desc, 0, sizeof(irq_desc_t) * IRQ_NUM);
+
 #endif
 }

+ 59 - 53
kernel/exception/trap.c

@@ -3,63 +3,13 @@
 #include "../process/ptrace.h"
 #include "../common/kprint.h"
 
-void sys_vector_init()
-{
-    set_trap_gate(0, 1, &divide_error);
-    set_trap_gate(1, 1, &debug);
-    set_intr_gate(2, 1, &nmi);
-    set_system_trap_gate(3, 1, &int3);
-    set_system_trap_gate(4, 1, &overflow);
-    set_system_trap_gate(5, 1, &bounds);
-    set_trap_gate(6, 1, &undefined_opcode);
-    set_trap_gate(7, 1, &dev_not_avaliable);
-    set_trap_gate(8, 1, &double_fault);
-    set_trap_gate(9, 1, &coprocessor_segment_overrun);
-    set_trap_gate(10, 1, &invalid_TSS);
-    set_trap_gate(11, 1, &segment_not_exists);
-    set_trap_gate(12, 1, &stack_segment_fault);
-    set_trap_gate(13, 1, &general_protection);
-    set_trap_gate(14, 1, &page_fault);
-    // 中断号15由Intel保留,不能使用
-    set_trap_gate(16, 1, &x87_FPU_error);
-    set_trap_gate(17, 1, &alignment_check);
-    set_trap_gate(18, 1, &machine_check);
-    set_trap_gate(19, 1, &SIMD_exception);
-    set_trap_gate(20, 1, &virtualization_exception);
-    // 中断号21-31由Intel保留,不能使用
-
-    // 32-255为用户自定义中断内部
 
-    /*
-    set_trap_gate(0, 1, divide_error);
-    set_trap_gate(1, 1, debug);
-    set_intr_gate(2, 1, nmi);
-    set_system_trap_gate(3, 1, int3);
-    set_system_trap_gate(4, 1, overflow);
-    set_system_trap_gate(5, 1, bounds);
-    set_trap_gate(6, 1, undefined_opcode);
-    set_trap_gate(7, 1, dev_not_avaliable);
-    set_trap_gate(8, 1, double_fault);
-    set_trap_gate(9, 1, coprocessor_segment_overrun);
-    set_trap_gate(10, 1, invalid_TSS);
-    set_trap_gate(11, 1, segment_not_exists);
-    set_trap_gate(12, 1, stack_segment_fault);
-    set_trap_gate(13, 1, general_protection);
-    set_trap_gate(14, 1, page_fault);
-    // 中断号15由Intel保留,不能使用
-    set_trap_gate(16, 1, x87_FPU_error);
-    set_trap_gate(17, 1, alignment_check);
-    set_trap_gate(18, 1, machine_check);
-    set_trap_gate(19, 1, SIMD_exception);
-    set_trap_gate(20, 1, virtualization_exception);
-    */
-}
 
 // 0 #DE 除法错误
 void do_divide_error(struct pt_regs *regs, unsigned long error_code)
 {
-    kerror("do_divide_error(0)");
-    //kerror("do_divide_error(0),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\n", error_code, regs->rsp, regs->rip);
+    //kerror("do_divide_error(0)");
+    kerror("do_divide_error(0),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\n", error_code, regs->rsp, regs->rip);
 
     while (1)
         ;
@@ -328,4 +278,60 @@ void do_virtualization_exception(struct pt_regs *regs, unsigned long error_code)
         ;
 }
 
-// 21-21 Intel保留,请勿使用
+// 21-21 Intel保留,请勿使用
+
+
+
+void sys_vector_init()
+{
+    kdebug("do_divide_error=%#018lx", do_divide_error);
+    kdebug("&do_divide_error=%#018lx", &do_divide_error);
+    set_trap_gate(0, 1, divide_error);
+    set_trap_gate(1, 1, debug);
+    set_intr_gate(2, 1, nmi);
+    set_system_trap_gate(3, 1, int3);
+    set_system_trap_gate(4, 1, overflow);
+    set_system_trap_gate(5, 1, bounds);
+    set_trap_gate(6, 1, undefined_opcode);
+    set_trap_gate(7, 1, dev_not_avaliable);
+    set_trap_gate(8, 1, double_fault);
+    set_trap_gate(9, 1, coprocessor_segment_overrun);
+    set_trap_gate(10, 1, invalid_TSS);
+    set_trap_gate(11, 1, segment_not_exists);
+    set_trap_gate(12, 1, stack_segment_fault);
+    set_trap_gate(13, 1, general_protection);
+    set_trap_gate(14, 1, page_fault);
+    // 中断号15由Intel保留,不能使用
+    set_trap_gate(16, 1, x87_FPU_error);
+    set_trap_gate(17, 1, alignment_check);
+    set_trap_gate(18, 1, machine_check);
+    set_trap_gate(19, 1, SIMD_exception);
+    set_trap_gate(20, 1, virtualization_exception);
+    // 中断号21-31由Intel保留,不能使用
+
+    // 32-255为用户自定义中断内部
+
+    /*
+    set_trap_gate(0, 1, divide_error);
+    set_trap_gate(1, 1, debug);
+    set_intr_gate(2, 1, nmi);
+    set_system_trap_gate(3, 1, int3);
+    set_system_trap_gate(4, 1, overflow);
+    set_system_trap_gate(5, 1, bounds);
+    set_trap_gate(6, 1, undefined_opcode);
+    set_trap_gate(7, 1, dev_not_avaliable);
+    set_trap_gate(8, 1, double_fault);
+    set_trap_gate(9, 1, coprocessor_segment_overrun);
+    set_trap_gate(10, 1, invalid_TSS);
+    set_trap_gate(11, 1, segment_not_exists);
+    set_trap_gate(12, 1, stack_segment_fault);
+    set_trap_gate(13, 1, general_protection);
+    set_trap_gate(14, 1, page_fault);
+    // 中断号15由Intel保留,不能使用
+    set_trap_gate(16, 1, x87_FPU_error);
+    set_trap_gate(17, 1, alignment_check);
+    set_trap_gate(18, 1, machine_check);
+    set_trap_gate(19, 1, SIMD_exception);
+    set_trap_gate(20, 1, virtualization_exception);
+    */
+}

+ 3 - 1
kernel/exception/trap.h

@@ -16,7 +16,7 @@
  * @brief 初始化系统中断表
  * 
  */
-void sys_vector_init();
+
 
 //除法错误
 void divide_error();
@@ -47,3 +47,5 @@ void alignment_check();
 void machine_check();
 void SIMD_exception();
 void virtualization_exception();
+
+void sys_vector_init();

+ 2 - 2
kernel/main.c

@@ -179,7 +179,7 @@ void system_initialize()
     printk_init(8, 16);
     kinfo("Kernel Starting...");
     // 重新加载gdt和idt
-
+    
     ul tss_item_addr = (ul)phys_2_virt(0x7c00);
     kdebug("TSS64_Table=%#018lx", (void *)TSS64_Table);
     kdebug("&TSS64_Table=%#018lx", (void *)&TSS64_Table);
@@ -207,7 +207,7 @@ void system_initialize()
     irq_init();
 
     softirq_init();
-
+    
     // 先初始化系统调用模块
     syscall_init();
     //  再初始化进程模块。顺序不能调转