diff --git a/Makefile b/Makefile index dd24e73..d72e87f 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ DISK_IMG_FILES = build/kernel/kernel.bin hello.txt alpha.txt KERNEL_OBJS = build/kernel/entry.o build/kernel/screenstuff.o build/kernel/io.o build/kernel/idt.o build/kernel/keyboard.o \ build/kernel/strings.o build/kernel/atapio.o build/kernel/kmain.o build/kernel/paging.o build/kernel/allocate.o \ build/kernel/gdt.o build/kernel/memory.o build/kernel/process.o build/kernel/datatypes/hash.o \ - build/kernel/terminal.o build/kernel/global.o + build/kernel/terminal.o build/kernel/global.o build/kernel/kernel.o STAGE2_OBS = build/c_code_entry.o build/boot_stage2/io.o build/boot_stage2/atapio.o build/boot_stage2/strings.o build/boot_stage2/screenstuff.o build/boot_stage2/stage2.o build/boot_stage2/paging.o run: disk.img diff --git a/src/kernel/global.cpp b/src/kernel/global.cpp index 59553af..b1096d0 100644 --- a/src/kernel/global.cpp +++ b/src/kernel/global.cpp @@ -1,4 +1,5 @@ -#include "global.h" +#include "memory.h" + namespace Global { Allocator* allocator = 0; } diff --git a/src/kernel/global.h b/src/kernel/global.h index d2afd06..03cdcc1 100644 --- a/src/kernel/global.h +++ b/src/kernel/global.h @@ -1,7 +1,7 @@ #ifndef GLOBAL_H #define GLOBAL_H -#include "memory.h" +class Allocator; namespace Global { extern Allocator* allocator; diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp new file mode 100644 index 0000000..777127f --- /dev/null +++ b/src/kernel/kernel.cpp @@ -0,0 +1,9 @@ +#include "kernel.h" + +Kernel* Kernel::kernel; + +Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base) + : Process(0, 0x8a000, page_directory, phys, virt, virt_alloc_base) +{ + this->kernel = this; +} \ No newline at end of file diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h new file mode 100644 index 0000000..720f219 --- /dev/null +++ b/src/kernel/kernel.h @@ -0,0 +1,15 @@ +#ifndef KERNEL_H +#define KERNEL_H + +#include "process.h" + +class Kernel : public Process { +private: + static Kernel* kernel; + +public: + + Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base); +}; + +#endif \ No newline at end of file diff --git a/src/kernel/kmain.cpp b/src/kernel/kmain.cpp index 281f63d..1490a27 100644 --- a/src/kernel/kmain.cpp +++ b/src/kernel/kmain.cpp @@ -13,19 +13,21 @@ #include "global.h" #include "datatypes/hashtable.h" #include "terminal.h" +#include "kernel.h" int main() { init_gdt(); init_term(); - + PageDirectory kernel_pd = PageDirectory(0xc0100000, 0x120000, 0xbffe0000); + kernel_pd.select(); kernel_pd.unmap(0x8000); PageMap phys_pm(0xc0600000); PageMap virt_pm(0xc0620000); - Kernel kernel = Kernel(&kernel_pd, &phys_pm, &virt_pm, 0xd0000000); + Kernel kernel = Kernel(&kernel_pd, &phys_pm, &virt_pm, 0xc0000000); Global::allocator = &kernel; Terminal* current_term; @@ -33,14 +35,22 @@ int main() { TextModeTerminal* term = new TextModeTerminal(0xc0501000); current_term = term; + TextModeTerminal* term2 = new TextModeTerminal(0xc0501000); + term2->printf("Balls"); + init_idt(); + term->activate(); term->clear_screen(); term->printf("Hello, World!\n\nWe are running XnoeOS Code in C++ now, Protected Mode has been achieved (as well as Virtual Memory / Paging!!!) and everything is working super nicely!\n\nHow wonderful!\n\nNow I just need to hope my print function works properly too~~\n"); term->printf("KERNEL OK!\n"); - term->activate(); + + Process* process = new Process(1); + + term->deactivate(); + term2->activate(); while (1); diff --git a/src/kernel/memory.cpp b/src/kernel/memory.cpp index a271d62..3e8dc4c 100644 --- a/src/kernel/memory.cpp +++ b/src/kernel/memory.cpp @@ -1,5 +1,4 @@ #include "memory.h" -#include "screenstuff.h" void memset(uint8_t* address, uint32_t count, uint8_t value) { for (int i=0; ipagemap = (uint8_t*)map; } +PageMap::PageMap() { + this->pagemap = new uint8_t[131072]; + memset(this->pagemap, 131072, 0xff); +} + void PageMap::set_bit(uint32_t index) { uint32_t offset = index % 8; uint32_t i = index / 8; @@ -83,7 +87,12 @@ PageTable::PageTable(uint32_t phys, uint32_t virt) { page_table = (PTE*)virt; } -PageTable::PageTable(){} +PageTable::PageTable(){ + virt_addr = new PTE[1024]; + phys_addr = Global::allocator->virtual_to_physical(virt_addr); + + page_table = (PTE*)virt_addr; +} void PageTable::map_table(uint32_t index, uint32_t addr) { page_table[index] = (PTE){ @@ -122,6 +131,7 @@ uint32_t PageTable::get_physical_address(uint32_t index) { } PageDirectory::PageDirectory(PDE* page_directory, uint32_t phys_addr, uint32_t offset) { + this->page_tables = (PageTable*)this->__page_tables; this->page_directory = page_directory; this->phys_addr = phys_addr; @@ -131,9 +141,19 @@ PageDirectory::PageDirectory(PDE* page_directory, uint32_t phys_addr, uint32_t o } } +PageDirectory::PageDirectory() { + this->page_tables = (PageTable*)this->__page_tables; + this->page_directory = new PDE[1024]; + memset((uint8_t*)this->page_tables, sizeof(PageTable) * 1024, 0); + this->phys_addr = Global::allocator->virtual_to_physical(this->page_directory); +} + void PageDirectory::map(uint32_t phys, uint32_t virt) { split_addr* split = (split_addr*)&virt; + if (!page_tables[split->pd_index].virt_addr) + page_tables[split->pd_index] = PageTable(); + page_directory[split->pd_index] = (PDE){ .present = 1, .read_write = 1, @@ -177,7 +197,15 @@ Allocator::Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt this->virt_alloc_base = virt_alloc_base; } +Allocator::Allocator(PageDirectory* page_directory, PageMap* virt, uint32_t virt_alloc_base) { + this->PD = page_directory; + this->virt = virt; + + this->virt_alloc_base = virt_alloc_base; +} + void* Allocator::allocate(uint32_t size) { + asm("mov $0x0, 0x8a000"); uint32_t count = (size + (4096 - size % 4096)) / 4096; uint32_t virt_addr = virt->find_next_available_from(this->virt_alloc_base, count); @@ -186,6 +214,7 @@ void* Allocator::allocate(uint32_t size) { for (int i=0; iphys->find_next_available_from(0); this->phys->mark_unavailable(phys_addr); + asm("mov $0xdead, 0x8a000"); this->PD->map(phys_addr, virt_addr + 4096 * i); } @@ -199,4 +228,8 @@ void Allocator::deallocate(uint32_t virt_addr) { phys->mark_available(phys_addr); virt->mark_available(virt_addr); +} + +uint32_t Allocator::virtual_to_physical(uint32_t virt) { + return PD->virtual_to_physical(virt); } \ No newline at end of file diff --git a/src/kernel/memory.h b/src/kernel/memory.h index 33d8fc2..2a8b476 100644 --- a/src/kernel/memory.h +++ b/src/kernel/memory.h @@ -1,10 +1,10 @@ #ifndef MEMORY_H #define MEMORY_H -#include "datatypes/tuple.h" #include "paging.h" #include "allocate.h" #include "screenstuff.h" +#include "global.h" void memset(uint8_t* address, uint32_t count, uint8_t value); void memcpy(uint8_t* src, uint8_t* dst, uint32_t count); @@ -20,6 +20,7 @@ private: public: PageMap(uint32_t map); + PageMap(); void mark_unavailable(uint32_t address); void mark_unavailable(uint32_t address, uint32_t count); @@ -51,12 +52,14 @@ struct PageTable { class PageDirectory { private: PDE* page_directory; - PageTable page_tables[1024]; + uint8_t __page_tables[sizeof(PageTable) * 1024]; + PageTable* page_tables; uint32_t phys_addr; public: PageDirectory(PDE* page_directories, uint32_t phys_addr, uint32_t offset); + PageDirectory(); void map(uint32_t phys, uint32_t virt); void unmap(uint32_t virt); @@ -76,8 +79,11 @@ protected: uint32_t virt_alloc_base; public: Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base); + Allocator(PageDirectory* page_directory, PageMap* virt, uint32_t virt_alloc_base); virtual void* allocate(uint32_t size); virtual void deallocate(uint32_t virt_addr); + + uint32_t virtual_to_physical(uint32_t virt); }; #endif \ No newline at end of file diff --git a/src/kernel/process.cpp b/src/kernel/process.cpp index dba508a..760d8e4 100644 --- a/src/kernel/process.cpp +++ b/src/kernel/process.cpp @@ -14,11 +14,20 @@ xnoe::Maybe*> Process::get_alloc_tracker(uint return xnoe::Maybe*>(); } -Process::Process(uint32_t PID, PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base) +Process::Process(uint32_t PID, void* stack, PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base) : Allocator(page_directory, phys, virt, virt_alloc_base) { this->PID = PID; this->page_remaining = 0; this->last_page_pointer = virt_alloc_base; + this->stack = stack; +} + +Process::Process(uint32_t PID) +: Allocator(new PageDirectory, new PageMap, 0) { + this->PID = PID; + this->page_remaining = 0; + this->last_page_pointer = virt_alloc_base; + this->stack = new uint8_t[0x8000]; } void* Process::allocate(uint32_t size) { @@ -83,6 +92,3 @@ uint32_t Process::count_allocations(uint32_t address) { return 0; } -Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base) - : Process(0, page_directory, phys, virt, virt_alloc_base) -{} \ No newline at end of file diff --git a/src/kernel/process.h b/src/kernel/process.h index bee7248..2cf3ce8 100644 --- a/src/kernel/process.h +++ b/src/kernel/process.h @@ -32,7 +32,8 @@ private: xnoe::Maybe*> get_alloc_tracker(uint32_t address); public: - Process(uint32_t PID, PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base); + Process(uint32_t PID, void* stack, PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base); + Process(uint32_t PID); void* allocate(uint32_t size) override; void deallocate(uint32_t virt_addr) override; @@ -40,11 +41,4 @@ public: uint32_t count_allocations(uint32_t address); }; -class Kernel : public Process { -public: - static Allocator* global_allocator; - - Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base); -}; - #endif \ No newline at end of file