Tiberiu Chibici
913e65b856
==================================================== + 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
110 lines
2.3 KiB
C
110 lines
2.3 KiB
C
/*
|
|
* 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);
|
|
}
|