[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