trouble rolling identity paging...[resolved]
Posted: Fri Apr 10, 2009 2:02 pm
Ok, I'm using both JamesM tutorial and a tut from osdever... and I just can not seem to figure out where the error is in my code..
In my code, basically it assigns all page directory entries to 0. Then it starts to identity map. With the identity map, if the page directory entry is zero, then it allocates a physical page, assigns it to it, and then ORs that with 7(user/RW/present) and then assigns all of the page entires in the table to zero. Then, it will map the src_page to the trg_page.. pretty simply..
Whenever I enable paging in CR0 though, it triple-faults. does anyone see any immediate error with my code?
Also, the AllocPage function does what it says.. it returns a page address. So it is automatically page aligned.
Code: Select all
typedef struct page
{
uint present : 1; // Page present in memory
uint rw : 1; // Read-only if clear, readwrite if set
uint user : 1; // Supervisor level only if clear
uint accessed : 1; // Has the page been accessed since last refresh?
uint dirty : 1; // Has the page been written to since last refresh?
uint unused : 7; // Amalgamation of unused and reserved bits
uint frame : 20; // Frame address (shifted right 12 bits)
} __packed page_t;
typedef struct{
page_t p[1024];
}__packed page_table_t;
typedef struct{
page_table_t *tabs[1024];
}__packed page_dir_t;
page_dir_t *page_dir;
page_table_t *kpage_tables;
void init_identity_paging(){
uint32_t frame;int i;
page_dir=k_AllocPage(1,OWNER_PAGEMAN);
memset(page_dir,0,sizeof(page_dir_t));
for(i=0;i<1024;i++){
page_dir->tabs[i]=0 ;
}
for(frame=0;frame<=(MEM_SIZE/0x1000);frame++){
mmap_to(frame,frame,1,1,1);
}
stopints();
write_cr3(page_dir);
write_cr0(read_cr0()|0x80000000); //set paging bit.
kput_hex(*(uint32_t*) &page_dir->tabs[0]);
kputs("\n");
startints();
}
void mmap_to(uint32_t src_page,uint32_t trg_page,int present,int rw,int user){
int i=1;
if(((uint32_t)page_dir->tabs[src_page/1024] & 0xFFFFF000)==0){
page_dir->tabs[src_page/1024]=(void*)
((uint32_t)k_AllocPage(1,OWNER_PAGEMAN) | 7);
for(i=0;i<1024;i++){
page_dir->tabs[src_page/1024]->p[i].present=0;
page_dir->tabs[src_page/1024]->p[i].rw=0;
page_dir->tabs[src_page/1024]->p[i].user=0;
page_dir->tabs[src_page/1024]->p[i].frame=0;
}
}
page_dir->tabs[src_page/1024]->p[src_page%1024].present=present;
page_dir->tabs[src_page/1024]->p[src_page%1024].rw=rw;
page_dir->tabs[src_page/1024]->p[src_page%1024].user=user;
page_dir->tabs[src_page/1024]->p[src_page%1024].frame=trg_page;
}
In my code, basically it assigns all page directory entries to 0. Then it starts to identity map. With the identity map, if the page directory entry is zero, then it allocates a physical page, assigns it to it, and then ORs that with 7(user/RW/present) and then assigns all of the page entires in the table to zero. Then, it will map the src_page to the trg_page.. pretty simply..
Whenever I enable paging in CR0 though, it triple-faults. does anyone see any immediate error with my code?
Also, the AllocPage function does what it says.. it returns a page address. So it is automatically page aligned.