【发布时间】: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。