我正在尝试在Qemu上启用x86架构上的分页 但是这段代码会导致三重错误。
此代码段以保护模式执行 代码:https://github.com/mridulv/simpleOperatingSystem
这是内核条目文件
[bits 32]
[extern main]
[extern main2]
[extern page_table]
call main
lea ECX, [page_table - 0xC0000000]
mov CR3, ECX
mov ECX, CR0
or ECX, 0x80000000
mov CR0, ECX
;lea ECX, [StartInHigherHalf]
;jmp ECX
;StartInHigherHalf:
; call main2
jmp $
这是创建页面目录的内核文件。
unsigned int page_table[1024] __attribute__((aligned(4096)));;
void set_page_tables() {
unsigned int pages_entry[1024 * 1024] __attribute__((aligned(4096)));
unsigned int KERNEL_VIRTUAL_OFFSET = 0xC0000000;
unsigned int KERNEL_FIRST_VIRTUAL_ADDRESS = 0xC0000000 >> 12;
int numPageTables = 4;
int numPagesInPageTable = 1024;
int numPageTableEntriesInPageDirectory = 1024;
int totalPages = numPageTables * numPagesInPageTable;
unsigned int index = 0;
unsigned int *pages_ptr = (unsigned int *)(pages_entry - KERNEL_VIRTUAL_OFFSET);
unsigned int *page_table_ptr = (unsigned int *)(pages_entry - KERNEL_VIRTUAL_OFFSET);
unsigned int positionAndFlags = 7;
while (index < totalPages) {
pages_ptr[index] = positionAndFlags;
index = index + 1;
positionAndFlags += 4096;
}
positionAndFlags = 7;
index = KERNEL_FIRST_VIRTUAL_ADDRESS;
unsigned int totalPagesLeft = KERNEL_FIRST_VIRTUAL_ADDRESS + totalPages;
while (index < totalPagesLeft) {
pages_ptr[index] = positionAndFlags;
index = index + 1;
positionAndFlags += 4096;
}
positionAndFlags = (unsigned int)&pages_ptr[0];
positionAndFlags = positionAndFlags | 7;
index = 0;
while (index < numPageTableEntriesInPageDirectory) {
page_table_ptr[index] = positionAndFlags;
index = index + 1;
positionAndFlags += 4096;
}
}
void main() {
char* video_memory = (char*) 0xb8000;
*video_memory = 'X';
set_page_tables();
}
void main2() {
char* video_memory = (char*) 0xb8004;
*video_memory = 'Y';
// __asm__
// (
// "leal (page_table, ), %ecx\n\t" // 0xC0000000 = KERNEL_VIRTUAL_BASE
// "movl %cr3, %ecx"
// );
}
Linker.ld
SECTIONS {
. = 0xC0100000;
.text : AT(ADDR(.text) - 0xC0000000) {
*(.text);
}
. = ALIGN(0x1000);
.bss : AT(ADDR(.bss) - 0xC0000000) {
*(.text);
}
. = ALIGN(0x1000);
.data : AT(ADDR(.data) - 0xC0000000) {
*(.text);
}
}
答案 0 :(得分:0)
我建议你在代码顶部添加章节声明,以便明确 -
section .text
并且代码中的错误是在执行
之前的错误call main
你的代码没有(根本没有)通过填写ESP寄存器来设置堆栈。
为此,您的代码应该像
像这样创建一个常量'STACK_SIZE' -
STACK_SIZE equ <valueOfSizeOfStack>
为堆栈创建空间
section .bss
kernelStack: RESB <valueOfSizeOfStack>
在“valueOfSizeOfStack”字段中,您可以为堆栈添加4096(4-KB)或其任意倍数(不是很大,它将以二进制大小计算)。