diff --git a/kernel/exception/entry.S b/kernel/exception/entry.S index e7013ad2..9a0a53cb 100644 --- a/kernel/exception/entry.S +++ b/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 + pushq %rax + movq %es, %rax + pushq %rax + movq %ds, %rax + pushq %rax + xorq %rax, %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 %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 diff --git a/kernel/exception/gate.h b/kernel/exception/gate.h index 5d519496..758bcf67 100644 --- a/kernel/exception/gate.h +++ b/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表的内容 * diff --git a/kernel/exception/irq.c b/kernel/exception/irq.c index 68eb6052..90a291e4 100644 --- a/kernel/exception/irq.c +++ b/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 } diff --git a/kernel/exception/trap.c b/kernel/exception/trap.c index 83efd6ba..c79b5b96 100644 --- a/kernel/exception/trap.c +++ b/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, ÷_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保留,请勿使用 \ No newline at end of file +// 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); + */ +} \ No newline at end of file diff --git a/kernel/exception/trap.h b/kernel/exception/trap.h index f7a52c88..00abac92 100644 --- a/kernel/exception/trap.h +++ b/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(); \ No newline at end of file diff --git a/kernel/main.c b/kernel/main.c index 69fef6fb..51464a28 100644 --- a/kernel/main.c +++ b/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(); // 再初始化进程模块。顺序不能调转