具有上半部内核和中断的三重故障

问题描述 投票:0回答:1

我正在开发一个用于学习目的的小型操作系统(此处的代码:https://github.com/davidedellagiustina/ScratchOS

我有一个上半部内核0xc0004000运行,映射到物理0x4000。默认页面目录正确地映射了该区域,然后有一个用于标识映射前1MB RAM的条目(需要跳到上半部分)。输入上半部分后,删除页面目录的第一项,使TLB无效,一切都很好(如果尝试访问地址0x4000,则会出现页面错误,因此页面目录已成功更新)。

之后,我为时间和键盘设置了一个中断向量和中断处理函数,最终我尝试创建一个新的,更完整的页面目录并替换启动目录,但是替换旧目录时出现三重故障。 。

目前,避免三重故障的唯一方法是加载一个新的页面目录,该目录映射身份映射到前1MB RAM,甚至尝试在加载后删除页面目录的第一个条目(就像我在启动过程中所做的那样)会导致三重错误(因此身份映射必须留在那儿)。

我能够发现禁用中断之前切换页表(甚至在切换到保护模式后甚至从不重新启用它们,更早的时候在底部功能asm volatile("sti");的引导[注释指令irq_init()中启动) src/cpu/isr.c进行测试]可以防止CPU发生三重故障。因此,我想我的IDT(文件src/cpu/idt.*src/cpu/isr.*)或GDT(切换到保护模式时在启动过程中重新加载,文件src/boot/bootsect.asmsrc/boot/gdt.asm)可能会出现问题。我对两个结构中加载的所有地址进行了仔细检查。我想念什么?在我看来,它具有三重故障,因为在某些时候,没有首页的身份映射,它无法找到整个中断向量(该向量已加载到内核内部的虚拟内存中,因此映射到物理首页),但是奇怪的行为是(请参见第一段)如果没有身份映射的页面目录映射到第一个1MB是引导目录,则不会抱怨。

有人可以帮忙找出我的错误吗?

paging virtual-memory interrupt-handling osdev fault
1个回答
2
投票

gdt和idt寄存器都使用虚拟地址。禁用低位映射时,这意味着对gdt或idt的下一次引用将导致页面错误。您需要在删除unity-page之前,以相等的高地址重载这两个寄存器。

© www.soinside.com 2019 - 2024. All rights reserved.