From 4830d04c2f167faf81ea8db9b3baa784766b5a55 Mon Sep 17 00:00:00 2001 From: longjin Date: Sun, 16 Oct 2022 18:19:05 +0800 Subject: [PATCH 1/2] =?UTF-8?q?bugfix:=20=E8=A7=A3=E5=86=B3=E4=BA=86ignore?= =?UTF-8?q?=5Fint=E5=9C=A8=E8=BF=90=E8=A1=8C=E6=97=B6=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E7=A0=B4=E5=9D=8F=E8=BF=9B=E7=A8=8B=E6=89=A7=E8=A1=8C=E4=B8=8A?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/driver/interrupt/apic/apic.c | 3 +- kernel/driver/interrupt/apic/apic.h | 2 +- kernel/exception/entry.S | 7 ++ kernel/exception/irq.c | 150 ++++++++++++---------------- kernel/head.S | 4 +- kernel/main.c | 6 -- 6 files changed, 76 insertions(+), 96 deletions(-) diff --git a/kernel/driver/interrupt/apic/apic.c b/kernel/driver/interrupt/apic/apic.c index 806fbd72..63c5cd61 100644 --- a/kernel/driver/interrupt/apic/apic.c +++ b/kernel/driver/interrupt/apic/apic.c @@ -344,7 +344,7 @@ void apic_local_apic_init() * @brief 初始化apic控制器 * */ -void apic_init() +int apic_init() { // 初始化中断门, 中断使用rsp0防止在软中断时发生嵌套,然后处理器重新加载导致数据被抹掉 for (int i = 32; i <= 55; ++i) @@ -386,6 +386,7 @@ void apic_init() kwarn("Cannot get RCBA address. RCBA_phys=%#010lx", RCBA_phys); } sti(); + return 0; } /** * @brief 中断服务程序 diff --git a/kernel/driver/interrupt/apic/apic.h b/kernel/driver/interrupt/apic/apic.h index 5d64b105..3a001ce0 100644 --- a/kernel/driver/interrupt/apic/apic.h +++ b/kernel/driver/interrupt/apic/apic.h @@ -290,7 +290,7 @@ void apic_init_ap_core_local_apic(); * @brief 初始化apic控制器 * */ -void apic_init(); +int apic_init(); /** * @brief 读取指定类型的 Interrupt Control Structure diff --git a/kernel/exception/entry.S b/kernel/exception/entry.S index df38194f..2159f5bf 100644 --- a/kernel/exception/entry.S +++ b/kernel/exception/entry.S @@ -351,4 +351,11 @@ ENTRY(syscall_int) xchgq %rax, (%rsp) // 把FUNC的地址换入栈中 jmp Err_Code +// irq模块初始化后的ignore_int入点 +ENTRY(ignore_int) + pushq $0 + pushq %rax + leaq ignore_int_handler(%rip), %rax // 获取ignore处理程序的地址 + xchgq %rax, (%rsp) // 把FUNC的地址换入栈中 + jmp Err_Code diff --git a/kernel/exception/irq.c b/kernel/exception/irq.c index eb066eee..d68da32d 100644 --- a/kernel/exception/irq.c +++ b/kernel/exception/irq.c @@ -2,47 +2,47 @@ #include "irq.h" #include - #if _INTR_8259A_ #include #else #include #endif +#include "gate.h" #include #include #include -#include "gate.h" #include +extern void ignore_int(); #pragma GCC push_options #pragma GCC optimize("O0") // 保存函数调用现场的寄存器 -#define SAVE_ALL_REGS \ - "cld; \n\t" \ - "pushq %rax; \n\t" \ - "pushq %rax; \n\t" \ - "movq %es, %rax; \n\t" \ - "pushq %rax; \n\t" \ - "movq %ds, %rax; \n\t" \ - "pushq %rax; \n\t" \ - "xorq %rax, %rax;\n\t" \ - "pushq %rbp; \n\t" \ - "pushq %rdi; \n\t" \ - "pushq %rsi; \n\t" \ - "pushq %rdx; \n\t" \ - "pushq %rcx; \n\t" \ - "pushq %rbx; \n\t" \ - "pushq %r8 ; \n\t" \ - "pushq %r9 ; \n\t" \ - "pushq %r10; \n\t" \ - "pushq %r11; \n\t" \ - "pushq %r12; \n\t" \ - "pushq %r13; \n\t" \ - "pushq %r14; \n\t" \ - "pushq %r15; \n\t" \ - "movq $0x10, %rdx;\n\t" \ - "movq %rdx, %ds; \n\t" \ +#define SAVE_ALL_REGS \ + "cld; \n\t" \ + "pushq %rax; \n\t" \ + "pushq %rax; \n\t" \ + "movq %es, %rax; \n\t" \ + "pushq %rax; \n\t" \ + "movq %ds, %rax; \n\t" \ + "pushq %rax; \n\t" \ + "xorq %rax, %rax;\n\t" \ + "pushq %rbp; \n\t" \ + "pushq %rdi; \n\t" \ + "pushq %rsi; \n\t" \ + "pushq %rdx; \n\t" \ + "pushq %rcx; \n\t" \ + "pushq %rbx; \n\t" \ + "pushq %r8 ; \n\t" \ + "pushq %r9 ; \n\t" \ + "pushq %r10; \n\t" \ + "pushq %r11; \n\t" \ + "pushq %r12; \n\t" \ + "pushq %r13; \n\t" \ + "pushq %r14; \n\t" \ + "pushq %r15; \n\t" \ + "movq $0x10, %rdx;\n\t" \ + "movq %rdx, %ds; \n\t" \ "movq %rdx, %es; \n\t" // 定义IRQ处理函数的名字格式:IRQ+中断号+interrupt @@ -52,14 +52,13 @@ // 构造中断entry // 为了复用返回函数的代码,需要压入一个错误码0 // todo: 将这里改为volatile,也许能解决编译选项为O1时,系统崩溃的问题 -#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" \ +#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" \ "jmp do_IRQ \n\t"); // 构造中断入口 @@ -89,32 +88,11 @@ Build_IRQ(0x36); Build_IRQ(0x37); // 初始化中断数组 -void (*interrupt_table[24])(void) = - { - IRQ0x20interrupt, - IRQ0x21interrupt, - IRQ0x22interrupt, - IRQ0x23interrupt, - IRQ0x24interrupt, - IRQ0x25interrupt, - IRQ0x26interrupt, - IRQ0x27interrupt, - IRQ0x28interrupt, - IRQ0x29interrupt, - IRQ0x2ainterrupt, - IRQ0x2binterrupt, - IRQ0x2cinterrupt, - IRQ0x2dinterrupt, - IRQ0x2einterrupt, - IRQ0x2finterrupt, - IRQ0x30interrupt, - IRQ0x31interrupt, - IRQ0x32interrupt, - IRQ0x33interrupt, - IRQ0x34interrupt, - IRQ0x35interrupt, - IRQ0x36interrupt, - IRQ0x37interrupt, +void (*interrupt_table[24])(void) = { + IRQ0x20interrupt, IRQ0x21interrupt, IRQ0x22interrupt, IRQ0x23interrupt, IRQ0x24interrupt, IRQ0x25interrupt, + IRQ0x26interrupt, IRQ0x27interrupt, IRQ0x28interrupt, IRQ0x29interrupt, IRQ0x2ainterrupt, IRQ0x2binterrupt, + IRQ0x2cinterrupt, IRQ0x2dinterrupt, IRQ0x2einterrupt, IRQ0x2finterrupt, IRQ0x30interrupt, IRQ0x31interrupt, + IRQ0x32interrupt, IRQ0x33interrupt, IRQ0x34interrupt, IRQ0x35interrupt, IRQ0x36interrupt, IRQ0x37interrupt, }; /** @@ -139,18 +117,9 @@ Build_IRQ(0x80); // 系统调用入口 void (*syscall_intr_table[1])(void) = {IRQ0x80interrupt}; // 初始化IPI中断服务程序数组 -void (*SMP_interrupt_table[SMP_IRQ_NUM])(void) = - { - IRQ0xc8interrupt, - IRQ0xc9interrupt, - IRQ0xcainterrupt, - IRQ0xcbinterrupt, - IRQ0xccinterrupt, - IRQ0xcdinterrupt, - IRQ0xceinterrupt, - IRQ0xcfinterrupt, - IRQ0xd0interrupt, - IRQ0xd1interrupt, +void (*SMP_interrupt_table[SMP_IRQ_NUM])(void) = { + IRQ0xc8interrupt, IRQ0xc9interrupt, IRQ0xcainterrupt, IRQ0xcbinterrupt, IRQ0xccinterrupt, + IRQ0xcdinterrupt, IRQ0xceinterrupt, IRQ0xcfinterrupt, IRQ0xd0interrupt, IRQ0xd1interrupt, }; // 初始化local apic中断服务程序数组 @@ -164,18 +133,9 @@ Build_IRQ(0x9c); Build_IRQ(0x9d); Build_IRQ(0x9e); Build_IRQ(0x9f); -void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void) = - { - IRQ0x96interrupt, - IRQ0x97interrupt, - IRQ0x98interrupt, - IRQ0x99interrupt, - IRQ0x9ainterrupt, - IRQ0x9binterrupt, - IRQ0x9cinterrupt, - IRQ0x9dinterrupt, - IRQ0x9einterrupt, - IRQ0x9finterrupt, +void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void) = { + IRQ0x96interrupt, IRQ0x97interrupt, IRQ0x98interrupt, IRQ0x99interrupt, IRQ0x9ainterrupt, + IRQ0x9binterrupt, IRQ0x9cinterrupt, IRQ0x9dinterrupt, IRQ0x9einterrupt, IRQ0x9finterrupt, }; /** @@ -189,7 +149,8 @@ void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void) = * @param irq_name 中断名 * @return int */ -int irq_register(ul irq_num, void *arg, void (*handler)(ul irq_num, ul parameter, struct pt_regs *regs), ul paramater, hardware_intr_controller *controller, char *irq_name) +int irq_register(ul irq_num, void *arg, void (*handler)(ul irq_num, ul parameter, struct pt_regs *regs), ul paramater, + hardware_intr_controller *controller, char *irq_name) { // 由于为I/O APIC分配的中断向量号是从32开始的,因此要减去32才是对应的interrupt_desc的元素 irq_desc_t *p = NULL; @@ -252,6 +213,10 @@ int irq_unregister(ul irq_num) */ void irq_init() { + // 将idt重置为新的ignore_int入点(此前在head.S中有设置, + // 但是那个不完整,某些版本的编译器的输出,在真机运行时会破坏进程执行环境,从而导致#GP + for (int i = 0; i < 256; ++i) + set_intr_gate(i, 0, ignore_int); #if _INTR_8259A_ init_8259A(); #else @@ -261,4 +226,15 @@ void irq_init() #endif } -#pragma GCC optimize("O0") \ No newline at end of file +#pragma GCC optimize("O0") + +/** + * @brief 当系统收到未知的中断时,执行此处理函数 + * + * @param regs + * @param error_code + */ +void ignore_int_handler(struct pt_regs *regs, unsigned long error_code) +{ + kwarn("Unknown interrupt or fault at RIP.\n"); +} \ No newline at end of file diff --git a/kernel/head.S b/kernel/head.S index cc840da7..1f9e2c78 100644 --- a/kernel/head.S +++ b/kernel/head.S @@ -326,6 +326,7 @@ entry64: jnc start_smp setup_IDT: + // 该部分代码只在启动初期使用,后面的c文件中会重新设置IDT, leaq m_ignore_int(%rip), %rdx // 将ignore_int的地址暂时存到中段描述符的高8B movq $(0x08 << 16), %rax // 设置段选择子。由IDT结构和段选择子结构可知,本行设置段基地址为0x100000,TI=0,RPL=0 movw %dx, %ax @@ -460,6 +461,7 @@ go_to_smp_kernel: .quad smp_ap_start // ==== 异常/中断处理模块 ignore int: 忽略中断 +// (该部分代码只在启动初期使用,后面的c文件中会重新设置IDT,从而重设ignore_int的中断入点) m_ignore_int: // 切换到c语言的ignore_int movq go_to_ignore_int(%rip), %rax @@ -470,7 +472,7 @@ m_ignore_int: go_to_ignore_int: - .quad ignore_int + .quad ignore_int_handler ENTRY(head_stack_start) diff --git a/kernel/main.c b/kernel/main.c index e8f11e2f..b48d505c 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -209,10 +209,4 @@ void Start_Kernel(void) while (1) pause(); } - -void ignore_int() -{ - kwarn("Unknown interrupt or fault at RIP.\n"); - sti(); -} #pragma GCC pop_options \ No newline at end of file From d364ed7d796633d7189c44dfc433abdcf40250fa Mon Sep 17 00:00:00 2001 From: longjin Date: Sun, 16 Oct 2022 20:54:02 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=99=A8=E5=BC=82=E5=B8=B8=E9=99=B7=E9=98=B1=E9=97=A8=E8=A2=AB?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E6=B8=85=E7=A9=BA=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/exception/irq.c | 17 +------- kernel/exception/trap.c | 92 +++++++++++++++++++++++++++++------------ 2 files changed, 67 insertions(+), 42 deletions(-) diff --git a/kernel/exception/irq.c b/kernel/exception/irq.c index d68da32d..941d47e2 100644 --- a/kernel/exception/irq.c +++ b/kernel/exception/irq.c @@ -13,7 +13,6 @@ #include #include #include -extern void ignore_int(); #pragma GCC push_options #pragma GCC optimize("O0") @@ -213,10 +212,7 @@ int irq_unregister(ul irq_num) */ void irq_init() { - // 将idt重置为新的ignore_int入点(此前在head.S中有设置, - // 但是那个不完整,某些版本的编译器的输出,在真机运行时会破坏进程执行环境,从而导致#GP - for (int i = 0; i < 256; ++i) - set_intr_gate(i, 0, ignore_int); + #if _INTR_8259A_ init_8259A(); #else @@ -227,14 +223,3 @@ void irq_init() #endif } #pragma GCC optimize("O0") - -/** - * @brief 当系统收到未知的中断时,执行此处理函数 - * - * @param regs - * @param error_code - */ -void ignore_int_handler(struct pt_regs *regs, unsigned long error_code) -{ - kwarn("Unknown interrupt or fault at RIP.\n"); -} \ No newline at end of file diff --git a/kernel/exception/trap.c b/kernel/exception/trap.c index ad05edde..fe2e2e69 100644 --- a/kernel/exception/trap.c +++ b/kernel/exception/trap.c @@ -1,15 +1,19 @@ #include "trap.h" #include "gate.h" -#include #include -#include #include +#include +#include #include + +extern void ignore_int(); + // 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\t CPU:%d\t pid=%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid); + kerror("do_divide_error(0),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\t pid=%d\n", error_code, + regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid); traceback(regs); current_pcb->state = PROC_STOPPED; sched(); @@ -20,7 +24,8 @@ void do_debug(struct pt_regs *regs, unsigned long error_code) { printk("[ "); printk_color(RED, BLACK, "ERROR / TRAP"); - printk(" ] do_debug(1),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + printk(" ] do_debug(1),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, + proc_current_cpu_id); while (1) hlt(); @@ -32,7 +37,8 @@ void do_nmi(struct pt_regs *regs, unsigned long error_code) printk("[ "); printk_color(BLUE, BLACK, "INT"); - printk(" ] do_nmi(2),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + printk(" ] do_nmi(2),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, + proc_current_cpu_id); while (1) hlt(); @@ -44,7 +50,8 @@ void do_int3(struct pt_regs *regs, unsigned long error_code) printk("[ "); printk_color(YELLOW, BLACK, "TRAP"); - printk(" ] do_int3(3),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + printk(" ] do_int3(3),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, + proc_current_cpu_id); while (1) hlt(); @@ -56,7 +63,8 @@ void do_overflow(struct pt_regs *regs, unsigned long error_code) printk("[ "); printk_color(YELLOW, BLACK, "TRAP"); - printk(" ] do_overflow(4),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + printk(" ] do_overflow(4),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); current_pcb->state = PROC_STOPPED; sched(); @@ -66,7 +74,8 @@ void do_overflow(struct pt_regs *regs, unsigned long error_code) void do_bounds(struct pt_regs *regs, unsigned long error_code) { - kerror("do_bounds(5),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_bounds(5),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, + proc_current_cpu_id); while (1) hlt(); @@ -76,7 +85,8 @@ void do_bounds(struct pt_regs *regs, unsigned long error_code) void do_undefined_opcode(struct pt_regs *regs, unsigned long error_code) { - kerror("do_undefined_opcode(6),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d, pid:%ld", error_code, regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid); + kerror("do_undefined_opcode(6),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d, pid:%ld", error_code, + regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid); traceback(regs); current_pcb->state = PROC_STOPPED; sched(); @@ -86,7 +96,8 @@ void do_undefined_opcode(struct pt_regs *regs, unsigned long error_code) void do_dev_not_avaliable(struct pt_regs *regs, unsigned long error_code) { - kerror("do_dev_not_avaliable(7),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_dev_not_avaliable(7),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); current_pcb->state = PROC_STOPPED; sched(); @@ -98,7 +109,8 @@ void do_double_fault(struct pt_regs *regs, unsigned long error_code) printk("[ "); printk_color(RED, BLACK, "Terminate"); - printk(" ] do_double_fault(8),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + printk(" ] do_double_fault(8),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); traceback(regs); current_pcb->state = PROC_STOPPED; sched(); @@ -108,7 +120,8 @@ void do_double_fault(struct pt_regs *regs, unsigned long error_code) void do_coprocessor_segment_overrun(struct pt_regs *regs, unsigned long error_code) { - kerror("do_coprocessor_segment_overrun(9),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_coprocessor_segment_overrun(9),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, + regs->rsp, regs->rip, proc_current_cpu_id); current_pcb->state = PROC_STOPPED; sched(); @@ -120,7 +133,8 @@ void do_invalid_TSS(struct pt_regs *regs, unsigned long error_code) printk("["); printk_color(RED, BLACK, "ERROR"); - printk("] do_invalid_TSS(10),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + printk("] do_invalid_TSS(10),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); printk_color(YELLOW, BLACK, "Information:\n"); // 解析错误码 @@ -149,7 +163,8 @@ void do_invalid_TSS(struct pt_regs *regs, unsigned long error_code) void do_segment_not_exists(struct pt_regs *regs, unsigned long error_code) { - kerror("do_segment_not_exists(11),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_segment_not_exists(11),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); current_pcb->state = PROC_STOPPED; sched(); @@ -159,7 +174,8 @@ void do_segment_not_exists(struct pt_regs *regs, unsigned long error_code) void do_stack_segment_fault(struct pt_regs *regs, unsigned long error_code) { - kerror("do_stack_segment_fault(12),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_stack_segment_fault(12),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); traceback(regs); current_pcb->state = PROC_STOPPED; sched(); @@ -169,9 +185,12 @@ void do_stack_segment_fault(struct pt_regs *regs, unsigned long error_code) void do_general_protection(struct pt_regs *regs, unsigned long error_code) { - kerror("do_general_protection(13),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\tpid=%ld\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid); + kerror("do_general_protection(13),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\tpid=%ld\n", error_code, + regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid); if (error_code & 0x01) - printk_color(RED, BLACK, "The exception occurred during delivery of an event external to the program,such as an interrupt or an earlier exception.\n"); + printk_color(RED, BLACK, + "The exception occurred during delivery of an event external to the program,such as an interrupt " + "or an earlier exception.\n"); if (error_code & 0x02) printk_color(RED, BLACK, "Refers to a gate descriptor in the IDT;\n"); @@ -196,10 +215,10 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code) unsigned long cr2 = 0; - __asm__ __volatile__("movq %%cr2, %0" - : "=r"(cr2)::"memory"); + __asm__ __volatile__("movq %%cr2, %0" : "=r"(cr2)::"memory"); - kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx, RBP=%#018lx, RIP:%#018lx CPU:%d, pid=%d\n", error_code, regs->rsp, regs->rbp, regs->rip, proc_current_cpu_id, current_pcb->pid); + kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx, RBP=%#018lx, RIP:%#018lx CPU:%d, pid=%d\n", error_code, + regs->rsp, regs->rbp, regs->rip, proc_current_cpu_id, current_pcb->pid); kerror("regs->rax = %#018lx\n", regs->rax); if (!(error_code & 0x01)) printk_color(RED, BLACK, "Page Not-Present,\t"); @@ -223,7 +242,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code) printk_color(RED, BLACK, "\n"); printk_color(RED, BLACK, "CR2:%#018lx\n", cr2); - + traceback(regs); current_pcb->state = PROC_STOPPED; sched(); @@ -235,7 +254,8 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code) void do_x87_FPU_error(struct pt_regs *regs, unsigned long error_code) { - kerror("do_x87_FPU_error(16),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_x87_FPU_error(16),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); while (1) hlt(); @@ -245,7 +265,8 @@ void do_x87_FPU_error(struct pt_regs *regs, unsigned long error_code) void do_alignment_check(struct pt_regs *regs, unsigned long error_code) { - kerror("do_alignment_check(17),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_alignment_check(17),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); current_pcb->state = PROC_STOPPED; sched(); @@ -255,7 +276,8 @@ void do_alignment_check(struct pt_regs *regs, unsigned long error_code) void do_machine_check(struct pt_regs *regs, unsigned long error_code) { - kerror("do_machine_check(18),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_machine_check(18),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); current_pcb->state = PROC_STOPPED; sched(); @@ -265,7 +287,8 @@ void do_machine_check(struct pt_regs *regs, unsigned long error_code) void do_SIMD_exception(struct pt_regs *regs, unsigned long error_code) { - kerror("do_SIMD_exception(19),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_SIMD_exception(19),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, + regs->rip, proc_current_cpu_id); current_pcb->state = PROC_STOPPED; sched(); @@ -275,7 +298,8 @@ void do_SIMD_exception(struct pt_regs *regs, unsigned long error_code) void do_virtualization_exception(struct pt_regs *regs, unsigned long error_code) { - kerror("do_virtualization_exception(20),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); + kerror("do_virtualization_exception(20),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, + regs->rsp, regs->rip, proc_current_cpu_id); current_pcb->state = PROC_STOPPED; sched(); @@ -283,8 +307,24 @@ void do_virtualization_exception(struct pt_regs *regs, unsigned long error_code) // 21-21 Intel保留,请勿使用 +/** + * @brief 当系统收到未知的中断时,执行此处理函数 + * + * @param regs + * @param error_code + */ +void ignore_int_handler(struct pt_regs *regs, unsigned long error_code) +{ + kwarn("Unknown interrupt or fault at RIP.\n"); +} + void sys_vector_init() { + // 将idt重置为新的ignore_int入点(此前在head.S中有设置, + // 但是那个不完整,某些版本的编译器的输出,在真机运行时会破坏进程执行环境,从而导致#GP + for (int i = 0; i < 256; ++i) + set_intr_gate(i, 0, ignore_int); + set_trap_gate(0, 0, divide_error); set_trap_gate(1, 0, debug); set_intr_gate(2, 0, nmi);