diff --git a/include/mm/palloc.h b/include/mm/palloc.h index 98fbc3d..98dc5b2 100644 --- a/include/mm/palloc.h +++ b/include/mm/palloc.h @@ -42,8 +42,9 @@ typedef struct AllocatedPage_t{ //----------------------------------------------------------------------------// -ulong MmAllocPageFrame(void ***frameListPtr, size_t *pageNumber, size_t size, bool contiguous); -void MmFreePageFrame(ulong id); +ulong MmAllocPageFrameEx(void ***frameListPtr, size_t *pageNumber, size_t size, bool contiguous); +ulong MmAllocPageFrame(size_t size, bool contiguous); +void MmFreePageFrame(ulong id); error_t MmTestBusyPage(void); diff --git a/kaleid/kernel/mm/paging.c b/kaleid/kernel/mm/paging.c index fdbf8b8..108911d 100644 --- a/kaleid/kernel/mm/paging.c +++ b/kaleid/kernel/mm/paging.c @@ -60,7 +60,7 @@ void MmInitPaging(void) pdpe_t *MmPDP = NULL; pde_t *MmPD = NULL; pte_t *MmPT = NULL; - ulong index, xedni; + register ulong index, xedni; ulong firstDirectoryAddr = 0; ulong lastDirectoryAddr = 0; ulong phDirSize = 0; @@ -74,19 +74,18 @@ void MmInitPaging(void) MmPhysLastKernAddress = (ulong)(_heap_start + _heap_max); ulong diffKernUsr = (ulong)USERSPACE - MmPhysLastKernAddress - KPAGESIZE; + // Size of physical table + phDirSize = (((phRamSize + KPAGESIZE) / KPAGESIZE)*sizeof(ulong)); + // Maximum VIRTUAL address in memory MmVirtLastAddress = phRamSize + diffKernUsr; - //DebugLog("\tPaging gap : %u MB (%p)\n\tLast virtual address %p\n", diffKernUsr / MB, diffKernUsr, MmVirtLastAddress); + // Alloc structures + memzero((void *)&MmPageMapLevel4[0], 512*sizeof(ulong)); + KalAllocMemoryEx(&MmPhysicalPageTable, phDirSize, M_ZEROED, KPAGESIZE); - memzero((void *)&MmPageMapLevel4[0], sizeof(MmPageMapLevel4)); - phDirSize = ((phRamSize / KPAGESIZE)*sizeof(ulong) + KPAGESIZE) & ( ~((KPAGESIZE - 1) | NX)); - - MmPhysicalPageTable = (ulong*)malloc(phDirSize); - //DebugLog("\t\tRam %u MB, pagesize %u KB, size %u MB\n", phRamSize / MB, KPAGESIZE / KB, phDirSize / MB); - - for (ulong curAddrPML4 = 0; - curAddrPML4 < MmVirtLastAddress; + for (register ulong curAddrPML4 = 0; + curAddrPML4 < phRamSize; curAddrPML4 += ((ulong)KPAGESIZE * 0x8000000)) { // Create an entry in PML4 each 512GB // 0x8000000 = 512 ^ 3 @@ -102,9 +101,9 @@ void MmInitPaging(void) //DebugLog("\t\t\t\tPDP %d : %p\n", index, MmPDP); MmPageMapLevel4[index] = (pdpe_t *)((ulong)MmPDP | PRESENT | READWRITE); - for (ulong curAddrPDP = curAddrPML4; + for (register ulong curAddrPDP = curAddrPML4; curAddrPDP < (curAddrPML4 + ((ulong)KPAGESIZE * 0x8000000)) && - curAddrPDP < MmVirtLastAddress; + curAddrPDP < phRamSize; curAddrPDP += ((ulong)KPAGESIZE * 0x40000)) { // Create an intry in PDP each 1GB // 0x40000 = 512 ^ 2 @@ -116,9 +115,9 @@ void MmInitPaging(void) //DebugLog("\t\t\t\tPD %d : %p\n", index, MmPD); MmPDP[index] = (pde_t *)((ulong)MmPD | PRESENT | READWRITE); - for (ulong curAddrPD = curAddrPDP; + for (register ulong curAddrPD = curAddrPDP; curAddrPD < (curAddrPDP + ((ulong)KPAGESIZE * 0x40000)) && - curAddrPD < MmVirtLastAddress; + curAddrPD < phRamSize; curAddrPD += ((ulong)KPAGESIZE * 0x200)) { // Create an intry in PD each 2MB // 0x200 = 512 @@ -130,16 +129,17 @@ void MmInitPaging(void) //DebugLog("\t\t\t\tPT %d : %p\n", index, MmPT); MmPD[index] = (pte_t *)((ulong)MmPT | PRESENT | READWRITE); - for (ulong curAddrPT = curAddrPD; + for (register ulong curAddrPT = curAddrPD; curAddrPT < (curAddrPD + ((ulong)KPAGESIZE * 0x200)) && - curAddrPT < MmVirtLastAddress; + curAddrPT < phRamSize; curAddrPT += (ulong)KPAGESIZE) { // Create an entry in PT each page of 4KB index = (curAddrPT / ((ulong)KPAGESIZE)) % 512; xedni = (curAddrPT / ((ulong)KPAGESIZE)); - //DebugLog("\t\t\t\tPage %d : %p\n", index, curAddrPT); + if (curAddrPT == 0x973db000) + DebugLog("\t\t\t\tPage %d : %p\n", index, curAddrPT); // STACK GUARD PAGE */ if ((ulong)curAddrPT == (ulong)BtLoaderInfo.stackEndAddr) { @@ -181,21 +181,13 @@ void MmInitPaging(void) //DebugLog("\tLast page of kernel at %p\n", curAddrPT); } } - /* // While we're inside the userspace pages */ - /* else if ((ulong)curAddrPT >= USERSPACE) { */ - /* MmPT[index] = ((ulong)curAddrPT - diffKernUsr) | PRESENT; // Not present for instance */ - /* xedni = (((ulong)curAddrPT - diffKernUsr) / ((ulong)KPAGESIZE)); */ - /* //MmPhysicalPageTable[xedni] = (ulong)curAddrPT; */ - - /* if ((ulong)curAddrPT == USERSPACE) { */ - /* DebugLog("\tUserspace at %p:%p\n", curAddrPT, curAddrPT - diffKernUsr); */ - /* } */ - /* } */ else { MmPT[index] = 0; + MmPhysicalPageTable[xedni] = 0; } KeFlushTlbSingle(curAddrPT); + asm (""); } } } @@ -294,6 +286,9 @@ void MmMapPage(void* virtualAddr, void* physicalAddr, ulong flags) ] = (ulong)virtualAddr; KeFlushTlbSingle(*page); + + if (virtualAddr > MmVirtLastAddress) + MmVirtLastAddress = virtualAddr; } // diff --git a/kaleid/kernel/mm/palloc.c b/kaleid/kernel/mm/palloc.c index f021ddc..1e3bafe 100644 --- a/kaleid/kernel/mm/palloc.c +++ b/kaleid/kernel/mm/palloc.c @@ -29,6 +29,7 @@ #include #include #include +#include //--------- @@ -42,6 +43,9 @@ static AllocatedPage_t busyPagesList = { (void*)0, 0, (AllocatedPage_t*)0 }; extern MemoryMap_t memoryMap; extern ulong MmPhysLastKernAddress; +static ulong NSuccessfulAlloc = 0; +static ulong NSuccessfulFree = 0; + //--------- static bool isPageBusy(void *phyPageAddr) @@ -120,7 +124,7 @@ static void removePageFromBusyList(void *phyPageAddr) // // Returns an id to identify a page frame allocated (kernel) // -ulong MmAllocPageFrame(void ***frameListPtr, size_t *pageNumber, size_t size, bool contiguous) +ulong MmAllocPageFrameEx(void ***frameListPtr, size_t *pageNumber, size_t size, bool contiguous) { static ulong id = 0; *pageNumber = (((ulong)size - 1) / KPAGESIZE) + 1; @@ -135,7 +139,7 @@ ulong MmAllocPageFrame(void ***frameListPtr, size_t *pageNumber, size_t size, bo // Maximum PHYSICAL address in memory ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize; - DebugLog("Allocating %d pages...\n", *pageNumber); + //DebugLog("Allocating %d pages...\n", *pageNumber); for (void *curPage = (void*)(MmPhysLastKernAddress + KPAGESIZE); curPage < (void*)phRamSize; curPage += KPAGESIZE) { if (!isPageBusy(curPage)) { @@ -153,28 +157,47 @@ ulong MmAllocPageFrame(void ***frameListPtr, size_t *pageNumber, size_t size, bo curNumber = 0; } + if (curNumber != *pageNumber) { + KeStartPanic("MmAllocPageFrameEx() : No more free pages to allocate"); + } + for (size_t i = 0; i < *pageNumber; i++) { addPageToBusyList((*frameListPtr)[i], id); //DebugLog("Allocating page : %p\n", *frameListPtr[i]); } + NSuccessfulAlloc++; + return id; } +ulong MmAllocPageFrame(size_t size, bool contiguous) +{ + void **ptr = NULL; + ulong d = 0; + return MmAllocPageFrameEx(&ptr, &d, size, contiguous); +} + + // // Frees a page frame by its id // void MmFreePageFrame(ulong id) { AllocatedPage_t *busyPage = &busyPagesList; + bool success = false; while(busyPage->next) { busyPage = busyPage->next; if (id == busyPage->id) { removePageFromBusyList(busyPage->phyAddress); + success = true; } } + + if (success) + NSuccessfulFree++; } // @@ -196,7 +219,7 @@ error_t MmMapPageFrame(ulong id, void *virtAddr, ulong flags) if (id == busyPage->id) { MmMapPage((void*)((ulong)virtAddr + offset), busyPage->phyAddress, flags); - DebugLog("Map %p at %p\n", busyPage->phyAddress, virtAddr + offset); + //DebugLog("Map %p at %p\n", busyPage->phyAddress, virtAddr + offset); offset += KPAGESIZE; } } @@ -216,7 +239,7 @@ error_t MmUnmapPageFrame(ulong id) //DebugLog("Physical : %p is %p\n", busyPage->phyAddress, actualPhys); if (actualPhys && id == busyPage->id) { - DebugLog("Unmap %p from %p\n", busyPage->phyAddress, MmTransPhyToVirtAddr(busyPage->phyAddress)); + //DebugLog("Unmap %p from %p\n", busyPage->phyAddress, MmTransPhyToVirtAddr(busyPage->phyAddress)); MmUnmapPage(MmTransPhyToVirtAddr(busyPage->phyAddress)); } } @@ -226,79 +249,24 @@ error_t MmUnmapPageFrame(ulong id) error_t MmTestBusyPage(void) { - DebugLog("\nBusy pages\n"); - printBusyPages(); + ulong tab[2000] = {0}; + int j = 0; + for (int i = 0; i < 2000; i++) { + if (rand() %2) { + if (rand() %2) { + tab[j++] = MmAllocPageFrame(rand()%65536, NORMAL); + } else { + tab[j++] = MmAllocPageFrame(rand()%65536, CONTIGUOUS); + } + } else { + MmFreePageFrame(tab[rand() % (j+1)]); + } + } - void **ptr = NULL; - size_t n = 0; - ulong id1 = MmAllocPageFrame(&ptr, &n, 6677, NORMAL); - DebugLog("Alloc 6677 bytes : %p, %d pages, first at %p\n", ptr, n, ptr[0]); + //printBusyPages(); - void **ptr2 = NULL; - size_t n2 = 0; - ulong id2 = MmAllocPageFrame(&ptr2, &n2, 9045, NORMAL); - DebugLog("Alloc 9045 bytes: %p, %d pages, first at %p\n", ptr2, n2, ptr2[0]); - - void **ptr3 = NULL; - size_t n3 = 0; - ulong id3 = MmAllocPageFrame(&ptr3, &n3, 1200, NORMAL); - DebugLog("Alloc 1200 bytes: %p, %d pages, first at %p\n", ptr3, n3, ptr3[0]); - - void **ptr4 = NULL; - size_t n4 = 0; - ulong id4 = MmAllocPageFrame(&ptr4, &n4, 4096, NORMAL); - DebugLog("Alloc 4096 bytes: %p, %d pages, first at %p\n", ptr4, n4, ptr4[0]); - void **ptr5 = NULL; - size_t n5 = 0; - ulong id5 = MmAllocPageFrame(&ptr5, &n5, 4097, NORMAL); - DebugLog("Alloc 4097 bytes: %p, %d pages, first at %p\n", ptr5, n5, ptr5[0]); - - printBusyPages(); - - MmFreePageFrame(id1); - MmFreePageFrame(id3); - DebugLog("Free 6677 and 1200 bytes\n"); - - void **ptr6 = NULL; - size_t n6 = 0; - ulong id6 = MmAllocPageFrame(&ptr6, &n6, 10000, NORMAL); - DebugLog("Alloc 10000 bytes: %p, %d pages, first at %p\n", ptr6, n6, ptr6[0]); - - printBusyPages(); - - MmFreePageFrame(id6); - DebugLog("Free 10000 bytes\n"); - - printBusyPages(); - - void **ptr7 = NULL; - size_t n7 = 0; - ulong id7 = MmAllocPageFrame(&ptr7, &n7, 10000, CONTIGUOUS); - DebugLog("Alloc 10000 bytes contiguous: %p, %d pages, first at %p\n", ptr7, n7, ptr7[0]); - - printBusyPages(); - - MmFreePageFrame(id1); - MmFreePageFrame(id2); - MmFreePageFrame(id3); - MmFreePageFrame(id4); - MmFreePageFrame(id5); - MmFreePageFrame(id6); - MmFreePageFrame(id7); - DebugLog("Free all bytes\n"); - - printBusyPages(); - - id1 = MmAllocPageFrame(&ptr, &n, 1*MB, NORMAL); - error_t err = MmMapPageFrame(id1, (void*)USERSPACE, PRESENT | USERMODE | READWRITE); - - if (err == EOK) - DebugLog("Map status : OK\n"); - if (err == EADDRINUSE) - DebugLog("Map status : NOK\n"); - - MmUnmapPageFrame(id1); + DebugLog("Alloc : %d; Free : %d\n", NSuccessfulAlloc, NSuccessfulFree); return EOK; }