mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 07:06:47 +00:00
解决了#DE会触发#UD的问题
This commit is contained in:
parent
f5f36aafd8
commit
d78db8225c
@ -1,6 +1,6 @@
|
|||||||
#include"../common/asm.h"
|
#include"../common/asm.h"
|
||||||
.code64
|
.code64
|
||||||
.section .text
|
//.section .text
|
||||||
|
|
||||||
R15 = 0x00
|
R15 = 0x00
|
||||||
R14 = 0x08
|
R14 = 0x08
|
||||||
@ -56,7 +56,7 @@ Restore_all:
|
|||||||
|
|
||||||
ret_from_exception:
|
ret_from_exception:
|
||||||
// === 从中断中返回 ===
|
// === 从中断中返回 ===
|
||||||
.code64
|
|
||||||
ENTRY(ret_from_intr)
|
ENTRY(ret_from_intr)
|
||||||
jmp Restore_all
|
jmp Restore_all
|
||||||
|
|
||||||
@ -64,28 +64,27 @@ ENTRY(ret_from_intr)
|
|||||||
Err_Code:
|
Err_Code:
|
||||||
// ===== 有错误码的情况下,保存寄存器并跳转服务程序
|
// ===== 有错误码的情况下,保存寄存器并跳转服务程序
|
||||||
|
|
||||||
pushq %rax
|
pushq %rax
|
||||||
movq %es, %rax
|
movq %es, %rax
|
||||||
pushq %rax
|
pushq %rax
|
||||||
movq %ds, %rax
|
movq %ds, %rax
|
||||||
pushq %rax
|
pushq %rax
|
||||||
|
xorq %rax, %rax
|
||||||
|
|
||||||
xorq %rax, %rax
|
pushq %rbp
|
||||||
|
pushq %rdi
|
||||||
pushq %rbp
|
pushq %rsi
|
||||||
pushq %rdi
|
pushq %rdx
|
||||||
pushq %rsi
|
pushq %rcx
|
||||||
pushq %rdx
|
pushq %rbx
|
||||||
pushq %rcx
|
pushq %r8
|
||||||
pushq %rbx
|
pushq %r9
|
||||||
pushq %r8
|
pushq %r10
|
||||||
pushq %r9
|
pushq %r11
|
||||||
pushq %r10
|
pushq %r12
|
||||||
pushq %r11
|
pushq %r13
|
||||||
pushq %r12
|
pushq %r14
|
||||||
pushq %r13
|
pushq %r15
|
||||||
pushq %r14
|
|
||||||
pushq %r15
|
|
||||||
|
|
||||||
cld
|
cld
|
||||||
|
|
||||||
@ -99,7 +98,7 @@ Err_Code:
|
|||||||
movq %rsp, %rdi // 把栈指针装入rdi,作为函数的第一个的参数
|
movq %rsp, %rdi // 把栈指针装入rdi,作为函数的第一个的参数
|
||||||
|
|
||||||
|
|
||||||
callq %rdx //调用服务程序 带*号表示调用的是绝对地址
|
callq *%rdx //调用服务程序 带*号表示调用的是绝对地址
|
||||||
jmp ret_from_exception
|
jmp ret_from_exception
|
||||||
|
|
||||||
// 系统调用入口
|
// 系统调用入口
|
||||||
@ -181,6 +180,7 @@ ENTRY(divide_error)
|
|||||||
pushq $0 //由于#DE不会产生错误码,但是为了保持弹出结构的一致性,故也压入一个错误码0
|
pushq $0 //由于#DE不会产生错误码,但是为了保持弹出结构的一致性,故也压入一个错误码0
|
||||||
pushq %rax // 先将rax入栈
|
pushq %rax // 先将rax入栈
|
||||||
leaq do_divide_error(%rip), %rax // 获取中断服务程序的地址
|
leaq do_divide_error(%rip), %rax // 获取中断服务程序的地址
|
||||||
|
|
||||||
xchgq %rax, (%rsp) // 把FUNC的地址换入栈中
|
xchgq %rax, (%rsp) // 把FUNC的地址换入栈中
|
||||||
jmp Err_Code
|
jmp Err_Code
|
||||||
|
|
||||||
|
@ -100,9 +100,8 @@ void set_tss_descriptor(unsigned int n, void *addr)
|
|||||||
|
|
||||||
unsigned long limit = 103;
|
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
|
*(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 + 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
|
_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表的内容
|
* @brief 初始化TSS表的内容
|
||||||
*
|
*
|
||||||
|
@ -46,15 +46,14 @@
|
|||||||
// 构造中断entry
|
// 构造中断entry
|
||||||
// 为了复用返回函数的代码,需要压入一个错误码0
|
// 为了复用返回函数的代码,需要压入一个错误码0
|
||||||
|
|
||||||
#define Build_IRQ(number) \
|
#define Build_IRQ(number) \
|
||||||
void IRQ_NAME(number); \
|
void IRQ_NAME(number); \
|
||||||
__asm__(SYMBOL_NAME_STR(IRQ) #number "interrupt: \n\t" \
|
__asm__(SYMBOL_NAME_STR(IRQ) #number "interrupt: \n\t" \
|
||||||
"pushq $0x00 \n\t" \
|
"pushq $0x00 \n\t" SAVE_ALL_REGS \
|
||||||
SAVE_ALL_REGS \
|
"movq %rsp, %rdi \n\t" \
|
||||||
"movq %rsp, %rdi \n\t" \
|
|
||||||
"leaq ret_from_intr(%rip), %rax \n\t" \
|
"leaq ret_from_intr(%rip), %rax \n\t" \
|
||||||
"pushq %rax \n\t" \
|
"pushq %rax \n\t" \
|
||||||
"movq $"#number", %rsi \n\t" \
|
"movq $" #number ", %rsi \n\t" \
|
||||||
"jmp do_IRQ \n\t");
|
"jmp do_IRQ \n\t");
|
||||||
|
|
||||||
// 构造中断入口
|
// 构造中断入口
|
||||||
@ -112,22 +111,23 @@ void (*interrupt_table[24])(void) =
|
|||||||
IRQ0x37interrupt,
|
IRQ0x37interrupt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 声明10个IPI消息处理程序,向量号从200(0xc8)开始
|
* @brief 声明10个IPI消息处理程序,向量号从200(0xc8)开始
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Build_IRQ(0xc8)
|
/*
|
||||||
Build_IRQ(0xc9)
|
*/
|
||||||
Build_IRQ(0xca)
|
Build_IRQ(0xc8);
|
||||||
Build_IRQ(0xcb)
|
Build_IRQ(0xc9);
|
||||||
Build_IRQ(0xcc)
|
Build_IRQ(0xca);
|
||||||
Build_IRQ(0xcd)
|
Build_IRQ(0xcb);
|
||||||
Build_IRQ(0xce)
|
Build_IRQ(0xcc);
|
||||||
Build_IRQ(0xcf)
|
Build_IRQ(0xcd);
|
||||||
Build_IRQ(0xd0)
|
Build_IRQ(0xce);
|
||||||
Build_IRQ(0xd1)
|
Build_IRQ(0xcf);
|
||||||
|
Build_IRQ(0xd0);
|
||||||
|
Build_IRQ(0xd1);
|
||||||
|
|
||||||
// 初始化IPI中断服务程序数组
|
// 初始化IPI中断服务程序数组
|
||||||
void (*SMP_interrupt_table[SMP_IRQ_NUM])(void) =
|
void (*SMP_interrupt_table[SMP_IRQ_NUM])(void) =
|
||||||
@ -189,7 +189,7 @@ int irq_unregister(ul irq_num)
|
|||||||
p->parameter = NULL;
|
p->parameter = NULL;
|
||||||
p->flags = 0;
|
p->flags = 0;
|
||||||
p->handler = NULL;
|
p->handler = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,10 +203,8 @@ void irq_init()
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
apic_init();
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -3,63 +3,13 @@
|
|||||||
#include "../process/ptrace.h"
|
#include "../process/ptrace.h"
|
||||||
#include "../common/kprint.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 除法错误
|
// 0 #DE 除法错误
|
||||||
void do_divide_error(struct pt_regs *regs, unsigned long error_code)
|
void do_divide_error(struct pt_regs *regs, unsigned long error_code)
|
||||||
{
|
{
|
||||||
kerror("do_divide_error(0)");
|
//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),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\n", error_code, regs->rsp, regs->rip);
|
||||||
|
|
||||||
while (1)
|
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 初始化系统中断表
|
* @brief 初始化系统中断表
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void sys_vector_init();
|
|
||||||
|
|
||||||
//除法错误
|
//除法错误
|
||||||
void divide_error();
|
void divide_error();
|
||||||
@ -47,3 +47,5 @@ void alignment_check();
|
|||||||
void machine_check();
|
void machine_check();
|
||||||
void SIMD_exception();
|
void SIMD_exception();
|
||||||
void virtualization_exception();
|
void virtualization_exception();
|
||||||
|
|
||||||
|
void sys_vector_init();
|
@ -179,7 +179,7 @@ void system_initialize()
|
|||||||
printk_init(8, 16);
|
printk_init(8, 16);
|
||||||
kinfo("Kernel Starting...");
|
kinfo("Kernel Starting...");
|
||||||
// 重新加载gdt和idt
|
// 重新加载gdt和idt
|
||||||
|
|
||||||
ul tss_item_addr = (ul)phys_2_virt(0x7c00);
|
ul tss_item_addr = (ul)phys_2_virt(0x7c00);
|
||||||
kdebug("TSS64_Table=%#018lx", (void *)TSS64_Table);
|
kdebug("TSS64_Table=%#018lx", (void *)TSS64_Table);
|
||||||
kdebug("&TSS64_Table=%#018lx", (void *)&TSS64_Table);
|
kdebug("&TSS64_Table=%#018lx", (void *)&TSS64_Table);
|
||||||
@ -207,7 +207,7 @@ void system_initialize()
|
|||||||
irq_init();
|
irq_init();
|
||||||
|
|
||||||
softirq_init();
|
softirq_init();
|
||||||
|
|
||||||
// 先初始化系统调用模块
|
// 先初始化系统调用模块
|
||||||
syscall_init();
|
syscall_init();
|
||||||
// 再初始化进程模块。顺序不能调转
|
// 再初始化进程模块。顺序不能调转
|
||||||
|
Loading…
x
Reference in New Issue
Block a user