c++ - 启用中断时的 QEMU 三重故障

标签 c++ c assembly kernel

我正在开发一个简单的操作系统,目前正在尝试加载 IDT。我在编译期间没有收到任何错误,但是当我尝试启用中断时 QEMU 出现三重故障。

我已经用 iHex 查看了 EIP 寄存器中的地址,但它似乎是自动生成的代码,因为它不在内核代码中。我也曾尝试在我的 C++ 代码中加载 GDT,但没有任何区别,我已经将它加载到我的引导加载程序中。

IDT安装函数

void idt_install()
{
    /* Sets the special IDT pointer up, just like in 'gdt.c' */
    idtp.limit = (sizeof (struct idt_entry) * 256) - 1;
    idtp.base = (unsigned int) idt;

    /* Clear out the entire IDT, initializing it to zeros */
    memset(&idt, 0, sizeof(struct idt_entry) * 256);

    /* Add any new ISRs to the IDT here using idt_set_gate */



    /* Points the processor's internal register to the new IDT */
    idt_load();
}

kernel_init函数中的相关代码 idt_install();

__asm__ __volatile__ ("sti");

它应该加载 IDT 并启用中断,但是我遇到三重故障并且 QEMU 反复重启。以下是使用 -d int 选项运行 QEMU 的结果。

EAX=000000fa EBX=000b8022 ECX=000b8000 EDX=00000060
ESI=00007e12 EDI=00000000 EBP=0000de88 ESP=0000de70
EIP=00007e4a EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00007c43 00000018
IDT=     000096c0 000007ff
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 
DR6=ffff0ff0 DR7=00000400
CCS=00000000 CCD=0000de54 CCO=EFLAGS  
EFER=0000000000000000
check_exception old: 0xffffffff new 0xd
     1: v=0d e=0042 i=0 cpl=0 IP=0008:00007e4a pc=00007e4a SP=0010:0000de70 env->regs[R_EAX]=000000fa
EAX=000000fa EBX=000b8022 ECX=000b8000 EDX=00000060
ESI=00007e12 EDI=00000000 EBP=0000de88 ESP=0000de70
EIP=00007e4a EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00007c43 00000018
IDT=     000096c0 000007ff
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 
DR6=ffff0ff0 DR7=00000400
CCS=00000000 CCD=0000de54 CCO=EFLAGS  
EFER=0000000000000000
check_exception old: 0xd new 0xd
     2: v=08 e=0000 i=0 cpl=0 IP=0008:00007e4a pc=00007e4a SP=0010:0000de70 env->regs[R_EAX]=000000fa
EAX=000000fa EBX=000b8022 ECX=000b8000 EDX=00000060
ESI=00007e12 EDI=00000000 EBP=0000de88 ESP=0000de70
EIP=00007e4a EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00007c43 00000018
IDT=     000096c0 000007ff
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 
DR6=ffff0ff0 DR7=00000400
CCS=00000000 CCD=0000de54 CCO=EFLAGS  
EFER=0000000000000000
check_exception old: 0x8 new 0xd

最佳答案

好的,我刚刚解决了这个问题。我忘记运行我的 install_isrs 函数。我不知道为什么这花了我几天时间才意识到,但如果其他人遇到这个问题,我只能说确保你没有遗漏一行会毁掉整个内核的代码。

关于c++ - 启用中断时的 QEMU 三重故障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57373848/

相关文章:

assembly - 最小操作码大小 x86-64 strlen 实现

c++ - 将数据从工作线程发送到 Qt 中的 gui 线程

c++ - Eigen:编码风格对性能的影响

c - C 中的指针赋值、地址运算符和解引用指针

c - 释放内存失败

assembly - Z80 汇编器的问题

c++ - 是否可以在运行时定义要在 STXXL 中排序的类型的长度?

c++ - WriteFile Hook 无法捕获写入文件操作

c - 初始化变量时大小写入无效(Valgrind 和 C)

assembly - MIPS 和 ARM 数据路径之间的区别