Starting for C++ paging management...

master
q3k 2013-03-01 19:07:44 +01:00
parent 63d86fc625
commit b4f6409bcb
8 changed files with 152 additions and 6 deletions

View File

@ -31,7 +31,7 @@ CFLAGS+= -mno-red-zone -ffreestanding -I ./include/Lua -I ./src/Lua
CXFLAGS:=-m64 -mcmodel=large -Wall -Werror -nostdlib -nostartfiles -nodefaultlibs -g
CXFLAGS+=-I ./include -Wno-packed-bitfield-compat -O2 -fno-optimize-sibling-calls -mcmodel=kernel
CXFLAGS+= -mno-red-zone -ffreestanding -I ./include/Lua -I ./src/Lua -fno-exceptions -fno-rtti
CXFLAGS+= -fno-stack-protector
CXFLAGS+= -fno-stack-protector -std=c++11
LFLAGS:=-nostdlib -nostartfiles -nodefaultlibs

View File

@ -47,6 +47,7 @@ void heap_free(T_HEAP *Heap, void *Address);
void heap_init_simple(void);
void *kmalloc(u64 Size);
void *kmalloc_aligned(u64 Size);
void *kmalloc_p(u64 Size, u8 Aligned, u64 *Physical);
void kfree(void *Data);

View File

@ -101,6 +101,7 @@ void paging_scratch_initialize(void);
// Warning, this memory cannot be freed.
void *paging_scratch_map(u64 Physical);
void *paging_scratch_allocate(void);
u64 paging_scratch_get_physical(void *Virtual);
// A simple page map call. This does no checks! Triple faults ahoy.
void paging_map_page(u64 Virtual, u64 Physical);

View File

