#include "assert.H" #include "exceptions.H" #include "console.H" #include "paging_low.H" #include "page_table.H" PageTable * PageTable::current_page_table = NULL; unsigned int PageTable::paging_enabled = 0; ContFramePool * PageTable::kernel_mem_pool = NULL; ContFramePool * PageTable::process_mem_pool = NULL; unsigned long PageTable::shared_size = 0; void PageTable::init_paging(ContFramePool * _kernel_mem_pool, ContFramePool * _process_mem_pool, const unsigned long _shared_size) { kernel_mem_pool = _kernel_mem_pool; process_mem_pool = process_mem_pool; shared_size = _shared_size; Console::puts("\nInitialized Paging System\n"); } PageTable::PageTable() { unsigned long * temp_page_directory = (unsigned long *) ((kernel_mem_pool->get_frames(1)) << 12); // Getting frame address to assign to page directory. unsigned long * page_table = (unsigned long *) ((kernel_mem_pool->get_frames(1)) << 12); // Get another frame for the page table. unsigned long tempaddr = 0; // Temporary address iterator. // We need to map the first 4MB. // This first for loop was here in case I needed to set the first 2mb as not present. for(unsigned int i = 0; i < 512; i++) { page_table[i] = tempaddr | 3; // set bits 0 and 1 to present and read/write respectively tempaddr += 4096; // 4096 = 4kb } for(unsigned int i = 512; i < 1024; i++) { page_table[i] = tempaddr | 3; // set bits 0 and 1 to present and read/write respectively tempaddr += 4096; // 4096 = 4kb } // Fill first entry of page directory. temp_page_directory[0] = (unsigned long)page_table; temp_page_directory[0] = temp_page_directory[0] | 3; for(unsigned int j = 1; j < 1024; j++) { temp_page_directory[j] = 0 | 2; } page_directory = temp_page_directory; current_page_table = this; Console::puts("\nConstructed Page Table object\n"); } void PageTable::load() { write_cr3((unsigned long)page_directory); Console::puti((unsigned long)page_directory); current_page_table = this; Console::puts("\nLoaded page table\n"); } void PageTable::enable_paging() { write_cr3((unsigned long)current_page_table->page_directory); write_cr0(read_cr0() | 0x80000000); paging_enabled = read_cr0(); Console::puts("\nEnabled paging\n"); } void PageTable::handle_fault(REGS * _r) { // Initializing some variables to make things easier. unsigned long * temp_pd = (unsigned long *) (current_page_table->page_directory); unsigned long * temp_pt = (unsigned long *) (*temp_pd); unsigned long pt_index = (read_cr2() >> 12) & 0x3FFFFF; unsigned long pd_index = read_cr2() >> 22; // If there isn't a page table present. if(!(temp_pd[pd_index] & 1)) { Console::puts("\nPage Table not Present.\n"); unsigned long * new_pt = (unsigned long *) (kernel_mem_pool->get_frames(1) << 12); // Set new page table entries as present. // Start at beginning address for the page table // this should be pd_index << 22. unsigned long temp_addr = pd_index << 22; for(unsigned int i = 0; i < 1024; i++) { new_pt[i] = temp_addr | 3; temp_addr += 4096; } // Add page table to page directory. temp_pd[pd_index] = (unsigned long) new_pt; temp_pd[pd_index] = temp_pd[pd_index] | 3; } /* // Why is this commented out? // Unfortunately, for whatever reason, any time I try to call // process_mem_pool->get_frames() the entire program crashes. // I've tried evaluating lines immediately afterwards, adding // for(;;);, the program ignores this and continues to crash. // Since I have no idea why this is happening, I can only assume // I did something wrong in cont_frame_pool or that this is just // an issue I didn't address properly somewhere and didn't see // addressed in the instructions. Regardless, I left what I believe // would be the implementation of handle_fault in the case that I // needed to allocate a frame in process_mem_pool in order to // allocate a page for a process commented out so I could at least // show that I knew how it would be implemented. if(read_cr2() >> 22 > 0) { if(((unsigned long *)temp_pd[pd_index])[pt_index] & 1) { Console::puts("\nPage not present.\n"); unsigned long * new_page = (unsigned long *) (process_mem_pool->get_frames(1) << 12); // Set new page as page table entry. ((unsigned long *)temp_pd[pd_index])[pt_index] = (unsigned long) new_page | 3; } } */ Console::puts("\nhandled page fault\n"); }