From b4f6409bcb5d5dcb93af33fd3a94725681e1d6b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergiusz=20Baza=C5=84ski?= Date: Fri, 1 Mar 2013 19:07:44 +0100 Subject: [PATCH] Starting for C++ paging management... --- Kernel/Makefile | 2 +- Kernel/include/Tier0/heap.h | 1 + Kernel/include/Tier0/paging.h | 1 + Kernel/include/Tier1/CKernelML4.h | 8 +- Kernel/src/Tier0/heap.c | 5 ++ Kernel/src/Tier0/paging.c | 20 +++++ Kernel/src/Tier1/CKernel.cpp | 3 +- Kernel/src/Tier1/CKernelML4.cpp | 118 +++++++++++++++++++++++++++++- 8 files changed, 152 insertions(+), 6 deletions(-) diff --git a/Kernel/Makefile b/Kernel/Makefile index a889f7a..ab1fef5 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -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 diff --git a/Kernel/include/Tier0/heap.h b/Kernel/include/Tier0/heap.h index 0363a0e..72b9c1b 100644 --- a/Kernel/include/Tier0/heap.h +++ b/Kernel/include/Tier0/heap.h @@ -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); diff --git a/Kernel/include/Tier0/paging.h b/Kernel/include/Tier0/paging.h index d069c54..7dc85bf 100644 --- a/Kernel/include/Tier0/paging.h +++ b/Kernel/include/Tier0/paging.h @@ -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); diff --git a/Kernel/include/Tier1/CKernelML4.h b/Kernel/include/Tier1/CKernelML4.h index 2695b66..36f5280 100644 --- a/Kernel/include/Tier1/CKernelML4.h +++ b/Kernel/include/Tier1/CKernelML4.h @@ -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); diff --git a/Kernel/src/Tier0/heap.c b/Kernel/src/Tier0/heap.c index 2dc961f..a1e1f3c 100644 --- a/Kernel/src/Tier0/heap.c +++ b/Kernel/src/Tier0/heap.c @@ -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); diff --git a/Kernel/src/Tier0/paging.c b/Kernel/src/Tier0/paging.c index 0f21603..5714e45 100644 --- a/Kernel/src/Tier0/paging.c +++ b/Kernel/src/Tier0/paging.c @@ -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; +} \ No newline at end of file diff --git a/Kernel/src/Tier1/CKernel.cpp b/Kernel/src/Tier1/CKernel.cpp index 461f45d..3e339cc 100644 --- a/Kernel/src/Tier1/CKernel.cpp +++ b/Kernel/src/Tier1/CKernel.cpp @@ -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); diff --git a/Kernel/src/Tier1/CKernelML4.cpp b/Kernel/src/Tier1/CKernelML4.cpp index 3256f76..047432e 100644 --- a/Kernel/src/Tier1/CKernelML4.cpp +++ b/Kernel/src/Tier1/CKernelML4.cpp @@ -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)); +} \ No newline at end of file