From 7a7d458bc6997b3f4a2b635636c4c95bf75b11d1 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Wed, 15 Jan 2020 16:12:13 +0100 Subject: [PATCH] Page allocator fully functionnal #67 --- include/mm/paging.h | 13 ++++++ kaleid/kernel/mm/paging.c | 21 ++++----- kaleid/kernel/mm/palloc.c | 87 ++++++++++++++++++++++++++++++++----- kaleid/kernel/sh/testcmds.c | 13 ------ 4 files changed, 97 insertions(+), 37 deletions(-) diff --git a/include/mm/paging.h b/include/mm/paging.h index 6dca6e1..b0f5568 100644 --- a/include/mm/paging.h +++ b/include/mm/paging.h @@ -49,6 +49,19 @@ typedef pde_t* pdpe_t; // Page directory L4 pointer offset typedef pdpe_t* pml4_t; +enum +{ + PRESENT = 1 << 0, + READWRITE = 1 << 1, + USERMODE = 1 << 2, + WRITETHR = 1 << 3, + CACHEDIS = 1 << 4, + ACCESSED = 1 << 5, + DIRTY = 1 << 6, + HUGE = 1 << 7, + NX = 1UL << 63 +}; + //----------------------------------------------------------------------------// // diff --git a/kaleid/kernel/mm/paging.c b/kaleid/kernel/mm/paging.c index 7d13543..fdbf8b8 100644 --- a/kaleid/kernel/mm/paging.c +++ b/kaleid/kernel/mm/paging.c @@ -50,19 +50,6 @@ static ulong MmStackGuards[2] = { 0 }; ulong MmVirtLastAddress = 0; ulong MmPhysLastKernAddress = 0; -enum -{ - PRESENT = 1 << 0, - READWRITE = 1 << 1, - USERMODE = 1 << 2, - WRITETHR = 1 << 3, - CACHEDIS = 1 << 4, - ACCESSED = 1 << 5, - DIRTY = 1 << 6, - HUGE = 1 << 7, - NX = 1UL << 63 -}; - //----------- // @@ -302,6 +289,10 @@ void MmMapPage(void* virtualAddr, void* physicalAddr, ulong flags) *page = ((ulong)physicalAddr & ~((KPAGESIZE - 1) | NX)) | flags; + MmPhysicalPageTable[(ulong)physicalAddr + / ((ulong)KPAGESIZE) + ] = (ulong)virtualAddr; + KeFlushTlbSingle(*page); } @@ -312,6 +303,10 @@ void MmUnmapPage(void* virtualAddr) { pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr); + MmPhysicalPageTable[(ulong)(MmTransVirtToPhyAddr(virtualAddr)) + / ((ulong)KPAGESIZE) + ] = 0; + *page = 0; KeFlushTlbSingle(*page); diff --git a/kaleid/kernel/mm/palloc.c b/kaleid/kernel/mm/palloc.c index ff8ebcc..f021ddc 100644 --- a/kaleid/kernel/mm/palloc.c +++ b/kaleid/kernel/mm/palloc.c @@ -81,14 +81,22 @@ static void printBusyPages(void) static void addPageToBusyList(void *phyPageAddr, ulong id) { AllocatedPage_t *busyPage = &busyPagesList; + AllocatedPage_t *prevBusyPage = NULL; while(busyPage->next) { + prevBusyPage = busyPage; busyPage = busyPage->next; + + if (busyPage->phyAddress > phyPageAddr) { + busyPage = prevBusyPage; + break; + } } AllocatedPage_t *newBusyPage = (AllocatedPage_t*)malloc(sizeof(AllocatedPage_t)); newBusyPage->phyAddress = phyPageAddr; newBusyPage->id = id; + newBusyPage->next = busyPage->next; busyPage->next = newBusyPage; } @@ -129,7 +137,7 @@ ulong MmAllocPageFrame(void ***frameListPtr, size_t *pageNumber, size_t size, bo DebugLog("Allocating %d pages...\n", *pageNumber); - for (void *curPage = (void*)MmPhysLastKernAddress; curPage < (void*)phRamSize; curPage += KPAGESIZE) { + for (void *curPage = (void*)(MmPhysLastKernAddress + KPAGESIZE); curPage < (void*)phRamSize; curPage += KPAGESIZE) { if (!isPageBusy(curPage)) { (*frameListPtr)[curNumber] = curPage; inBlock = true; @@ -169,6 +177,53 @@ void MmFreePageFrame(ulong id) } } +// +// Maps an allocated page frame to the given address +// +error_t MmMapPageFrame(ulong id, void *virtAddr, ulong flags) +{ + AllocatedPage_t *busyPage = &busyPagesList; + ulong offset = 0; + + while(busyPage->next) { + busyPage = busyPage->next; + + //DebugLog("Physical : %p is %p\n", busyPage->phyAddress, MmTransPhyToVirtAddr(busyPage->phyAddress)); + + if (MmTransPhyToVirtAddr(busyPage->phyAddress)) { + return EADDRINUSE; + } + + if (id == busyPage->id) { + MmMapPage((void*)((ulong)virtAddr + offset), busyPage->phyAddress, flags); + DebugLog("Map %p at %p\n", busyPage->phyAddress, virtAddr + offset); + offset += KPAGESIZE; + } + } + + return EOK; +} + +error_t MmUnmapPageFrame(ulong id) +{ + AllocatedPage_t *busyPage = &busyPagesList; + void *actualPhys = 0; + + while(busyPage->next) { + busyPage = busyPage->next; + actualPhys = MmTransPhyToVirtAddr(busyPage->phyAddress); + + //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)); + MmUnmapPage(MmTransPhyToVirtAddr(busyPage->phyAddress)); + } + } + + return EOK; +} + error_t MmTestBusyPage(void) { DebugLog("\nBusy pages\n"); @@ -178,49 +233,49 @@ error_t MmTestBusyPage(void) void **ptr = NULL; size_t n = 0; ulong id1 = MmAllocPageFrame(&ptr, &n, 6677, NORMAL); - DebugLog("\nAlloc 6677 bytes : %p, %d pages, first at %p\n", ptr, n, ptr[0]); + DebugLog("Alloc 6677 bytes : %p, %d pages, first at %p\n", ptr, n, ptr[0]); void **ptr2 = NULL; size_t n2 = 0; ulong id2 = MmAllocPageFrame(&ptr2, &n2, 9045, NORMAL); - DebugLog("\nAlloc 9045 bytes: %p, %d pages, first at %p\n", ptr2, n2, ptr2[0]); + 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("\nAlloc 1200 bytes: %p, %d pages, first at %p\n", ptr3, n3, ptr3[0]); + 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("\nAlloc 4096 bytes: %p, %d pages, first at %p\n", ptr4, n4, ptr4[0]); + 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("\nAlloc 4097 bytes: %p, %d pages, first at %p\n", ptr5, n5, ptr5[0]); + DebugLog("Alloc 4097 bytes: %p, %d pages, first at %p\n", ptr5, n5, ptr5[0]); printBusyPages(); MmFreePageFrame(id1); MmFreePageFrame(id3); - DebugLog("\nFree 6677 and 1200 bytes\n"); + DebugLog("Free 6677 and 1200 bytes\n"); void **ptr6 = NULL; size_t n6 = 0; ulong id6 = MmAllocPageFrame(&ptr6, &n6, 10000, NORMAL); - DebugLog("\nAlloc 10000 bytes: %p, %d pages, first at %p\n", ptr6, n6, ptr6[0]); + DebugLog("Alloc 10000 bytes: %p, %d pages, first at %p\n", ptr6, n6, ptr6[0]); printBusyPages(); MmFreePageFrame(id6); - DebugLog("\nFree 10000 bytes\n"); + DebugLog("Free 10000 bytes\n"); printBusyPages(); void **ptr7 = NULL; size_t n7 = 0; ulong id7 = MmAllocPageFrame(&ptr7, &n7, 10000, CONTIGUOUS); - DebugLog("\nAlloc 10000 bytes contiguous: %p, %d pages, first at %p\n", ptr7, n7, ptr7[0]); + DebugLog("Alloc 10000 bytes contiguous: %p, %d pages, first at %p\n", ptr7, n7, ptr7[0]); printBusyPages(); @@ -231,9 +286,19 @@ error_t MmTestBusyPage(void) MmFreePageFrame(id5); MmFreePageFrame(id6); MmFreePageFrame(id7); - DebugLog("\nFree all bytes\n"); + 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); + return EOK; } diff --git a/kaleid/kernel/sh/testcmds.c b/kaleid/kernel/sh/testcmds.c index cbd1f8b..0973993 100644 --- a/kaleid/kernel/sh/testcmds.c +++ b/kaleid/kernel/sh/testcmds.c @@ -220,19 +220,6 @@ error_t CmdPageTranslatePhyToVirt(int argc, char **argv, char *cmdline) return EOK; } -enum -{ - PRESENT = 1 << 0, - READWRITE = 1 << 1, - USERMODE = 1 << 2, - WRITETHR = 1 << 3, - CACHEDIS = 1 << 4, - ACCESSED = 1 << 5, - DIRTY = 1 << 6, - HUGE = 1 << 7, - NX = 1UL << 63 -}; - error_t CmdPageMap(int argc, char **argv, char *cmdline) { void *virtual = (void*)strtoul(argv[1], NULL, 16);