paging problem
Posted: Sun Aug 17, 2014 12:24 pm
Hi guys, I am currently trying to enable paging for my kernel but I am facing a strange problem, if I use the code in the wiki for paging it works just fine but this code is really simple so I tried to enable paging using the code from jamesMolly tutorial but when I enable paging using the code from the tutorial my OS crashes and restarts in qemu I checked the value laoded to cr3 register many times and it is right, this in my case is 0x10e000 contains a pointer to the first page table at address 0x111000 and the pages are set up right I verified that using gdb debugger, This is my code:
Please help I really have no idea why this code doesn't work and the code in the wiki works despite that it forms the same structures in memory.
Code: Select all
kernel_directory = (page_directory_t *)kmalloc(sizeof(page_directory_t),1);
memset(kernel_directory,0,sizeof(page_directory_t));
uint32 i = 0;
while(i<placement_address){
alloc_frame(get_page(i,1,kernel_directory),0,0);
i+= 0x1000;
}
asm volatile("mov %0,%%cr3"::"b"(kernel_directory));
uint32 cr0;
asm volatile("mov %%cr0, %0": "=b"(cr0));
cr0 |= 0x80000000; // Enable paging!
asm volatile("mov %0, %%cr0":: "b"(cr0));
void alloc_frame(page_t *page,uint8 is_kernel,uint8 is_writable){
if(page->frame != 0)
return;
uint32 addr = first_frame();
set_frame(addr);
page->present = 1;
page->rw = (is_writable)?1:0;
page->user = (is_kernel)?0:1;
page->frame = addr/0x1000;
}
page_t *get_page(uint32 address, int make, page_directory_t *dir)
{
// Turn the address into an index.
address /= 0x1000;
// Find the page table containing this address.
uint32 table_idx = address / 1024;
if (dir->tables[table_idx]) // If this table is already assigned
{
return &dir->tablesAddr[table_idx]->pages[address%1024];
}
else if(make)
{
uint32 tmp;
dir->tablesAddr[table_idx] = (page_table_t *)kmalloc_ap(sizeof(page_table_t), &tmp);
memset(&dir->tablesAddr[table_idx]->pages[address%1024],0,sizeof(page_table_t));
dir->tables[table_idx] = tmp| 0x7; // PRESENT, RW, US.
return &dir->tablesAddr[table_idx]->pages[address%1024];
}
else
{
return 0;
}
}
typedef struct page{
uint32 present :1;
uint32 rw :1;
uint32 user :1;
uint32 accessed :1;
uint32 dirty :1;
uint32 unused :1;
uint32 frame :20;
}page_t;
typedef struct page_table{
page_t pages[1024];
}page_table_t;
typedef struct page_directory{
uint32 tables[1024];
page_table_t *tablesAddr[1024];
}page_directory_t;