How to set up x86 paging? Getting triple error errors

I have a toy core that I work with under x86 on bochs. When I turn on paging, bochs is reset with a triple error error. Each and every memory access seems to be causing an error. So, I assume that I had an error with swap settings, and the problem is not in my interrupt handler. Here is the code.

paging.c

#include "paging.h" #include "lib.h" #include "screen.h" #include "descriptor_tables.h" typedef struct page_dir_entry_s{ bool present:1; bool writeable:1; bool user_access:1; bool write_through:1; bool cache_disabled:1; bool accessed:1; bool unused0:1; bool use_mb:1;//makes pages 4MB not 4KB bool unused1:4; u32 frame:20; } page_dir_entry_t; typedef struct page_table_entry_s{ bool present:1; bool writeable:1; bool user_access:1; bool write_through:1; bool cache_disabled:1; bool accessed:1; bool dirty:1; bool unused0:1; bool global:1; bool unused1:3; u32 phys_page_addr:20; } page_table_entry_t; extern u32 end;//as declared in the linker script static u32 next_addr=0; static page_dir_entry_t* page_dir=NULL; static page_table_entry_t* page_table=NULL; extern void enable_paging(u32); void InitPaging(){ next_addr=end; while((next_addr%4096)!=0) ++next_addr; page_dir=(void*)next_addr; next_addr+=4*1024; memset(page_dir,0,4*1024); page_table=(void*)next_addr; next_addr+=4; u32 addr=0; u32 i=0; *(((u32*)page_table)+i)=0;//zero it out while(addr<next_addr){ page_table[i].present=true; page_table[i].writeable=true; page_table[i].phys_page_addr=addr; ++i; *(((u32*)page_table)+i)=0;//zero it out addr+=(1024*4);//4KB next_addr+=4; } page_dir[0].writeable=true; page_dir[0].present=true; page_dir[0].frame=(u32)page_table; enable_paging((u32)page_dir); } 

paging_asm.s

 [global enable_paging] enable_paging: mov eax,[esp+4] mov cr3,eax mov eax,cr0 or eax,0x80000000 mov cr0,eax ret 
+4
source share
1 answer

The "frame" and "phys_page_addr" fields are bits 32 through 12 (in this swap mode) of the physical address.

Paging does nothing with an offset (0 - 4K).

At least you need:

 page_table[i].phys_page_addr=addr >> 12; 

and

 page_dir[0].frame=((u32)page_table) >> 12; 

Since both "addr" and "page_table" are aligned at 4096, this simply removes the extra zeros.

+1
source

Source: https://habr.com/ru/post/1368869/


All Articles