x86自定义OS启动时initialize_paging()触发崩溃问题排查
x86架构OS分页初始化崩溃问题
问题概述
从零开始用C语言和GAS汇编编写x86操作系统,当前可正常启动,完成GDT、IDT及中断处理器初始化,但按照James Molloy的实现方式初始化分页时,执行到switch_page_directory()函数会导致QEMU中的OS崩溃并反复重启。
相关代码
kernel_main函数
void kernel_main(void) { clear_screen(); // Initialise all the ISRs and segmentation gdt_init(); idt_init(); initialize_paging(); // 问题出在此函数内 nanos_printf("Hello, paging world!\n"); uint32_t *ptr = (uint32_t*)0xA0000000; uint32_t do_page_fault = *ptr; return 0; }
initialize_paging函数
void initialize_paging() { uint32_t mem_end_page = 0x1000000; nframes = mem_end_page / 0x1000; frames = (uint32_t*)kmalloc(INDEX_FROM_BIT(nframes)); memset(frames, 0, INDEX_FROM_BIT(nframes)); kernel_directory = (page_directory_t*)kmalloc_a(sizeof(page_directory_t)); current_directory = kernel_directory; int i = 0; while (i < placement_address) { alloc_frame( get_page(i, 1, kernel_directory), 0, 0); i += 0x1000; } register_interrupt_handler(14, page_fault); switch_page_directory(kernel_directory); // 问题触发点 }
switch_page_directory函数
void switch_page_directory(page_directory_t *dir) { if (dir == NULL) { // Handle null pointer case return; } current_directory = dir; asm volatile("mov %0, %%cr3":: "r"(&dir->tablesPhysical)); uint32_t cr0; asm volatile("mov %%cr0, %0": "=r"(cr0)); cr0 |= 0x80000000; // 设置分页位 asm volatile("mov %0, %%cr0":: "r"(cr0)); }
链接脚本
ENTRY(_start) SECTIONS { . = 1M; .text BLOCK(4K) : ALIGN(4K) { *(.multiboot) *(.text) } .rodata BLOCK(4K) : ALIGN(4K) { *(.rodata) } .data BLOCK(4K) : ALIGN(4K) { *(.data) } .bss BLOCK(4K) : ALIGN(4K) { *(COMMON) *(.bss) } /DISCARD/ : { *(.comment) *(.eh_frame) *(.note*) *(.iplt) *(.igot) } end = .; _end = .; __end = .; }
已尝试的解决措施
曾修改链接脚本为James Molloy的版本,问题未解决,已恢复原脚本。
内容的提问来源于stack exchange,提问作者user21223662
相关产品推荐
相关产品推荐

