[GOOD] BUILD 0.1.0.450 DATE 8/29/2011 AT 10:30 AM
==================================================== + Changed 'align 0x4' line above multiboot header in loader.asm to 'align 4' + Removed -e option for echo in build.sh + Modified build.sh for linux + Fixed triple fault when enabling paging + Fixed page faults at memory manager initialization + Fixed 'mem' console function + Added more info about page fault at crash screen + Added Panic() macro + Added verbose mode for memory manager [ BAD] BUILD 0.1.0.390 DATE 8/27/2011 AT 10:54 PM ==================================================== + Added stdlib routines, separated in different files + Rewritten physical memory manager + Added virtual mem manager + Added memory allocation/freeing + Added memory library + Added temporary allocation (at end of kernel), until paging is started - Removed functionality from debug console function 'mem' - Removed system.h, the one remaining function now in stdio.h
This commit is contained in:
304
Kernel/memory/mem-heap.c
Normal file
304
Kernel/memory/mem-heap.c
Normal file
@ -0,0 +1,304 @@
|
||||
#include <memory-add.h>
|
||||
#include <debugio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MEMHEAP_MAGIC 0x50DBE514
|
||||
#define MEMHEAP_INDEX_SIZE 0x20000
|
||||
#define MEMHEAP_MINIM_SIZE 0x70000
|
||||
|
||||
#define FlagsKernel 1
|
||||
#define FlagsWriteable 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 Magic;
|
||||
// bit 0: used bit 1: reserved
|
||||
uint8 Used;
|
||||
uint32 Size;
|
||||
} MemHeapHeader;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 Magic;
|
||||
MemHeapHeader* Header;
|
||||
} MemHeapFooter;
|
||||
|
||||
MemHeap* KernelHeap;
|
||||
|
||||
uint32 MemHeapFindSmallestHole (uint32 size, uint8 page_align, MemHeap* heap)
|
||||
{
|
||||
uint32 i;
|
||||
for (i = 0; i < heap->Index.Size; i++)
|
||||
{
|
||||
MemHeapHeader* head = (MemHeapHeader*) OrderedArrayLookup(i, &heap->Index);
|
||||
|
||||
if (page_align)
|
||||
{
|
||||
uint32 location = (uint32)(head) + sizeof(MemHeapHeader);
|
||||
|
||||
// page align it
|
||||
uint32 offset = 0x1000 - (location & 0xfff);
|
||||
offset &= 0xfff;
|
||||
|
||||
if (head->Size - offset >= size) return i;
|
||||
}
|
||||
|
||||
else if (head->Size >= size) return i;
|
||||
}
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
int32 MemHeapCompare (uint32 a, uint32 b)
|
||||
{
|
||||
MemHeapHeader *ha = (MemHeapHeader*)a, *hb = (MemHeapHeader*)b;
|
||||
|
||||
if (ha->Size > hb->Size) return 1;
|
||||
else if (ha->Size == hb->Size) return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
inline void MemHeapHeaderSetup (uint32 size, uint8 used, MemHeapHeader* head)
|
||||
{
|
||||
head->Magic = MEMHEAP_MAGIC;
|
||||
head->Used = used;
|
||||
head->Size = size;
|
||||
}
|
||||
|
||||
inline void MemHeapFooterSetup (MemHeapHeader* head, MemHeapFooter* foot)
|
||||
{
|
||||
foot->Magic = MEMHEAP_MAGIC;
|
||||
foot->Header = head;
|
||||
}
|
||||
|
||||
|
||||
MemHeap* MemHeapCreate(uint32 start, uint32 end, uint32 max, uint8 flags)
|
||||
{
|
||||
if ((start & 0xfff) || (end & 0xfff)) return NULL;
|
||||
|
||||
MemHeap* heap = (MemHeap*) kmalloc(sizeof(MemHeap));
|
||||
heap->Index = OrderedArrayPlace(start, MEMHEAP_INDEX_SIZE, MemHeapCompare);
|
||||
|
||||
start += sizeof(uint32) * MEMHEAP_INDEX_SIZE;
|
||||
|
||||
if (start & 0xfff) start = (start & 0xFFFFF000) + 0x1000;
|
||||
|
||||
heap->StartAddress = start;
|
||||
heap->EndAddress = end;
|
||||
heap->Flags = flags;
|
||||
heap->MaxAddress = max;
|
||||
|
||||
// One large hole
|
||||
MemHeapHeader* hole = (MemHeapHeader*)start;
|
||||
MemHeapHeaderSetup(end-start, 0, hole);
|
||||
OrderedArrayInsert(start, &heap->Index);
|
||||
|
||||
return heap;
|
||||
}
|
||||
|
||||
|
||||
void MemHeapExpand(uint32 newsz, MemHeap* heap, PageDirectory* pd)
|
||||
{
|
||||
if (newsz <= heap->EndAddress - heap->StartAddress) return;
|
||||
|
||||
if (newsz & 0xfff) newsz = (newsz & 0xfffff000) + 0x1000;
|
||||
if (newsz + heap->StartAddress >= heap->MaxAddress) return;
|
||||
|
||||
uint32 i;
|
||||
for (i = heap->EndAddress - heap->StartAddress; i < heap->StartAddress + newsz; i+=0x1000)
|
||||
MemPhAllocFrame(PagingGetPage(i, 1, pd), heap->Flags & FlagsKernel, heap->Flags & FlagsWriteable);
|
||||
|
||||
heap->EndAddress = heap->StartAddress + newsz;
|
||||
}
|
||||
|
||||
uint32 MemHeapContract(uint32 newsz, MemHeap* heap, PageDirectory* pd)
|
||||
{
|
||||
if (newsz >= heap->EndAddress - heap->StartAddress) return 0;
|
||||
|
||||
if (newsz & 0xfff) newsz = (newsz & 0xfffff000) + 0x1000; // page align
|
||||
newsz = Max(newsz, MEMHEAP_MINIM_SIZE);
|
||||
|
||||
uint32 i;
|
||||
for (i = heap->EndAddress - heap->StartAddress - 0x1000; i > newsz; i-=0x1000)
|
||||
MemPhFreeFrame(PagingGetPage(i, 0, pd));
|
||||
|
||||
heap->EndAddress = heap->StartAddress + newsz;
|
||||
return newsz;
|
||||
}
|
||||
|
||||
|
||||
uint32 MemHeapAlloc (uint32 size, uint8 isPageAligned, MemHeap* heap, PageDirectory* pd)
|
||||
{
|
||||
// Sanity check
|
||||
if (!size || !heap) return 0;
|
||||
|
||||
// Find a good hole
|
||||
uint32 newsize = size + sizeof(MemHeapHeader) + sizeof(MemHeapFooter);
|
||||
uint32 i = MemHeapFindSmallestHole(newsize, isPageAligned, heap);
|
||||
|
||||
// Didn't find? Expand heap
|
||||
if (i == 0xffffffff)
|
||||
{
|
||||
uint32 oldLen = heap->EndAddress - heap->StartAddress;
|
||||
uint32 oldEnd = heap->EndAddress;
|
||||
MemHeapExpand(oldLen + newsize, heap, pd);
|
||||
|
||||
uint32 newLen = heap->EndAddress - heap->StartAddress;
|
||||
|
||||
// Find the last header
|
||||
uint32 i = 0, index = 0, addr = 0;
|
||||
for (; i < heap->Index.Size; i++)
|
||||
{
|
||||
uint32 tmp = OrderedArrayLookup(i, &heap->Index);
|
||||
if (tmp > addr) {
|
||||
addr = tmp; index = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MemHeapHeader* head; MemHeapFooter* foot;
|
||||
|
||||
if (heap->Index.Size == 0) // No headers? Add one
|
||||
{
|
||||
head = (MemHeapHeader*)oldEnd;
|
||||
MemHeapHeaderSetup(newLen - oldLen, 0, head);
|
||||
OrderedArrayInsert(oldEnd, &heap->Index);
|
||||
}
|
||||
|
||||
else { // Modify last header
|
||||
head = (MemHeapHeader*) OrderedArrayLookup(index, &heap->Index);
|
||||
head->Size = newLen - oldLen;
|
||||
}
|
||||
|
||||
foot = (MemHeapFooter*)((uint32)head + head->Size - sizeof(MemHeapFooter));
|
||||
MemHeapFooterSetup(head, foot);
|
||||
|
||||
// Try again
|
||||
return MemHeapAlloc(size, isPageAligned, heap, pd);
|
||||
}
|
||||
|
||||
// Get info about hole
|
||||
uint32 origAddr = OrderedArrayLookup(i, &heap->Index);
|
||||
MemHeapHeader* origHead =(MemHeapHeader*) origAddr;
|
||||
uint32 origSize = origHead->Size;
|
||||
|
||||
// Should split in two?
|
||||
if (origSize - newsize <= sizeof(MemHeapHeader) + sizeof(MemHeapFooter))
|
||||
{
|
||||
size += origSize - newsize;
|
||||
newsize = origSize;
|
||||
}
|
||||
|
||||
// Should be page aligned
|
||||
if (isPageAligned && (origAddr&0xfffff000))
|
||||
{
|
||||
uint32 newAddr = origAddr + 0x1000 - (origAddr&0xfff) - sizeof(MemHeapHeader);
|
||||
MemHeapHeaderSetup(0x1000 - (origAddr&0xfff) - sizeof(MemHeapHeader), 0, origHead);
|
||||
|
||||
MemHeapFooter* holeFooter = (MemHeapFooter*)(newAddr - sizeof(MemHeapFooter));
|
||||
MemHeapFooterSetup(origHead, holeFooter);
|
||||
|
||||
origAddr = newAddr;
|
||||
origSize -= origHead->Size;
|
||||
}
|
||||
|
||||
else OrderedArrayDeleteIndex(i, &heap->Index);
|
||||
|
||||
// Create the new block
|
||||
MemHeapHeader* bHead = (MemHeapHeader*)origAddr;
|
||||
MemHeapFooter* bFoot = (MemHeapFooter*)(origAddr + sizeof(MemHeapHeader) + size);
|
||||
MemHeapHeaderSetup(newsize, 1, bHead);
|
||||
MemHeapFooterSetup(bHead, bFoot);
|
||||
|
||||
// Create a new hole at the end of current block if necessary
|
||||
if (origSize - newsize > 0)
|
||||
{
|
||||
// header
|
||||
MemHeapHeader* hHead = (MemHeapHeader*)(origAddr + sizeof(MemHeapHeader) +
|
||||
sizeof(MemHeapFooter) + size);
|
||||
MemHeapHeaderSetup(origSize - newsize, 0, hHead);
|
||||
|
||||
// footer
|
||||
MemHeapFooter* hFoot = (MemHeapFooter*)((uint32)hHead + hHead->Size - sizeof(MemHeapFooter));
|
||||
if ((uint32)hFoot < heap->EndAddress) MemHeapFooterSetup(hHead, hFoot);
|
||||
|
||||
// add it to index
|
||||
OrderedArrayInsert((uint32)hHead, &heap->Index);
|
||||
}
|
||||
|
||||
return (uint32)bHead + sizeof(MemHeapHeader);
|
||||
}
|
||||
|
||||
void MemHeapFree (uint32 address, MemHeap* heap, PageDirectory* pd)
|
||||
{
|
||||
// Sanity check
|
||||
if (!address || !heap) return;
|
||||
|
||||
MemHeapHeader* head = (MemHeapHeader*) (address - sizeof(MemHeapHeader));
|
||||
MemHeapFooter* foot = (MemHeapFooter*) ((uint32)head + head->Size - sizeof(MemHeapFooter));
|
||||
|
||||
if (head->Magic != MEMHEAP_MAGIC) return;
|
||||
if (foot->Magic != MEMHEAP_MAGIC) return;
|
||||
|
||||
// Clear used flag
|
||||
head->Used = 0;
|
||||
|
||||
uint8 AddToIndex = 1;
|
||||
|
||||
// Unify left (if possible)
|
||||
MemHeapFooter* testFoot = (MemHeapFooter*) ((uint32)head - sizeof(MemHeapFooter));
|
||||
if (testFoot->Magic == MEMHEAP_MAGIC && testFoot->Header->Used == 0)
|
||||
{
|
||||
uint32 temp = head->Size;
|
||||
head = testFoot->Header;
|
||||
foot->Header = head;
|
||||
head->Size += temp;
|
||||
|
||||
AddToIndex = 0;
|
||||
}
|
||||
|
||||
// Unify right (if possible)
|
||||
MemHeapHeader* testHead = (MemHeapHeader*) ((uint32)foot + sizeof(MemHeapFooter));
|
||||
if ((uint32)testHead < heap->EndAddress && testHead->Magic == MEMHEAP_MAGIC && testHead->Used == 0)
|
||||
{
|
||||
head->Size += testHead->Size;
|
||||
testFoot = (MemHeapFooter*) ((uint32)testHead + testHead->Size - sizeof(MemHeapFooter));
|
||||
foot = testFoot;
|
||||
|
||||
uint32 i;
|
||||
for (i = 0; i < heap->Index.Size &&
|
||||
(uint32)testHead != OrderedArrayLookup(i, &heap->Index); i++) ;
|
||||
|
||||
if (i < heap->Index.Size) OrderedArrayDeleteIndex(i, &heap->Index);
|
||||
}
|
||||
|
||||
// Contract heap (if possible)
|
||||
if ((uint32)foot + sizeof(MemHeapFooter) == heap->EndAddress)
|
||||
{
|
||||
uint32 old = heap->EndAddress - heap->StartAddress;
|
||||
uint32 new = MemHeapContract((uint32)head + head->Size - sizeof(MemHeapFooter), heap,pd);
|
||||
|
||||
// Last block still existent
|
||||
if (head->Size > (old - new))
|
||||
{
|
||||
head->Size -= old - new;
|
||||
foot = (MemHeapFooter*) ((uint32)head + head->Size - sizeof(MemHeapFooter));
|
||||
MemHeapFooterSetup(head, foot);
|
||||
}
|
||||
|
||||
// Nope, not existent
|
||||
else
|
||||
{
|
||||
uint32 i;
|
||||
for (i=0; i<heap->Index.Size && (uint32)testHead != OrderedArrayLookup(i,&heap->Index); i++) ;
|
||||
|
||||
if (i < heap->Index.Size) OrderedArrayDeleteIndex(i,&heap->Index);
|
||||
}
|
||||
}
|
||||
|
||||
// Lastly, insert hole in array
|
||||
if (AddToIndex) OrderedArrayInsert((uint32)head, &heap->Index);
|
||||
}
|
||||
|
||||
|
74
Kernel/memory/mem-paging.c
Normal file
74
Kernel/memory/mem-paging.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* memory-vi.c
|
||||
*
|
||||
* Created on: Aug 23, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
#include <memory-add.h>
|
||||
#include <stdio.h>
|
||||
/*******************************
|
||||
* Data *
|
||||
*******************************/
|
||||
PageDirectory* CurrentDirectory;
|
||||
PageDirectory* KernelDirectory;
|
||||
|
||||
/*******************************
|
||||
* Useful routines *
|
||||
*******************************/
|
||||
void PagingInitialize(uint32 kernel_used)
|
||||
{
|
||||
LogMem("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);
|
||||
|
||||
LogMem("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);
|
||||
|
||||
LogMem("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));
|
||||
|
||||
LogMem("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;
|
||||
}
|
||||
|
75
Kernel/memory/mem-paging.c~
Normal file
75
Kernel/memory/mem-paging.c~
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* memory-vi.c
|
||||
*
|
||||
* Created on: Aug 23, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
#include <memory-add.h>
|
||||
#include <stdio.h>
|
||||
/*******************************
|
||||
* Data *
|
||||
*******************************/
|
||||
PageDirectory* CurrentDirectory;
|
||||
PageDirectory* KernelDirectory;
|
||||
|
||||
/*******************************
|
||||
* Useful routines *
|
||||
*******************************/
|
||||
void PagingInitialize(uint32 kernel_used)
|
||||
{
|
||||
LogMem("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);
|
||||
|
||||
LogMem("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);
|
||||
|
||||
LogMem("Mapped kernel space.\n");
|
||||
|
||||
PagingSwitchPageDirectory (kernelPd);
|
||||
}
|
||||
|
||||
void PagingSwitchPageDirectory (PageDirectory* dir)
|
||||
{
|
||||
CurrentDirectory = dir;
|
||||
asm volatile ("mov %0, %%cr3":: "r"(&dir->TablesPhysical));
|
||||
LogMem("Switched page directory to 0x%x.\n", (uint32)(&dir->TablesPhysical));
|
||||
|
||||
uint32 cr0;
|
||||
asm volatile ("mov %%cr0, %0": "=r"(cr0));
|
||||
cr0 |= 0x80000000;
|
||||
asm volatile ("mov %0, %%cr0":: "r"(cr0));
|
||||
|
||||
LogMem("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;
|
||||
}
|
||||
|
108
Kernel/memory/mem-phys.c
Normal file
108
Kernel/memory/mem-phys.c
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* mem-phys.c
|
||||
*
|
||||
* Created on: Aug 27, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
#include <memory-add.h>
|
||||
|
||||
uint32* FrameMap;
|
||||
uint32 TotalFrames;
|
||||
uint32 TotalMemory;
|
||||
uint32 UsedFrames;
|
||||
|
||||
inline void ConvertIndexToFrame (uint32 index, uint32* address, uint32* offset)
|
||||
{
|
||||
*address = (index >> 5);
|
||||
*offset = index & 0x1f;
|
||||
}
|
||||
|
||||
inline uint32 ConvertFrameToIndex (uint32 address, uint32 offset)
|
||||
{
|
||||
return (address<<5) | offset;
|
||||
}
|
||||
|
||||
void MemPhSetFrame (uint32 frame, uint8 value)
|
||||
{
|
||||
uint32 addr, off;
|
||||
ConvertIndexToFrame(frame, &addr, &off);
|
||||
|
||||
if (value) {
|
||||
if ((FrameMap[addr] & (1<<off)) == 0) UsedFrames++;
|
||||
FrameMap[addr] |= 1<<off;
|
||||
}
|
||||
|
||||
else {
|
||||
if (FrameMap[addr] & (1<<off)) UsedFrames--;
|
||||
FrameMap[addr] &= ~(1<<off);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 MemPhGetFrame (uint32 frame)
|
||||
{
|
||||
uint32 addr, off;
|
||||
ConvertIndexToFrame(frame, &addr, &off);
|
||||
|
||||
return FrameMap[addr] & (1<<off);
|
||||
}
|
||||
|
||||
uint32 MemPhFindFreeFrame()
|
||||
{
|
||||
uint32 addr, pos;
|
||||
|
||||
for (addr = 0; addr < TotalFrames >> 5; addr++)
|
||||
if (FrameMap[addr] != 0xffffffff)
|
||||
{
|
||||
for (pos = 0; (FrameMap[addr] & (1<<pos)) != 0; pos++) ;
|
||||
|
||||
return ConvertFrameToIndex(addr, pos);
|
||||
}
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
void MemPhAllocFrame(Page* page, uint8 isKernel, uint8 isWriteable)
|
||||
{
|
||||
if ((*page & PageFrame) != 0) return;
|
||||
|
||||
uint32 free = MemPhFindFreeFrame();
|
||||
if (free == 0xffffffff) {
|
||||
Panic("%#Failed allocation free=0x%x page=0x%x\n", ColorRed, free, *page);
|
||||
return;
|
||||
}
|
||||
|
||||
MemPhSetFrame(free, 1);
|
||||
*page |= PagePresent;
|
||||
*page |= (isKernel) ? 0 : PageUser;
|
||||
*page |= (isWriteable) ? PageWriteable : 0;
|
||||
*page |= (free<<12) & PageFrame;
|
||||
}
|
||||
|
||||
void MemPhFreeFrame(Page* page)
|
||||
{
|
||||
uint32 frame = *page & PageFrame;
|
||||
if (!frame) return;
|
||||
|
||||
MemPhSetFrame(frame, 0);
|
||||
*page &= ~PageFrame;
|
||||
}
|
||||
|
||||
void MemPhInitialize(uint32 SystemMemoryKb)
|
||||
{
|
||||
TotalFrames = SystemMemoryKb >> 2;
|
||||
TotalMemory = SystemMemoryKb;
|
||||
|
||||
FrameMap = (uint32*) kmalloc(sizeof(uint32) * (1 + (TotalFrames>>5)));
|
||||
memset(FrameMap, 0, sizeof(uint32) * (1 + (TotalFrames>>5)));
|
||||
LogMem("%#Started physical memory manager ok!, found %ukb\n", ColorLightGreen, SystemMemoryKb);
|
||||
}
|
||||
|
||||
void MemPhReserveFrames (uint32 address, uint32 length)
|
||||
{
|
||||
address >>= 12;
|
||||
length = (length>>12) + ((length & 0xfff) > 0);
|
||||
uint32 end = address + length;
|
||||
|
||||
for (; address < end ; address++)
|
||||
MemPhSetFrame(address, 1);
|
||||
}
|
109
Kernel/memory/mem-phys.c~
Normal file
109
Kernel/memory/mem-phys.c~
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* mem-phys.c
|
||||
*
|
||||
* Created on: Aug 27, 2011
|
||||
* Author: Tiberiu
|
||||
*/
|
||||
#include <memory-add.h>
|
||||
|
||||
uint32* FrameMap;
|
||||
uint32 TotalFrames;
|
||||
uint32 TotalMemory;
|
||||
uint32 UsedFrames;
|
||||
|
||||
inline void ConvertIndexToFrame (uint32 index, uint32* address, uint32* offset)
|
||||
{
|
||||
*address = (index >> 5);
|
||||
*offset = index & 0x1f;
|
||||
}
|
||||
|
||||
inline uint32 ConvertFrameToIndex (uint32 address, uint32 offset)
|
||||
{
|
||||
return (address<<5) | offset;
|
||||
}
|
||||
|
||||
void MemPhSetFrame (uint32 frame, uint8 value)
|
||||
{
|
||||
uint32 addr, off;
|
||||
ConvertIndexToFrame(frame, &addr, &off);
|
||||
|
||||
if (value) {
|
||||
if ((FrameMap[addr] & (1<<off)) == 0) UsedFrames++;
|
||||
FrameMap[addr] |= 1<<off;
|
||||
}
|
||||
|
||||
else {
|
||||
if (FrameMap[addr] & (1<<off)) UsedFrames--;
|
||||
FrameMap[addr] &= ~(1<<off);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 MemPhGetFrame (uint32 frame)
|
||||
{
|
||||
uint32 addr, off;
|
||||
ConvertIndexToFrame(frame, &addr, &off);
|
||||
|
||||
return FrameMap[addr] & (1<<off);
|
||||
}
|
||||
|
||||
uint32 MemPhFindFreeFrame()
|
||||
{
|
||||
uint32 addr, pos;
|
||||
|
||||
for (addr = 0; addr < TotalFrames >> 5; addr++)
|
||||
if (FrameMap[addr] != 0xffffffff)
|
||||
{
|
||||
for (pos = 0; (FrameMap[addr] & (1<<pos)) != 0; pos++) ;
|
||||
|
||||
return ConvertFrameToIndex(addr, pos);
|
||||
}
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
void MemPhAllocFrame(Page* page, uint8 isKernel, uint8 isWriteable)
|
||||
{
|
||||
if ((*page & PageFrame) != 0) return;
|
||||
|
||||
uint32 free = MemPhFindFreeFrame();
|
||||
if (free == 0xffffffff) {
|
||||
Panic("%#Failed allocation free=0x%x page=0x%x\n", ColorRed, free, *page);
|
||||
return;
|
||||
}
|
||||
|
||||
MemPhSetFrame(free, 1);
|
||||
*page |= PagePresent;
|
||||
*page |= (isKernel) ? 0 : PageUser;
|
||||
*page |= (isWriteable) ? PageWriteable : 0;
|
||||
*page |= (free<<12) & PageFrame;
|
||||
}
|
||||
|
||||
void MemPhFreeFrame(Page* page)
|
||||
{
|
||||
uint32 frame = *page & PageFrame;
|
||||
if (!frame) return;
|
||||
|
||||
MemPhSetFrame(frame, 0);
|
||||
*page &= ~PageFrame;
|
||||
}
|
||||
|
||||
void MemPhInitialize(uint32 SystemMemoryKb)
|
||||
{
|
||||
LogMem("Starting physical memory manager...\n");
|
||||
TotalFrames = SystemMemoryKb >> 2;
|
||||
TotalMemory = SystemMemoryKb;
|
||||
|
||||
FrameMap = (uint32*) kmalloc(sizeof(uint32) * (1 + (TotalFrames>>5)));
|
||||
memset(FrameMap, 0, sizeof(uint32) * (1 + (TotalFrames>>5)));
|
||||
LogMem("%#Started physical memory manager ok!, found %ukb\n", ColorLightGreen, SystemMemoryKb);
|
||||
}
|
||||
|
||||
void MemPhReserveFrames (uint32 address, uint32 length)
|
||||
{
|
||||
address >>= 12;
|
||||
length = (length>>12) + ((length & 0xfff) > 0);
|
||||
uint32 end = address + length;
|
||||
|
||||
for (; address < end ; address++)
|
||||
MemPhSetFrame(address, 1);
|
||||
}
|
Reference in New Issue
Block a user