【问题标题】:enabling paging leads to triple fault (solved)启用分页导致三重故障(已解决)
【发布时间】:2021-03-25 17:38:00
【问题描述】:

如果这对将来的某人有帮助:

  • 检查全局描述符表是否工作
  • 检查页表条目结构的元素是否排序正确

这段代码对我有用:

gdt.s

section .data
gdt:
    .null:
        dq 0
    .code:
        dw 0xFFFF
        dw 0x0000
        db 0x00
        db 0x9A
        db 0xCF
        db 0x00
    .data:
        dw 0xFFFF
        dw 0x0000
        db 0x00
        db 0x92
        db 0xCF
        db 0x00

gdtr:
    dw $-gdt-1
    dd gdt

section .text

global init_global_descriptor_table
init_global_descriptor_table:
    lgdt [gdtr]
    jmp 0x08:.reload_cs

.reload_cs:
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    ret

分页.c

enum flags {
    Present = 1 << 0,
    ReadWrite = 1 << 1,
    AccessAll = 1 << 2,
    WriteThroughCashing = 1 << 3,
    DisableCashing = 1 << 4,
    Accessed = 1 << 5,
    Dirty = 1 << 6,     // only for page-table-entries
    MPages = 1 << 7,
    Global = 1 << 8,    // only for page-table-entries
};

struct entry {
    unsigned int flags : 9;
    unsigned int available : 3;
    unsigned int addr : 20;
};

extern void load_paging_directory(int *ptr);

void init_paging() {
    struct entry *dir = (struct entry *)0x00105000;
    struct entry *t1 = (struct entry *)0x00106000;      

    for (int i = 0; i < 1024; i++) {
        dir[i] = (struct entry){0};
        if (i <= 262) t1[i] = (struct entry){Present | ReadWrite, 0, i};
    }

    dir[0] = (struct entry){Present, 0, (int)t1 >> 12};
    load_paging_directory((int *)dir);
}

paging_asm.s

global load_paging_directory
load_paging_directory:
    push ebp,
    mov ebp, esp
    mov eax, [ebp + 8]
    mov cr3, eax
    mov eax, cr0
    or eax, 0x80000001
    mov cr0, eax   
    mov esp, ebp
    pop ebp
    ret

我的错误是我的结构在低位中有地址字段,在高位中有标志字段。这是一些非常奇怪的行为的原因。最后它并没有在 mov cr0, eax 处崩溃,而是在 mov esp, ebp 处崩溃。 感谢所有评论的人。

【问题讨论】:

  • 你的环境是什么?它看起来也不像是一个初学者级别的项目。
  • 我使用 qemu 进行仿真,使用 gcc 交叉编译器,目标 i686-elf 带有标志 -std=gnu99 -ffreestanding -g
  • 我认为重启是三重错误,因为您没有任何异常处理程序。您的模拟器应该能够向您展示实际的故障所在。你可以试试 bochs 而不是 qemu;它通常具有更好的开发功能(包括内置调试器)。
  • for 循环出于某种原因将 dir 设置为 0
  • 0x00105000 地址是什么?为什么不malloc

标签: c nasm paging gdt


【解决方案1】:

这个问题已经用这个结构解决了:

struct entry {
    unsigned int flags : 9;
    unsigned int available : 3;
    unsigned int addr : 20;
};

【讨论】:

    猜你喜欢
    • 2016-11-19
    • 2019-12-13
    • 1970-01-01
    • 2020-05-31
    • 2021-02-28
    • 1970-01-01
    • 2017-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多