Move a bunch of init code to Kernel::initialize()

- Kernel owns a MemoryManager, which is responsible for initializing the GDT.
- Kernel is passed a new StartupInformation struct (borrowed this one from
  Ghost) which contains a bunch of handy tidbits for setting things up.
- Cleaned out even more stuff from kmain()
This commit is contained in:
Eryn Wells 2016-03-25 01:21:49 -04:00
parent b9ece9bbcb
commit bcfba2c167
3 changed files with 50 additions and 33 deletions

View file

@ -32,15 +32,37 @@ Kernel::systemKernel()
*/
Kernel::Kernel()
: mConsole()
: mConsole(),
mMemoryManager()
{ }
void
Kernel::initialize()
Kernel::initialize(const StartupInformation& startupInformation)
{
mConsole.clear(kernel::Console::Color::Blue);
mConsole.printString("Loading Polka...\n");
mConsole.printFormat("Kernel start: 0x%08lX\n", startupInformation.kernelStart);
mConsole.printFormat("Kernel end: 0x%08lX\n", startupInformation.kernelEnd);
mConsole.printFormat("Kernel size: %ld bytes\n", startupInformation.kernelEnd - startupInformation.kernelStart);
auto& multiboot = startupInformation.multibootInformation;
mConsole.printFormat("Command line: \"%s\"\n", multiboot->commandLine());
mConsole.printFormat("Memory map:\n");
mConsole.printFormat(" available: lower = %ld KB, upper = %ld KB\n", multiboot->lowerMemoryKB(), multiboot->upperMemoryKB());
for (auto it = multiboot->memoryMapBegin(); it != multiboot->memoryMapEnd(); ++it) {
auto begin = (*it).base;
auto end = begin + (*it).length - 1;
mConsole.printFormat(" begin = 0x%08lX %08lX, end = 0x%08lX %08lX (%s)\n",
u32(begin >> 32), u32(begin & 0xFFFFFFFF),
u32(end >> 32), u32(end & 0xFFFFFFFF),
(*it).type == 1 ? "available" : "reserved");
}
mMemoryManager.initialize(mConsole);
}

View file

@ -11,26 +11,43 @@
#include "Attributes.hh"
#include "Console.hh"
#include "Memory.hh"
#include "Multiboot.hh"
#include "kstd/Types.hh"
namespace kernel {
struct StartupInformation
{
u32 kernelStart;
u32 kernelEnd;
multiboot::Information* multibootInformation;
};
struct Kernel
{
static Kernel& systemKernel();
Kernel();
void initialize();
/** Initialize the system. */
void initialize(const StartupInformation& startupInformation);
/**
* Put up a panic screen and halt the system.
* @see halt()
*/
void panic(const char* msg, ...);
/** Disable interrupts and halt the system. You will never return from that place... */
void halt() NORETURN;
Console& console();
private:
Console mConsole;
MemoryManager mMemoryManager;
};
} /* namespace kernel */

View file

@ -22,6 +22,7 @@
#error "This file should be compiled with an ix86-elf compiler!"
#endif
// Linker script defined symbols. See linker.ld.
extern u32 kernelStart;
extern u32 kernelEnd;
@ -32,40 +33,17 @@ void
kmain(multiboot::Information *information,
u32 magic)
{
multiboot::Information::setInformation(information);
auto info = multiboot::Information::information();
auto& kernel = kernel::Kernel::systemKernel();
kernel.initialize();
kernel::StartupInformation startupInformation;
startupInformation.kernelStart = u32(&kernelStart);
startupInformation.kernelEnd = u32(&kernelEnd);
startupInformation.multibootInformation = information;
kernel.initialize(startupInformation);
auto& console = kernel.console();
auto start = u32(&kernelStart);
auto end = u32(&kernelEnd);
console.printFormat("Kernel start: 0x%08lX\n", start);
console.printFormat("Kernel end: 0x%08lX\n", end);
console.printFormat("Kernel size: %ld bytes\n", end - start);
console.printFormat("Command line: \"%s\"\n", info->commandLine());
console.printFormat("Memory map:\n");
console.printFormat(" available: lower = %ld KB, upper = %ld KB\n", info->lowerMemoryKB(), info->upperMemoryKB());
for (auto it = info->memoryMapBegin(); it != info->memoryMapEnd(); ++it) {
auto begin = (*it).base;
auto end = begin + (*it).length - 1;
console.printFormat(" begin = 0x%08lX %08lX, end = 0x%08lX %08lX (%s)\n",
u32(begin >> 32), u32(begin & 0xFFFFFFFF),
u32(end >> 32), u32(end & 0xFFFFFFFF),
(*it).type == 1 ? "available" : "reserved");
}
auto& gdt = x86::GDT::systemGDT();
gdt.setNullDescriptor(0);
gdt.setDescriptor(1, x86::GDT::DescriptorSpec::kernelSegment(0, 0xFFFFFFFF, x86::GDT::Type::CodeEXR));
gdt.setDescriptor(2, x86::GDT::DescriptorSpec::kernelSegment(0, 0xFFFFFFFF, x86::GDT::Type::DataRW));
gdt.load();
console.printString("GDT loaded\n");
auto& interruptHandler = x86::InterruptHandler::systemInterruptHandler();
interruptHandler.initialize();
interruptHandler.enableInterrupts();