Adds ultra-simple program loader and executor. Currently yields a Page Fault.
This commit is contained in:
parent
cc61fbecb9
commit
012cc69edb
4 changed files with 45 additions and 13 deletions
|
@ -53,7 +53,11 @@ run:
|
||||||
-d cpu_reset,int \
|
-d cpu_reset,int \
|
||||||
-no-reboot \
|
-no-reboot \
|
||||||
-no-shutdown \
|
-no-shutdown \
|
||||||
-serial stdio
|
-serial stdio \
|
||||||
|
-initrd ../program0/program0.bin
|
||||||
|
|
||||||
|
insight:
|
||||||
|
objdump -d kernel-base.ker | c++filt | less
|
||||||
|
|
||||||
bnr: kernel-base.ker run
|
bnr: kernel-base.ker run
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace multiboot
|
||||||
|
|
||||||
mbarray() = delete;
|
mbarray() = delete;
|
||||||
public:
|
public:
|
||||||
T const & operator [](size_t idx) {
|
T const & operator [](size_t idx) const {
|
||||||
return this->data[idx];
|
return this->data[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#include "console.hpp"
|
#include "console.hpp"
|
||||||
#include "pmm.hpp"
|
#include "pmm.hpp"
|
||||||
#include "numeric.hpp"
|
#include "numeric.hpp"
|
||||||
|
@ -15,6 +13,9 @@
|
||||||
#include "driver/keyboard.hpp"
|
#include "driver/keyboard.hpp"
|
||||||
#include "driver/scheduler.hpp"
|
#include "driver/scheduler.hpp"
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
using namespace multiboot;
|
using namespace multiboot;
|
||||||
using namespace console_tools;
|
using namespace console_tools;
|
||||||
|
|
||||||
|
@ -28,6 +29,28 @@ driver::Timer timer;
|
||||||
driver::Keyboard keyboardDriver;
|
driver::Keyboard keyboardDriver;
|
||||||
driver::Scheduler scheduler;
|
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>();
|
||||||
|
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)
|
extern "C" void init(Structure const & data)
|
||||||
{
|
{
|
||||||
Console::main
|
Console::main
|
||||||
|
@ -97,18 +120,18 @@ extern "C" void init(Structure const & data)
|
||||||
Console::main << "Interrupts set up.\n";
|
Console::main << "Interrupts set up.\n";
|
||||||
|
|
||||||
Console::main << "Creating VMM Context...\n";
|
Console::main << "Creating VMM Context...\n";
|
||||||
VMMContext kernelContext;
|
kernelContext = new (PMM::alloc().data()) VMMContext();
|
||||||
|
|
||||||
|
|
||||||
Console::main << "Mapping memory...\n";
|
Console::main << "Mapping memory...\n";
|
||||||
for(uint32_t addr = 0; addr < 4096 * 1024; addr += 0x1000) {
|
for(uint32_t addr = 0; addr < 4096 * 1024; addr += 0x1000) {
|
||||||
kernelContext.map(
|
kernelContext->map(
|
||||||
virtual_t(addr),
|
virtual_t(addr),
|
||||||
physical_t(addr),
|
physical_t(addr),
|
||||||
VMMFlags::Writable | VMMFlags::UserSpace);
|
VMMFlags::Writable | VMMFlags::UserSpace);
|
||||||
}
|
}
|
||||||
Console::main << "Active Context...\n";
|
Console::main << "Active Context...\n";
|
||||||
VMM::activate(kernelContext);
|
VMM::activate(*kernelContext);
|
||||||
|
|
||||||
Console::main << "Active Paging...\n";
|
Console::main << "Active Paging...\n";
|
||||||
VMM::enable();
|
VMM::enable();
|
||||||
|
@ -122,14 +145,13 @@ extern "C" void init(Structure const & data)
|
||||||
|
|
||||||
asm volatile("sti");
|
asm volatile("sti");
|
||||||
|
|
||||||
// asm volatile ("int $0x00");
|
|
||||||
|
|
||||||
Console::main << "Interrupts enabled.\n";
|
Console::main << "Interrupts enabled.\n";
|
||||||
|
|
||||||
uint32_t *invalidAddress = (uint32_t*)0xFF0000FF;
|
|
||||||
|
|
||||||
Console::main <<
|
if(data.modules.length > 0)
|
||||||
"Value at " << invalidAddress << " = " << (*invalidAddress) << "\n";
|
{
|
||||||
|
run_program0(data.modules[0]);
|
||||||
|
}
|
||||||
|
|
||||||
while(true);
|
while(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,12 @@ void VMMContext::provide(virtual_t virt, VMMFlags flags)
|
||||||
this->map(virt, PMM::alloc(), flags | VMMFlags::SystemAllocated);
|
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.
|
* 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 <<
|
Console::main <<
|
||||||
"Mapping " << virt << " -> " << phys << " [" << bin(static_cast<int>(flags)) << "]: " << hex(pageDesc) << "\n";
|
"Mapping " << virt << " -> " << phys << " [" << bin(static_cast<int>(flags)) << "]: " << hex(pageDesc) << "\n";
|
||||||
//*/
|
//*/
|
||||||
asm volatile("invlpg %0" : : "m" (*(char*)phys.numeric()));
|
invlpg(virt.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue