diff --git a/prototypes/base/Makefile b/prototypes/base/Makefile index dc1c8a5..b60293e 100644 --- a/prototypes/base/Makefile +++ b/prototypes/base/Makefile @@ -53,7 +53,11 @@ run: -d cpu_reset,int \ -no-reboot \ -no-shutdown \ - -serial stdio + -serial stdio \ + -initrd ../program0/program0.bin + +insight: + objdump -d kernel-base.ker | c++filt | less bnr: kernel-base.ker run diff --git a/prototypes/base/include/multiboot.hpp b/prototypes/base/include/multiboot.hpp index d476f5e..7005ab4 100644 --- a/prototypes/base/include/multiboot.hpp +++ b/prototypes/base/include/multiboot.hpp @@ -30,7 +30,7 @@ namespace multiboot mbarray() = delete; public: - T const & operator [](size_t idx) { + T const & operator [](size_t idx) const { return this->data[idx]; } diff --git a/prototypes/base/init.cpp b/prototypes/base/init.cpp index 05cbf2d..699e81c 100644 --- a/prototypes/base/init.cpp +++ b/prototypes/base/init.cpp @@ -1,5 +1,3 @@ -#include - #include "console.hpp" #include "pmm.hpp" #include "numeric.hpp" @@ -15,6 +13,9 @@ #include "driver/keyboard.hpp" #include "driver/scheduler.hpp" +#include +#include + using namespace multiboot; using namespace console_tools; @@ -28,6 +29,28 @@ driver::Timer timer; driver::Keyboard keyboardDriver; driver::Scheduler scheduler; +VMMContext *kernelContext; + +void run_program0(Module const & module) +{ + for(uint32_t ptr = 0; ptr < module.size(); ptr += 0x1000) + { + kernelContext->provide( + virtual_t(ptr), + VMMFlags::Writable | VMMFlags::UserSpace); + } + char * src = module.start.data(); + char * dst = (char*)0x40000000; + for(uint32_t ptr = 0; ptr < module.size(); ptr++) + { + dst[ptr] = src[ptr]; + } + + using EntryPoint = void (*)(); + EntryPoint ep = (EntryPoint)0x40000000; + ep(); +} + extern "C" void init(Structure const & data) { Console::main @@ -97,18 +120,18 @@ extern "C" void init(Structure const & data) Console::main << "Interrupts set up.\n"; Console::main << "Creating VMM Context...\n"; - VMMContext kernelContext; + kernelContext = new (PMM::alloc().data()) VMMContext(); Console::main << "Mapping memory...\n"; for(uint32_t addr = 0; addr < 4096 * 1024; addr += 0x1000) { - kernelContext.map( + kernelContext->map( virtual_t(addr), physical_t(addr), VMMFlags::Writable | VMMFlags::UserSpace); } Console::main << "Active Context...\n"; - VMM::activate(kernelContext); + VMM::activate(*kernelContext); Console::main << "Active Paging...\n"; VMM::enable(); @@ -122,14 +145,13 @@ extern "C" void init(Structure const & data) asm volatile("sti"); - // asm volatile ("int $0x00"); - Console::main << "Interrupts enabled.\n"; - uint32_t *invalidAddress = (uint32_t*)0xFF0000FF; - Console::main << - "Value at " << invalidAddress << " = " << (*invalidAddress) << "\n"; + if(data.modules.length > 0) + { + run_program0(data.modules[0]); + } while(true); } diff --git a/prototypes/base/src/vmm.cpp b/prototypes/base/src/vmm.cpp index e529aa4..4b86964 100644 --- a/prototypes/base/src/vmm.cpp +++ b/prototypes/base/src/vmm.cpp @@ -68,6 +68,12 @@ void VMMContext::provide(virtual_t virt, VMMFlags flags) this->map(virt, PMM::alloc(), flags | VMMFlags::SystemAllocated); } +static inline void invlpg(void* m) +{ + /* Clobber memory to avoid optimizer re-ordering access before invlpg, which may cause nasty bugs. */ + asm volatile ( "invlpg (%0)" : : "b"(m) : "memory" ); +} + /** * Maps a given page into the virtual memory. */ @@ -86,7 +92,7 @@ void VMMContext::map(virtual_t virt, physical_t phys, VMMFlags flags) Console::main << "Mapping " << virt << " -> " << phys << " [" << bin(static_cast(flags)) << "]: " << hex(pageDesc) << "\n"; //*/ - asm volatile("invlpg %0" : : "m" (*(char*)phys.numeric())); + invlpg(virt.data()); } /**