c - 自制内核中的三重故障

标签 c assembly operating-system kernel

我正在尝试编写一个内核,主要是为了娱乐目的,但我遇到了一个问题,我认为它是三重故障。在我尝试启用分页之前一切正常。破坏的代码是这样的:

void switch_page_directory(page_directory_t *dir){

 current_directory = dir;
 asm volatile("mov %0, %%cr3":: "r"(&dir->tablesPhysical));

 u32int cr0;
 asm volatile("mov %%cr0, %0": "=r"(cr0));

 cr0 |= 0x80000000;//enable paging
 asm volatile("mov %0, %%cr0":: "r"(cr0)); //this line breaks


}//switch page directory

我一直在关注各种教程/文档,但我用来分页的是 http://www.jamesmolloy.co.uk/tutorial_html/6.-Paging.html .我不确定还有哪些其他代码有助于解决这个问题,但如果我应该提供更多代码,我会非常乐意这样做。

编辑=====

我相信 CS、DS 和 SS 正在选择正确的条目,这是用于设置它们的代码

global gdt_flush     
extern gp            
gdt_flush:

    lgdt [gp]        ; Load the GDT with our 'gp' which is a special pointer
    mov ax, 0x10      ; 0x10 is the offset in the GDT to our data segment

    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax

    jmp 0x08:flush2   ; 0x08 is the offset to our code segment: Far jump!

flush2:
    ret               ; Returns back to the C code!

这是 gdt 结构本身

struct gdt_entry{
    unsigned short limit_low;
    unsigned short base_low;
    unsigned char base_middle;
    unsigned char access;
    unsigned char granularity;
    unsigned char base_high;
} __attribute__((packed));

struct gdt_ptr{
    unsigned short limit;
    unsigned int base;
} __attribute__((packed));

struct gdt_entry gdt[5];
struct gdt_ptr gp;

IDT 与此非常相似。

最佳答案

GDT:您没有说 GDT 条目的内容是什么,但是您显示的内容看起来与 earlier part of the tutorial you linked to 非常相似并且如果您以相同的方式设置条目,那么一切都应该很好(即平面段映射,CS 的环 0 代码段,其他所有内容的环 0 数据段,都以 0 为基数和限制4GB)。

IDT:如果中断被禁用并且您(还)不希望导致页面错误,则可能无论如何都没有关系。

页表:不正确的页表似乎最有可能是可疑的。确保您的身份映射覆盖所有您正在使用的代码、数据和堆栈内存(至少)。

http://www.jamesmolloy.co.uk/tutorial_html/6.-Paging.html底部链接的源代码肯定会构建一些确实可以与 QEMU 和 Bochs 一起正常工作的东西,因此希望您可以将您正在做的事情与正在做的事情进行比较,并找出问题所在。

QEMU 总体来说不错,但我会推荐 Bochs用于开发真正低级的东西 - 它包括(或可以配置为包括)一个非常方便的 internal debugger .例如在config文件的cpu:行设置reset_on_triple_fault=0,在switch_page_directory()代码中设置断点,运行到断点处,然后单步指令,看看会发生什么......

关于c - 自制内核中的三重故障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4081246/

相关文章:

c - 遇到永远循环的问题

c - 如何从 .o 文件中删除 undefined symbol

c - 如何从 union 内部引用 union 成员?

gcc - avr-gcc内联汇编: Jump to label with runtime offset

assembly - 无法解析的外部符号_WinMainCRTStartup

c++ - 使用 sleep() 时生产者消费者(使用 Monitor)代码不工作?

c - .bin 和 .dat 文件有什么区别?

c# - Java 与 C# 机器代码做同样的事情

javascript - 如何在 JavaScript 中检测 Mac OS X 版本

operating-system - 对于内核/操作系统,C 仍然是它吗?