mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
解决了#DE会触发#UD的问题
This commit is contained in:
parent
f5f36aafd8
commit
d78db8225c
@ -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
|
||||
|
||||
|
@ -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表的内容
|
||||
*
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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保留,请勿使用
|
||||
// 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);
|
||||
*/
|
||||
}
|
@ -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();
|
@ -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();
|
||||
// 再初始化进程模块。顺序不能调转
|
||||
|
Loading…
x
Reference in New Issue
Block a user