@ -33,13 +33,15 @@ namespace cb {
// static pointers to common areas
static T_PAGING_TAB *m_LOWMEM;
static u64 m_LOWMEM_Physical;
static T_PAGING_DIR *m_SCRATCH;
static u64 m_SCRATCH_Physical;
static T_PAGING_DIR *m_TEXT;
static u64 m_TEXT_Physical;
public:
static void PopulateCommonPointers(void);
// Creates a new page directory for a kernel task, with new stack and other internal stuff
// Allocator is a function pointer to an allocator to use, Destructor is the same but for
// deallocation
CKernelML4(void *(*Allocator)(u64), void (*Destructor)(void *));
CKernelML4(void);
// Destroys the structures and frees the segments, if needed
~CKernelML4(void);

View File

@ -388,6 +388,11 @@ void *kmalloc(u64 Size)
return heap_alloc(g_Heap, Size, 0);
}
void *kmalloc_aligned(u64 Size)
{
return heap_alloc(g_Heap, Size, 1);
}
/*void *kmalloc_p(u64 Size, u8 Aligned, u64 *Physical)
{
return heap_alloc_p(g_Heap, Size, Aligned, Physical);

View File

@ -204,3 +204,23 @@ void paging_map_page(u64 Virtual, u64 Physical)
Tab->Entries[PAGING_GET_TAB_INDEX(Virtual)].Physical = Physical >> 12;
__asm__ volatile("invlpg %0" :: "m"(Virtual));
}
u64 paging_scratch_get_physical(void* Virtual)
{
u16 DirEntry = PAGING_GET_DIR_INDEX(Virtual);
paging_temp_page_set_physical(g_PagingScratch.DirectoryPhysical);
T_PAGING_DIR *Directory = (T_PAGING_DIR *)paging_temp_page_get_virtual();
if (!Directory->Entries[DirEntry].Present)
PANIC("Address not in directory!");
u64 TablePhysical = Directory->Entries[DirEntry].Physical << 12;
paging_temp_page_set_physical(TablePhysical);
T_PAGING_TAB *Table = (T_PAGING_TAB*)paging_temp_page_get_virtual();
u16 TabEntry = PAGING_GET_TAB_INDEX(Virtual);
if (!Table->Entries[TabEntry].Present)
PANIC("Address not in table!");
return Table->Entries[TabEntry].Physical << 12;
}

View File

@ -1,6 +1,6 @@
#include "Tier1/CKernel.h"
//#include "Tier1/CPageFaultDispatcher.h"
//#include "Tier1/CPageDirectory.h"
#include "Tier1/CKernelML4.h"
//#include "Tier1/CTask.h"
//#include "Tier1/CScheduler.h"
#include "Tier1/Util/CVector.h"
@ -45,6 +45,7 @@ void CKernel::Start(void)
m_Logger = new CLogger();
Alentours::CPCIManager::Initialize();
CKernelML4::PopulateCommonPointers();
/*CTask *KernelTask = CreateKernelTask();
kprintf("[i] Kernel task has TID %i.\n", KernelTask->GetPID());
CScheduler::AddTask(KernelTask);

View File

@ -1,3 +1,119 @@
#include "Tier1/CKernelML4.h"
using namespace cb;
extern "C"
{
#include "Tier0/paging.h"
#include "Tier0/heap.h"
#include "Tier0/system.h"
#include "Tier0/panic.h"
#include "Tier0/kstdio.h"
}
#define ASSERT_ALIGNED(m) ASSERT(!(m & 0xFFF))
#define POPULATE_PAGING_ENTRY(Entry, address) do { Entry.Present = 0;\
Entry.RW = 0; \
Entry.User = 0; \
Entry.Misc = 0; \
Entry.Zero = 0; \
Entry.Physical = address >> 12; } while(0)
void CKernelML4::PopulateCommonPointers(void)
{
T_PAGING_ML4 *ML4 = (T_PAGING_ML4*)kmalloc_aligned(sizeof(T_PAGING_ML4));
for (u16 i = 0; i < 256; i++)
ML4->Entries[i].Present = 0;
// start with TEXT, this is the easiest (16 directory entries)
// TEXT: ml4 entry 511, dpt entry 510, dir entries 0 - 15
T_PAGING_DPT *TextDPT = (T_PAGING_DPT*)kmalloc_aligned(sizeof(T_PAGING_DPT));
for (u16 i = 0; i < 256; i++)
TextDPT->Entries[i].Present = 0;
POPULATE_PAGING_ENTRY(ML4->Entries[511], paging_scratch_get_physical(TextDPT));
ASSERT_ALIGNED(paging_scratch_get_physical(TextDPT));
T_PAGING_DIR *TextDirectory = (T_PAGING_DIR*)kmalloc_aligned(sizeof(T_PAGING_DIR));
for (u16 i = 0; i < 256; i++)
TextDirectory->Entries[i].Present = 0;
u64 KernelStart = system_get_kernel_physical_start();
for (u16 i = 0; i < 16; i++)
{
T_PAGING_TAB *Table = (T_PAGING_TAB*)kmalloc_aligned(sizeof(T_PAGING_TAB));
for (u16 j = 0; j < 256; i++)
{
POPULATE_PAGING_ENTRY(Table->Entries[i], KernelStart);
KernelStart += 4096;
}
u64 TablePhysical = paging_scratch_get_physical(Table);
ASSERT_ALIGNED(TablePhysical);
POPULATE_PAGING_ENTRY(TextDirectory->Entries[i], TablePhysical);
}
m_TEXT = TextDirectory;
m_TEXT_Physical = paging_scratch_get_physical(TextDirectory);
POPULATE_PAGING_ENTRY(TextDPT->Entries[510], paging_scratch_get_physical(TextDirectory));
ASSERT_ALIGNED(paging_scratch_get_physical(TextDirectory));
// next let's populate LOWMEM (1/2 of a Table)
// LOWMEM: ml4 entry 0, dpt entry 0, dir entry 0, table entries 0-127
T_PAGING_DPT *LowmemDPT = (T_PAGING_DPT*)kmalloc_aligned(sizeof(T_PAGING_DPT));
for (u16 i = 0; i < 256; i++)
LowmemDPT->Entries[i].Present = 0;
POPULATE_PAGING_ENTRY(ML4->Entries[0], paging_scratch_get_physical(LowmemDPT));
ASSERT_ALIGNED(paging_scratch_get_physical(LowmemDPT));
T_PAGING_DIR *LowmemDirectory = (T_PAGING_DIR*)kmalloc_aligned(sizeof(T_PAGING_DIR));
for (u16 i = 0; i < 256; i++)
LowmemDirectory->Entries[i].Present = 0;
POPULATE_PAGING_ENTRY(LowmemDPT-Entries[0], paging_scratch_get_physical(LowmemDirectory));
ASSERT_ALIGNED(paging_scratch_get_physical(LowmemDirectory));
T_PAGING_TAB *LowmemTable = (T_PAGING_TAB*)kmalloc_aligned(sizeof(T_PAGING_TAB));
for (u16 i = 0; i < 128; i++)
POPULATE_PAGING_ENTRY(LowmemTable->Entries[i], 4096 * i);
for (u16 i = 128; i < 256; i++)
LowmemTable->Entries[i].Present = 0;
POPULATE_PAGING_ENTRY(LowmemDirectory->Entries[0], paging_scratch_get_physical(LowmemTable));
ASSERT_ALIGNED(paging_scratch_get_physical(LowmemTable));
m_LOWMEM = LowmemTable;
m_LOWMEM_Physical = paging_scratch_get_physical(LowmemTable);
// aaand do the SCRATCH (one whole dirctory of tables)
// SCRATCH: ml4 entry 511, dpt entry 509, dir entries 0 - 255
// T_PAGING_DIR *ScratchDirectory = (T_PAGING_DIR*)kmalloc_aligned(sizeof(T_PAGING_DIR));
// u64 ScratchStart = 0xFFFFFFFF40000000;
// for (u16 i = 0; i < 256; i++)
// {
// T_PAGING_TAB *Table = (T_PAGING_TAB*)kmalloc_aligned(sizeof(T_PAGING_TAB));
// for (u16 j = 0; j < 256; i++)
// {
// Table->Entries[j].Present = 1;
// Table->Entries[j].RW = 0;
// Table->Entries[j].User = 0;
// Table->Entries[j].Misc = 0;
// Table->Entries[j].Zero = 0;
// POPULATE_PAGING_ENTRY(Table->Entries[j], ScratchStart);
// ScratchStart += 4096;
// }
// u64 TablePhysical = paging_scratch_get_physical(Table);
// POPULATE_PAGING_ENTRY(ScratchDirectory->Entries[i], TablePhysical);
// ASSERT_ALIGNED(TablePhysical);
// }
// // SCRATCH and TEXT share the same DPT
// TextDPT->Entries[509].Present = 0;
// TextDPT->Entries[509].RW = 0;
// TextDPT->Entries[509].User = 0;
// TextDPT->Entries[509].Misc = 0;
// TextDPT->Entries[509].Zero = 0;
// TextDPT->Entries[509].Physical = paging_scratch_get_physical(ScratchDirectory) >> 12;
// ASSERT_ALIGNED(paging_scratch_get_physical(ScratchDirectory));
}