/* * memory-vi.c * * Created on: Aug 23, 2011 * Author: Tiberiu */ #include #include /******************************* * Data * *******************************/ PageDirectory* CurrentDirectory; PageDirectory* KernelDirectory; /******************************* * Useful routines * *******************************/ void PagingInitialize(uint32 kernel_used) { Log("Mem", "Virtual memory manager initialization started. End of kernel = 0x%x\n", kernel_used); PageDirectory* kernelPd = (PageDirectory*) kmalloc_a(sizeof(PageDirectory)); memset(kernelPd, 0, sizeof(PageDirectory)); CurrentDirectory = kernelPd; KernelDirectory = kernelPd; uint32 i; for (i = 0; i < kernel_used; i+=0x1000) MemPhAllocFrame(PagingGetPage(i, 1, kernelPd), 0, 0); Log("Mem", "Identity mapped first 0x%x bytes.\n", kernel_used); for (i = KERNEL_HEAP_START; i < KERNEL_HEAP_END; i+=0x1000) MemPhAllocFrame(PagingGetPage(i, 1, kernelPd), 1, 1); Log("Mem", "Mapped kernel space.\n"); PagingSwitchPageDirectory (kernelPd); } void PagingSwitchPageDirectory (PageDirectory* dir) { CurrentDirectory = dir; asm volatile ("mov %0, %%cr3":: "r"(&dir->TablesPhysical)); uint32 cr0; asm volatile ("mov %%cr0, %0": "=r"(cr0)); cr0 |= 0x80000000; asm volatile ("mov %0, %%cr0":: "r"(cr0)); Log("Mem", "Enabled paging.\n"); } Page* PagingGetPage(uint32 addr, uint8 make, PageDirectory* dir) { addr >>= 12; uint32 tableIndex = addr >> 10; if (dir->Tables[tableIndex]) return &dir->Tables[tableIndex]->Pages[addr&0x3ff]; else if (make) { uint32 temp; dir->Tables[tableIndex] = (PageTable*)kmalloc_ap(sizeof(PageTable), &temp); memset (dir->Tables[tableIndex], 0, 0x1000); dir->TablesPhysical[tableIndex] = temp | 0x7; return &dir->Tables[tableIndex]->Pages[addr&0x3ff]; } else return 0; }