[BUG] Problem with stack during paging init
This commit is contained in:
parent
25b5eb6c78
commit
de43801a48
|
@ -42,8 +42,9 @@ typedef struct AllocatedPage_t{
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
ulong MmAllocPageFrame(void ***frameListPtr, size_t *pageNumber, size_t size, bool contiguous);
|
ulong MmAllocPageFrameEx(void ***frameListPtr, size_t *pageNumber, size_t size, bool contiguous);
|
||||||
void MmFreePageFrame(ulong id);
|
ulong MmAllocPageFrame(size_t size, bool contiguous);
|
||||||
|
void MmFreePageFrame(ulong id);
|
||||||
|
|
||||||
error_t MmTestBusyPage(void);
|
error_t MmTestBusyPage(void);
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ void MmInitPaging(void)
|
||||||
pdpe_t *MmPDP = NULL;
|
pdpe_t *MmPDP = NULL;
|
||||||
pde_t *MmPD = NULL;
|
pde_t *MmPD = NULL;
|
||||||
pte_t *MmPT = NULL;
|
pte_t *MmPT = NULL;
|
||||||
ulong index, xedni;
|
register ulong index, xedni;
|
||||||
ulong firstDirectoryAddr = 0;
|
ulong firstDirectoryAddr = 0;
|
||||||
ulong lastDirectoryAddr = 0;
|
ulong lastDirectoryAddr = 0;
|
||||||
ulong phDirSize = 0;
|
ulong phDirSize = 0;
|
||||||
|
@ -74,19 +74,18 @@ void MmInitPaging(void)
|
||||||
MmPhysLastKernAddress = (ulong)(_heap_start + _heap_max);
|
MmPhysLastKernAddress = (ulong)(_heap_start + _heap_max);
|
||||||
ulong diffKernUsr = (ulong)USERSPACE - MmPhysLastKernAddress - KPAGESIZE;
|
ulong diffKernUsr = (ulong)USERSPACE - MmPhysLastKernAddress - KPAGESIZE;
|
||||||
|
|
||||||
|
// Size of physical table
|
||||||
|
phDirSize = (((phRamSize + KPAGESIZE) / KPAGESIZE)*sizeof(ulong));
|
||||||
|
|
||||||
// Maximum VIRTUAL address in memory
|
// Maximum VIRTUAL address in memory
|
||||||
MmVirtLastAddress = phRamSize + diffKernUsr;
|
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));
|
for (register ulong curAddrPML4 = 0;
|
||||||
phDirSize = ((phRamSize / KPAGESIZE)*sizeof(ulong) + KPAGESIZE) & ( ~((KPAGESIZE - 1) | NX));
|
curAddrPML4 < phRamSize;
|
||||||
|
|
||||||
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;
|
|
||||||
curAddrPML4 += ((ulong)KPAGESIZE * 0x8000000)) {
|
curAddrPML4 += ((ulong)KPAGESIZE * 0x8000000)) {
|
||||||
// Create an entry in PML4 each 512GB
|
// Create an entry in PML4 each 512GB
|
||||||
// 0x8000000 = 512 ^ 3
|
// 0x8000000 = 512 ^ 3
|
||||||
|
@ -102,9 +101,9 @@ void MmInitPaging(void)
|
||||||
//DebugLog("\t\t\t\tPDP %d : %p\n", index, MmPDP);
|
//DebugLog("\t\t\t\tPDP %d : %p\n", index, MmPDP);
|
||||||
MmPageMapLevel4[index] = (pdpe_t *)((ulong)MmPDP | PRESENT | READWRITE);
|
MmPageMapLevel4[index] = (pdpe_t *)((ulong)MmPDP | PRESENT | READWRITE);
|
||||||
|
|
||||||
for (ulong curAddrPDP = curAddrPML4;
|
for (register ulong curAddrPDP = curAddrPML4;
|
||||||
curAddrPDP < (curAddrPML4 + ((ulong)KPAGESIZE * 0x8000000)) &&
|
curAddrPDP < (curAddrPML4 + ((ulong)KPAGESIZE * 0x8000000)) &&
|
||||||
curAddrPDP < MmVirtLastAddress;
|
curAddrPDP < phRamSize;
|
||||||
curAddrPDP += ((ulong)KPAGESIZE * 0x40000)) {
|
curAddrPDP += ((ulong)KPAGESIZE * 0x40000)) {
|
||||||
// Create an intry in PDP each 1GB
|
// Create an intry in PDP each 1GB
|
||||||
// 0x40000 = 512 ^ 2
|
// 0x40000 = 512 ^ 2
|
||||||
|
@ -116,9 +115,9 @@ void MmInitPaging(void)
|
||||||
//DebugLog("\t\t\t\tPD %d : %p\n", index, MmPD);
|
//DebugLog("\t\t\t\tPD %d : %p\n", index, MmPD);
|
||||||
MmPDP[index] = (pde_t *)((ulong)MmPD | PRESENT | READWRITE);
|
MmPDP[index] = (pde_t *)((ulong)MmPD | PRESENT | READWRITE);
|
||||||
|
|
||||||
for (ulong curAddrPD = curAddrPDP;
|
for (register ulong curAddrPD = curAddrPDP;
|
||||||
curAddrPD < (curAddrPDP + ((ulong)KPAGESIZE * 0x40000)) &&
|
curAddrPD < (curAddrPDP + ((ulong)KPAGESIZE * 0x40000)) &&
|
||||||
curAddrPD < MmVirtLastAddress;
|
curAddrPD < phRamSize;
|
||||||
curAddrPD += ((ulong)KPAGESIZE * 0x200)) {
|
curAddrPD += ((ulong)KPAGESIZE * 0x200)) {
|
||||||
// Create an intry in PD each 2MB
|
// Create an intry in PD each 2MB
|
||||||
// 0x200 = 512
|
// 0x200 = 512
|
||||||
|
@ -130,16 +129,17 @@ void MmInitPaging(void)
|
||||||
//DebugLog("\t\t\t\tPT %d : %p\n", index, MmPT);
|
//DebugLog("\t\t\t\tPT %d : %p\n", index, MmPT);
|
||||||
MmPD[index] = (pte_t *)((ulong)MmPT | PRESENT | READWRITE);
|
MmPD[index] = (pte_t *)((ulong)MmPT | PRESENT | READWRITE);
|
||||||
|
|
||||||
for (ulong curAddrPT = curAddrPD;
|
for (register ulong curAddrPT = curAddrPD;
|
||||||
curAddrPT < (curAddrPD + ((ulong)KPAGESIZE * 0x200)) &&
|
curAddrPT < (curAddrPD + ((ulong)KPAGESIZE * 0x200)) &&
|
||||||
curAddrPT < MmVirtLastAddress;
|
curAddrPT < phRamSize;
|
||||||
curAddrPT += (ulong)KPAGESIZE) {
|
curAddrPT += (ulong)KPAGESIZE) {
|
||||||
// Create an entry in PT each page of 4KB
|
// Create an entry in PT each page of 4KB
|
||||||
|
|
||||||
index = (curAddrPT / ((ulong)KPAGESIZE)) % 512;
|
index = (curAddrPT / ((ulong)KPAGESIZE)) % 512;
|
||||||
xedni = (curAddrPT / ((ulong)KPAGESIZE));
|
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 */
|
// STACK GUARD PAGE */
|
||||||
if ((ulong)curAddrPT == (ulong)BtLoaderInfo.stackEndAddr) {
|
if ((ulong)curAddrPT == (ulong)BtLoaderInfo.stackEndAddr) {
|
||||||
|
@ -181,21 +181,13 @@ void MmInitPaging(void)
|
||||||
//DebugLog("\tLast page of kernel at %p\n", curAddrPT);
|
//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 {
|
else {
|
||||||
MmPT[index] = 0;
|
MmPT[index] = 0;
|
||||||
|
MmPhysicalPageTable[xedni] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeFlushTlbSingle(curAddrPT);
|
KeFlushTlbSingle(curAddrPT);
|
||||||
|
asm ("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -294,6 +286,9 @@ void MmMapPage(void* virtualAddr, void* physicalAddr, ulong flags)
|
||||||
] = (ulong)virtualAddr;
|
] = (ulong)virtualAddr;
|
||||||
|
|
||||||
KeFlushTlbSingle(*page);
|
KeFlushTlbSingle(*page);
|
||||||
|
|
||||||
|
if (virtualAddr > MmVirtLastAddress)
|
||||||
|
MmVirtLastAddress = virtualAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <mm/palloc.h>
|
#include <mm/palloc.h>
|
||||||
#include <mm/map.h>
|
#include <mm/map.h>
|
||||||
#include <io/vga.h>
|
#include <io/vga.h>
|
||||||
|
#include <ke/time.h>
|
||||||
|
|
||||||
//---------
|
//---------
|
||||||
|
|
||||||
|
@ -42,6 +43,9 @@ static AllocatedPage_t busyPagesList = { (void*)0, 0, (AllocatedPage_t*)0 };
|
||||||
extern MemoryMap_t memoryMap;
|
extern MemoryMap_t memoryMap;
|
||||||
extern ulong MmPhysLastKernAddress;
|
extern ulong MmPhysLastKernAddress;
|
||||||
|
|
||||||
|
static ulong NSuccessfulAlloc = 0;
|
||||||
|
static ulong NSuccessfulFree = 0;
|
||||||
|
|
||||||
//---------
|
//---------
|
||||||
|
|
||||||
static bool isPageBusy(void *phyPageAddr)
|
static bool isPageBusy(void *phyPageAddr)
|
||||||
|
@ -120,7 +124,7 @@ static void removePageFromBusyList(void *phyPageAddr)
|
||||||
//
|
//
|
||||||
// Returns an id to identify a page frame allocated (kernel)
|
// 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;
|
static ulong id = 0;
|
||||||
*pageNumber = (((ulong)size - 1) / KPAGESIZE) + 1;
|
*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
|
// Maximum PHYSICAL address in memory
|
||||||
ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize;
|
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) {
|
for (void *curPage = (void*)(MmPhysLastKernAddress + KPAGESIZE); curPage < (void*)phRamSize; curPage += KPAGESIZE) {
|
||||||
if (!isPageBusy(curPage)) {
|
if (!isPageBusy(curPage)) {
|
||||||
|
@ -153,28 +157,47 @@ ulong MmAllocPageFrame(void ***frameListPtr, size_t *pageNumber, size_t size, bo
|
||||||
curNumber = 0;
|
curNumber = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (curNumber != *pageNumber) {
|
||||||
|
KeStartPanic("MmAllocPageFrameEx() : No more free pages to allocate");
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < *pageNumber; i++) {
|
for (size_t i = 0; i < *pageNumber; i++) {
|
||||||
addPageToBusyList((*frameListPtr)[i], id);
|
addPageToBusyList((*frameListPtr)[i], id);
|
||||||
//DebugLog("Allocating page : %p\n", *frameListPtr[i]);
|
//DebugLog("Allocating page : %p\n", *frameListPtr[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSuccessfulAlloc++;
|
||||||
|
|
||||||
return id;
|
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
|
// Frees a page frame by its id
|
||||||
//
|
//
|
||||||
void MmFreePageFrame(ulong id)
|
void MmFreePageFrame(ulong id)
|
||||||
{
|
{
|
||||||
AllocatedPage_t *busyPage = &busyPagesList;
|
AllocatedPage_t *busyPage = &busyPagesList;
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
while(busyPage->next) {
|
while(busyPage->next) {
|
||||||
busyPage = busyPage->next;
|
busyPage = busyPage->next;
|
||||||
|
|
||||||
if (id == busyPage->id) {
|
if (id == busyPage->id) {
|
||||||
removePageFromBusyList(busyPage->phyAddress);
|
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) {
|
if (id == busyPage->id) {
|
||||||
MmMapPage((void*)((ulong)virtAddr + offset), busyPage->phyAddress, flags);
|
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;
|
offset += KPAGESIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,7 +239,7 @@ error_t MmUnmapPageFrame(ulong id)
|
||||||
//DebugLog("Physical : %p is %p\n", busyPage->phyAddress, actualPhys);
|
//DebugLog("Physical : %p is %p\n", busyPage->phyAddress, actualPhys);
|
||||||
|
|
||||||
if (actualPhys && id == busyPage->id) {
|
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));
|
MmUnmapPage(MmTransPhyToVirtAddr(busyPage->phyAddress));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,79 +249,24 @@ error_t MmUnmapPageFrame(ulong id)
|
||||||
|
|
||||||
error_t MmTestBusyPage(void)
|
error_t MmTestBusyPage(void)
|
||||||
{
|
{
|
||||||
DebugLog("\nBusy pages\n");
|
ulong tab[2000] = {0};
|
||||||
printBusyPages();
|
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;
|
//printBusyPages();
|
||||||
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]);
|
|
||||||
|
|
||||||
void **ptr2 = NULL;
|
DebugLog("Alloc : %d; Free : %d\n", NSuccessfulAlloc, NSuccessfulFree);
|
||||||
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);
|
|
||||||
|
|
||||||
return EOK;
|
return EOK;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue