2016-06-26 16:45:10 +00:00
|
|
|
#include <console.hpp>
|
|
|
|
#include <kernel/pmm.hpp>
|
|
|
|
#include <numeric.hpp>
|
|
|
|
#include <pointer.hpp>
|
|
|
|
#include <multiboot.hpp>
|
|
|
|
#include <kernel/gdt.hpp>
|
|
|
|
#include <kernel/idt.hpp>
|
|
|
|
#include <io.hpp>
|
|
|
|
#include <kernel/vmm.hpp>
|
|
|
|
#include <elf.hpp>
|
|
|
|
#include <kernel/bsod.hpp>
|
|
|
|
|
|
|
|
#include <asm.hpp>
|
|
|
|
|
|
|
|
#include "driver/timer.hpp"
|
|
|
|
#include "driver/keyboard.hpp"
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <new>
|
|
|
|
|
|
|
|
|
|
|
|
using namespace multiboot;
|
|
|
|
using namespace console_tools;
|
|
|
|
|
|
|
|
struct dummy;
|
|
|
|
|
|
|
|
// Symbols generated by linker, no useful content in there...
|
|
|
|
extern dummy kernelStartMarker;
|
|
|
|
extern dummy kernelEndMarker;
|
|
|
|
|
|
|
|
driver::Timer timer;
|
|
|
|
driver::Keyboard keyboardDriver;
|
|
|
|
|
|
|
|
VMMContext * kernelContext;
|
|
|
|
|
|
|
|
static void initializePMM(Structure const & data)
|
|
|
|
{
|
|
|
|
for(auto &mmap : data.memoryMaps) {
|
|
|
|
if(mmap.length == 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if(mmap.isFree() == false) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Console::main
|
|
|
|
//<< "mmap: "
|
|
|
|
//<< "start: " << hex(mmap.base) << ", length: " << hex(mmap.length)
|
|
|
|
//<< ", " << mmap.entry_size
|
|
|
|
//<< ", " << sizeof(mmap)
|
|
|
|
//<< "\n";
|
|
|
|
if(mmap.base > 0xFFFFFFFF) {
|
|
|
|
//Console::main << "mmap out of 4 gigabyte range." << "\n";
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if(mmap.isFree()) {
|
|
|
|
// Mark all free memory free...
|
|
|
|
physical_t lower = physical_t(mmap.base).alignUpper(4096);
|
|
|
|
physical_t upper = physical_t(mmap.base + mmap.length).alignLower(4096);
|
|
|
|
|
|
|
|
uint32_t ptr = lower.numeric();
|
|
|
|
while (ptr < upper.numeric()) {
|
|
|
|
PMM::markFree(physical_t(ptr));
|
|
|
|
ptr += 0x1000;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Mark all memory used by the kernel used...
|
|
|
|
physical_t lower = physical_t(&kernelStartMarker).alignLower(4096);
|
|
|
|
physical_t upper = physical_t(&kernelEndMarker).alignUpper(4096);
|
|
|
|
|
|
|
|
uint32_t ptr = lower.numeric();
|
|
|
|
while (ptr < upper.numeric()) {
|
|
|
|
PMM::markUsed(physical_t(ptr));
|
|
|
|
ptr += 0x1000;
|
|
|
|
}
|
|
|
|
|
|
|
|
// nullptr is not valid.
|
|
|
|
PMM::markUsed(physical_t(nullptr));
|
|
|
|
|
|
|
|
// Mark the video memory as used.
|
|
|
|
PMM::markUsed(physical_t(0xB8000));
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void init(Structure const & data)
|
|
|
|
{
|
|
|
|
Console::main.clear();
|
|
|
|
Console::main
|
|
|
|
<< "Hello World!\n"
|
|
|
|
<< FColor(Color::Yellow) << "Hello color!" << FColor() << "\n"
|
|
|
|
<< BColor(Color::Blue) << "Hello blue!" << BColor() << "\n"
|
|
|
|
<< "Hello default color.\n";
|
|
|
|
|
|
|
|
GDT::initialize();
|
|
|
|
|
|
|
|
Console::main
|
|
|
|
<< "bootloader name: " << data.bootLoaderName << "\n"
|
|
|
|
<< "command line: " << data.commandline << "\n"
|
|
|
|
<< "count of modules: " << data.modules.length << "\n"
|
|
|
|
<< "count of mmaps: " << data.memoryMaps.length << "\n";
|
|
|
|
|
|
|
|
initializePMM(data);
|
|
|
|
|
|
|
|
auto freeMemory = PMM::getFreeMemory();
|
|
|
|
Console::main
|
|
|
|
<< "Free: "
|
|
|
|
<< (freeMemory >> 20) << "MB, "
|
|
|
|
<< (freeMemory >> 10) << "KB, "
|
|
|
|
<< (freeMemory >> 0) << "B, "
|
|
|
|
<< (freeMemory >> 12) << "Pages\n";
|
|
|
|
|
|
|
|
IDT::initialize();
|
|
|
|
Console::main << "Interrupts set up.\n";
|
|
|
|
|
|
|
|
Console::main << "Creating VMM Context...\n";
|
|
|
|
kernelContext = new (PMM::alloc().data()) VMMContext();
|
|
|
|
|
|
|
|
Console::main << "Mapping memory...\n";
|
|
|
|
for(uint32_t addr = 0; addr < 4096 * 1024; addr += 0x1000) {
|
|
|
|
kernelContext->map(
|
|
|
|
virtual_t(addr),
|
|
|
|
physical_t(addr),
|
|
|
|
VMMFlags::Writable | VMMFlags::UserSpace);
|
|
|
|
}
|
|
|
|
kernelContext->map(
|
|
|
|
virtual_t(kernelContext),
|
|
|
|
physical_t(kernelContext),
|
|
|
|
VMMFlags::Writable);
|
|
|
|
Console::main << "Active Context...\n";
|
|
|
|
VMM::activate(*kernelContext);
|
|
|
|
|
|
|
|
Console::main << "Active Paging...\n";
|
|
|
|
VMM::enable();
|
|
|
|
Console::main << "Virtual Memory Management ready.\n";
|
|
|
|
|
|
|
|
timer.install();
|
|
|
|
keyboardDriver.install();
|
|
|
|
|
|
|
|
Console::main << "Drivers installed.\n";
|
|
|
|
|
2016-06-26 16:48:09 +00:00
|
|
|
ASM::sti();
|
|
|
|
Console::main << "Interrupts enabled.\n";
|
2016-06-26 16:45:10 +00:00
|
|
|
|
|
|
|
while(true);
|
|
|
|
}
|
|
|
|
|
2016-06-26 16:48:09 +00:00
|
|
|
static_assert(sizeof(void*) == 4, "Target platform is not 32 bit.");
|