c++ - 启用中断时 QEMU 三重故障
问题描述
我正在开发一个简单的操作系统,目前正在尝试加载 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 函数。我不知道为什么我花了好几天才意识到这一点,但如果其他人遇到这个问题,我只能说确保你没有遗漏一行代码,这会破坏你的整个内核。
推荐阅读
- node.js - 如何将列表数组转换为节点js中的单个列表
- http - 如何使用 observable 从 Angular 的假公共 api 中仅获取一条数据记录?
- java - 为什么我在尝试使用 Spring RestTemplate 对 REST API 执行简单的 GET all 时获得此错误响应?
- python - 过滤数据框中的组
- nagios - Nagios nrpe 插件安装在远程主机上
- php - 我们可以在 psr-4 composer 命名空间路径之后手动添加子目录吗?
- python - Flask CLI 显示“TypeError:异常必须从 BaseException 派生”
- datetime - 如何从 GUI 获取有效日期作为输入
- azure-devops - Azure 管道默认使用错误的代理
- ios - 对象捕获命令行不适合我