gpt4 book ai didi

c - 启用分页时 QEMU 三重故障

转载 作者:行者123 更新时间:2023-12-03 14:55:36 25 4
gpt4 key购买 nike

我正在实现自己的内核,但遇到了困难。我正在尝试将我的内核加载到高半虚拟地址中。我通过标识映射低 1M RAM 解决了标识地址问题。我创建了一个 init 部分,该部分重新定位到内核的物理地址,以便处理分页初始化。我的内核的虚拟偏移量是 0xc0000000。这是我的链接描述文件:

OUTPUT_FORMAT(elf32-i386)
ENTRY(start)

KERNEL_VIRTUAL_OFFSET = 0xC0000000;

SECTIONS
{
. = 1M;
kernel_start = .;

start_init = .;
.init ALIGN(4K) :
{ *(.multiboot);
*(.init);
*(.tables);
}
end_init = .;

. += KERNEL_VIRTUAL_OFFSET;

kernel_high_half_start = .;
.text ALIGN(4K) : AT(ADDR(.text) - KERNEL_VIRTUAL_OFFSET)
{*(.text) }
.data ALIGN(4K) : AT(ADDR(.data) - KERNEL_VIRTUAL_OFFSET)
{ *(.data) }
.rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_VIRTUAL_OFFSET)
{ *(.rodata) }
.bss ALIGN(4K) : AT(ADDR(.bss) - KERNEL_VIRTUAL_OFFSET)
{ *(.bss) }
kernel_high_half_end = .;

kernel_end = . - KERNEL_VIRTUAL_OFFSET;
}

这是我的切入点。我使用 GRUB 作为我的引导装载程序。由于 init 部分,它成功启动并跳转到我的入口点:

    its 32
section .multiboot
;grub bootloader header
align 4
dd 0x1BADB002 ;magic
dd 0x00 ;flags
dd - (0x1BADB002 + 0x00) ;checksum. m+f+c should be zero

; Declarations
global start
extern kmain
extern paging_init
extern kernel_page_directory

section .init

enable_paging:
mov eax, kernel_page_directory
mov cr3, eax
mov eax, cr0
or eax, 0x80000000
mov cr0, eax ; ***** PAGING ENABLED HERE *****
ret

start:
cli ;block interrupts
mov esp, init_stack
call paging_init
call enable_paging

;mov eax, 0xb8000
;mov byte[eax], 'h'
;mov byte[eax+1], 0x7

; Now high half kernel is mapped to the page directory
mov esp, stack_space ;set stack pointer
push ebx ; grub boot info
call kmain

loop:
hlt ;halt the CPU
jmp loop

resb 4096; 4KB small stack for my init section.
init_stack:

section .bss
resb 8192 ;8KB for stack
stack_space:

这是我的代码,它填充了内核的页表和页目录。如您所见,整个代码都链接到 init 部分,以避免重定位问题:

page_table_t kernel_page_directory[PAGE_DIR_SIZE]
__attribute__((aligned(PAGE_SIZE))) __attribute__((section(".tables"))) = {0};

page_pointer_t kernel_page_tables[PAGE_TABLE_SIZE]
__attribute__((aligned(PAGE_SIZE))) __attribute__((section(".tables"))) = {0};

page_pointer_t identity_page_table[PAGE_TABLE_SIZE]
__attribute__((aligned(PAGE_SIZE))) __attribute__((section(".tables"))) = {0};

/* Identity map the low 1M
* In early boot stage.
*/
static void __attribute__((section(".init"))) map_identity()
{
//map bios
unsigned int current_page = 0;
for(int i = 0; i < BIOS_PAGE_TABLE_ENTRIES; i++, current_page += PAGE_SIZE)
{
identity_page_table[i] = (current_page) | 0x3;
}

//map init
current_page = INIT_START;
for(int i = INIT_START >> 12 & 0x3FF;
i < ((INIT_START >> 12 & 0x3FF) + (INIT_SIZE / PAGE_SIZE));
i++, current_page += PAGE_SIZE)
{
identity_page_table[i] = (current_page) | 0x3;
}

kernel_page_directory[0] = ((unsigned long)(identity_page_table)) | 0x3;
}

/* Map the kernel memory to its page directory,
* **in early boot stage.
* We don't need to map the init section, we don't need it anymore.
*/

__attribute__((section(".init"))) static void map_kernel_memory()
{
//Identity map the init section
//Start at 1MB i.e. its page aligned.
unsigned int start_index = 256;
unsigned long current_page = KERNEL_START;

for(int i = start_index;
i < start_index + (KERNEL_SIZE / PAGE_SIZE) + 1;
i++, current_page += PAGE_SIZE)
{
kernel_page_tables[i] = current_page | 0x3;
}

kernel_page_directory[KERNEL_DIRECTORY_ENTRY] = ((unsigned long)kernel_page_tables) | 0x3;
}

__attribute__((section(".init"))) void paging_init()
{
map_identity();

map_kernel_memory();
}

我试图指出确切的汇编指令,但这使我的内核无法正常工作,我认为这是因为当我启用分页时 mov cr0, eaxCR3 确实包含 kernel_page_directory 的地址或带有 0x3。一旦启用分页,QEMU 就会停止响应并且系统会不断重启。正在冲洗屏幕,然后重复打印。任何想法为什么会这样?我该如何解决?

最佳答案

你的页面目录地址是页面对齐的吗?每页(帧)的大小为 4 KB。我建议像这样为页面目录创建一个结构:

typedef struct page_directory{
page_table_t *tables[1024];
size_t tablesPhysical[1024]; // Physical address of page tables
size_t physicalAddr; // Physical address of `tablesPhysical'
} page_directory_t;

因此,您的目录地址必须是 4 KB (0x1000) 的倍数。 James Molloy's Tutorial可能对你有帮助。

关于c - 启用分页时 QEMU 三重故障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38157968/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com