Working on Paging API

This commit is contained in:
Adrien Bourmault 2020-01-10 23:56:07 +01:00
parent 4a652d7084
commit ee73150891
1 changed files with 41 additions and 12 deletions

View File

@ -14,6 +14,8 @@
pml4_t MmPageMapLevel4[512] __attribute__((__aligned__(KPAGESIZE))); pml4_t MmPageMapLevel4[512] __attribute__((__aligned__(KPAGESIZE)));
ulong *MmPhysicalPageTable; ulong *MmPhysicalPageTable;
extern MemoryMap_t memoryMap;
extern ulong _text; extern ulong _text;
extern ulong _text_end; extern ulong _text_end;
extern ulong _rodata; extern ulong _rodata;
@ -23,7 +25,7 @@ extern ulong _data_end;
ulong MmStackGuards[2] = { 0 }; ulong MmStackGuards[2] = { 0 };
ulong MmVirtLastAddress = 0; ulong MmVirtLastAddress = 0;
ulong MmPhysLastAddress = 0; ulong MmPhysLastKernelAddress = 0;
enum enum
{ {
@ -45,7 +47,6 @@ enum
// //
void MmInitPaging(void) void MmInitPaging(void)
{ {
extern MemoryMap_t memoryMap;
pdpe_t *MmPDP = NULL; pdpe_t *MmPDP = NULL;
pde_t *MmPD = NULL; pde_t *MmPD = NULL;
pte_t *MmPT = NULL; pte_t *MmPT = NULL;
@ -58,8 +59,8 @@ void MmInitPaging(void)
ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize; ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize;
// Difference between the end of kernel and the begin of userspace // Difference between the end of kernel and the begin of userspace
MmPhysLastAddress = (ulong)(_heap_start + _heap_max); MmPhysLastKernelAddress = (ulong)(_heap_start + _heap_max);
ulong diffKernUsr = (ulong)USERSPACE - MmPhysLastAddress - KPAGESIZE; ulong diffKernUsr = (ulong)USERSPACE - MmPhysLastKernelAddress - KPAGESIZE;
// Maximum VIRTUAL address in memory // Maximum VIRTUAL address in memory
MmVirtLastAddress = phRamSize + diffKernUsr; MmVirtLastAddress = phRamSize + diffKernUsr;
@ -160,11 +161,11 @@ void MmInitPaging(void)
//DebugLog("\tSection .rodata at %p\n", curAddrPT); //DebugLog("\tSection .rodata at %p\n", curAddrPT);
} }
// While we're inside the kernel pages // While we're inside the kernel pages
else if ((ulong)curAddrPT <= MmPhysLastAddress) { else if ((ulong)curAddrPT <= MmPhysLastKernelAddress) {
MmPT[index] = (ulong)curAddrPT | PRESENT | READWRITE; MmPT[index] = (ulong)curAddrPT | PRESENT | READWRITE;
MmPhysicalPageTable[xedni] = (ulong)curAddrPT; MmPhysicalPageTable[xedni] = (ulong)curAddrPT;
if ((ulong)curAddrPT == MmPhysLastAddress) { if ((ulong)curAddrPT == MmPhysLastKernelAddress) {
//DebugLog("\tLast page of kernel at %p\n", curAddrPT); //DebugLog("\tLast page of kernel at %p\n", curAddrPT);
} }
} }
@ -284,23 +285,51 @@ void MmMapPage(void* virtualAddr, void* physicalAddr, ulong flags)
// //
void MmUnmapPage(void* virtualAddr) void MmUnmapPage(void* virtualAddr)
{ {
MmUnsetPage(virtualAddr, PRESENT); // Removing the present flag pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr);
*page &= (~PRESENT);
KeFlushTlbSingle(*page);
} }
// //
// Find physical unallocated pages // Find physical unallocated pages
// //
void *MmGetPhyPageBlock(size_t size, bool usermode) { void *MmGetPhyPageBlock(size_t size, bool usermode) {
void *startPage = 0; void *startPhyPage = 0;
void *endPhyPage = 0;
size_t curSize = 0;
// Maximum PHYSICAL address in memory
ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize;
ulong curVirtAddr = 0;
if (!usermode) { if (!usermode) {
startPage = MmTransPhyToVirtAddr(0); startPhyPage = MmTransVirtToPhyAddr((void*)KPAGESIZE + 1);
endPhyPage = (void*)MmPhysLastKernelAddress;
} else { } else {
startPage = MmTransVirtToPhyAddr((void*)USERSPACE); startPhyPage = MmTransVirtToPhyAddr((void*)USERSPACE);
endPhyPage = (void*)(phRamSize & ~(KPAGESIZE - 1));
} }
DebugLog("Userspace at %p\n", (void*)USERSPACE); DebugLog("Start phy at %p\n", startPhyPage);
DebugLog("Userspace physical at %p\n", MmTransVirtToPhyAddr((void*)USERSPACE)); DebugLog("End phy at %p\n", endPhyPage);
for (ulong curPhyAddr = (ulong)startPhyPage;
curPhyAddr <= (ulong)endPhyPage;
curPhyAddr += KPAGESIZE) {
curVirtAddr = (ulong)MmTransPhyToVirtAddr((void*)curPhyAddr);
if (curVirtAddr == 0) {
DebugLog("CurrentAddr %p\n", curVirtAddr);
DebugLog("\t Free !\n");
curSize += KPAGESIZE;
}
if (curSize >= size)
break;
}
return NULL; return NULL;
} }