Add Multiboot information struct and pass it in to kmain()
Print memory availability
This commit is contained in:
parent
98ad3282c1
commit
100da19d28
4 changed files with 274 additions and 6 deletions
23
src/Main.cc
23
src/Main.cc
|
@ -1,8 +1,17 @@
|
||||||
|
/* Main.cc
|
||||||
|
* vim: set tw=80:
|
||||||
|
* Eryn Wells <eryn@erynwells.me>
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Entry point for the kernel in C/C++.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "Console.hh"
|
#include "Console.hh"
|
||||||
#include "Descriptors.hh"
|
#include "Descriptors.hh"
|
||||||
#include "Interrupts.hh"
|
#include "Interrupts.hh"
|
||||||
|
#include "Multiboot.hh"
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
#error "This file should be compiled with a cross-compiler, not the Linux system compiler!"
|
#error "This file should be compiled with a cross-compiler, not the Linux system compiler!"
|
||||||
|
@ -19,10 +28,7 @@ kearly()
|
||||||
{
|
{
|
||||||
using kernel::Console;
|
using kernel::Console;
|
||||||
|
|
||||||
/*
|
// Create a console object for early use because global initialization hasn't happened yet.
|
||||||
* Create a console object for early use because global initialization
|
|
||||||
* hasn't happened yet.
|
|
||||||
*/
|
|
||||||
Console console;
|
Console console;
|
||||||
console.clear(kernel::Console::Color::Blue);
|
console.clear(kernel::Console::Color::Blue);
|
||||||
console.printString("Loading system ...\n");
|
console.printString("Loading system ...\n");
|
||||||
|
@ -32,12 +38,19 @@ kearly()
|
||||||
/** The beginning of the world... */
|
/** The beginning of the world... */
|
||||||
extern "C"
|
extern "C"
|
||||||
void
|
void
|
||||||
kmain()
|
kmain(multiboot::Information *information)
|
||||||
{
|
{
|
||||||
|
multiboot::Information::setInformation(information);
|
||||||
|
auto info = multiboot::Information::information();
|
||||||
|
|
||||||
// Reinitialize the system console now that we have global static objects.
|
// Reinitialize the system console now that we have global static objects.
|
||||||
auto& console = kernel::Console::systemConsole();
|
auto& console = kernel::Console::systemConsole();
|
||||||
console.clear(kernel::Console::Color::Blue);
|
console.clear(kernel::Console::Color::Blue);
|
||||||
|
|
||||||
|
console.printString("Loading Polka ...\n");
|
||||||
|
|
||||||
|
console.printFormat("Detected memory: lower = %ld KB, upper = %ld KB\n", info->lowerMemoryKB(), info->upperMemoryKB());
|
||||||
|
|
||||||
auto& gdt = x86::GDT::systemGDT();
|
auto& gdt = x86::GDT::systemGDT();
|
||||||
gdt.setNullDescriptor(0);
|
gdt.setNullDescriptor(0);
|
||||||
gdt.setDescriptor(1, x86::GDT::DescriptorSpec::kernelSegment(0, 0xFFFFFFFF, x86::GDT::Type::CodeEXR));
|
gdt.setDescriptor(1, x86::GDT::DescriptorSpec::kernelSegment(0, 0xFFFFFFFF, x86::GDT::Type::CodeEXR));
|
||||||
|
|
87
src/Multiboot.cc
Normal file
87
src/Multiboot.cc
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
/* Multiboot.cc
|
||||||
|
* vim: set tw=80:
|
||||||
|
* Eryn Wells <eryn@erynwells.me>
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Definition of multiboot stuff.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Multiboot.hh"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
enum Present {
|
||||||
|
Memory = 1 << 0,
|
||||||
|
BootDevice = 1 << 1,
|
||||||
|
CommandLine = 1 << 2,
|
||||||
|
Modules = 1 << 3,
|
||||||
|
AOutSymbols = 1 << 4,
|
||||||
|
ElfSymbols = 1 << 5,
|
||||||
|
MemoryMap = 1 << 6,
|
||||||
|
Drives = 1 << 7,
|
||||||
|
ConfigurationTable = 1 << 8,
|
||||||
|
BootLoaderName = 1 << 9,
|
||||||
|
APMTable = 1 << 10,
|
||||||
|
VBE = 1 << 11,
|
||||||
|
};
|
||||||
|
|
||||||
|
multiboot::Information *sInformation = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace multiboot {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Static
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Information *
|
||||||
|
Information::information()
|
||||||
|
{
|
||||||
|
return sInformation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Information::setInformation(Information *info)
|
||||||
|
{
|
||||||
|
sInformation = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Public
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
Information::lowerMemoryKB()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
if ((mFlags & Present::Memory) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return mMemLower;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
Information::upperMemoryKB()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
if ((mFlags & Present::Memory) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return mMemUpper;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
Information::commandLine()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
if ((mFlags & Present::CommandLine) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return reinterpret_cast<const char *>(mCommandLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace multiboot */
|
167
src/Multiboot.hh
Normal file
167
src/Multiboot.hh
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
/* Multiboot.hh
|
||||||
|
* vim: set tw=80:
|
||||||
|
* Eryn Wells <eryn@erynwells.me>
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Definition of the Multiboot structure. When grub boots, it fills in this
|
||||||
|
* structure and leaves a pointer to it in the EBX register.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MULTIBOOT_HH__
|
||||||
|
#define __MULTIBOOT_HH__
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "Attributes.hh"
|
||||||
|
|
||||||
|
namespace multiboot {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The multiboot information struct. Defined by the multiboot spec.
|
||||||
|
* See http://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Machine-state
|
||||||
|
*/
|
||||||
|
struct PACKED Information
|
||||||
|
{
|
||||||
|
static const Information *information();
|
||||||
|
static void setInformation(Information* info);
|
||||||
|
|
||||||
|
uint32_t lowerMemoryKB() const;
|
||||||
|
uint32_t upperMemoryKB() const;
|
||||||
|
const char* commandLine() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Bit field of flags. Fields below are only defined if the appropriate
|
||||||
|
* flag is set.
|
||||||
|
*/
|
||||||
|
uint32_t mFlags;
|
||||||
|
|
||||||
|
/** Amount of lower (0 to 1 MB) memory, in KB. */
|
||||||
|
uint32_t mMemLower;
|
||||||
|
/** Amount of upper (1 MB to ...) memory, in KB. Maximally, this value is the address of the first upper memory hole, minus 1 MB. */
|
||||||
|
uint32_t mMemUpper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates which BIOS disk the boot loader loaded the OS image from.
|
||||||
|
* Defined only if `bootDevice == true`.
|
||||||
|
*/
|
||||||
|
struct PACKED
|
||||||
|
{
|
||||||
|
/** Third level partition number. If unused this is set to 0xFF. */
|
||||||
|
uint8_t partitionLevel3;
|
||||||
|
/** Sub-partition number. If unused this is set to 0xFF. */
|
||||||
|
uint8_t partitionLevel2;
|
||||||
|
/** Top-level partition number. */
|
||||||
|
uint8_t partitionLevel1;
|
||||||
|
/**
|
||||||
|
* BIOS drive number, as returned by the `INT 0x13` low-level disk
|
||||||
|
* interface.
|
||||||
|
*/
|
||||||
|
uint8_t driveNumber;
|
||||||
|
} bootDevice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pointer to a C-style string containing the command line arguments.
|
||||||
|
* Defined only if `commandLinePresent == true`.
|
||||||
|
*/
|
||||||
|
uint32_t mCommandLine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates what boot modules were loaded along with the kernel image.
|
||||||
|
* Defined only if `modulesPresent == true`.
|
||||||
|
*/
|
||||||
|
struct PACKED
|
||||||
|
{
|
||||||
|
/** Number of boot modules present. */
|
||||||
|
uint32_t count;
|
||||||
|
/** Pointer to start of boot modules array. */
|
||||||
|
uint32_t address;
|
||||||
|
} modules;
|
||||||
|
|
||||||
|
// TODO: Document these.
|
||||||
|
union PACKED
|
||||||
|
{
|
||||||
|
struct PACKED
|
||||||
|
{
|
||||||
|
uint32_t tableSize;
|
||||||
|
uint32_t stringSize;
|
||||||
|
uint32_t address;
|
||||||
|
uint32_t reserved;
|
||||||
|
} aout;
|
||||||
|
|
||||||
|
struct PACKED
|
||||||
|
{
|
||||||
|
uint32_t number;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t address;
|
||||||
|
uint32_t shndx;
|
||||||
|
} elf;
|
||||||
|
} symbols;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Points to a buffer containing a memory map of the machine provided by the
|
||||||
|
* BIOS. Defined only if `memoryMapPresent == true`.
|
||||||
|
*/
|
||||||
|
struct PACKED
|
||||||
|
{
|
||||||
|
/** Number of memory map entries present. */
|
||||||
|
uint32_t count;
|
||||||
|
/** Pointer to start of memory map entry array. */
|
||||||
|
uint32_t address;
|
||||||
|
} memoryMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Points to a buffer containing a list of drive definitions provided by the
|
||||||
|
* BIOS. Defined only if `drivesPresent == true`.
|
||||||
|
*/
|
||||||
|
struct PACKED
|
||||||
|
{
|
||||||
|
/** Number of memory map entries present. */
|
||||||
|
uint32_t count;
|
||||||
|
/** Pointer to start of memory map entry array. */
|
||||||
|
uint32_t address;
|
||||||
|
} drives;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pointer to the table containing APM information. Defined only if
|
||||||
|
* `apmTablePresent == true`.
|
||||||
|
*/
|
||||||
|
uint32_t apmTable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* I dunno some VBE stuff. TODO.
|
||||||
|
*/
|
||||||
|
struct PACKED {
|
||||||
|
uint32_t controlInformation;
|
||||||
|
uint32_t modeInformation;
|
||||||
|
uint32_t mode;
|
||||||
|
uint32_t interfaceSegment;
|
||||||
|
uint32_t interfaceOff;
|
||||||
|
uint32_t interfaceLength;
|
||||||
|
} vbe;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PACKED Module
|
||||||
|
{
|
||||||
|
/** Start address of boot module. */
|
||||||
|
uint32_t start;
|
||||||
|
/** End address of boot module. */
|
||||||
|
uint32_t end;
|
||||||
|
/** Pointer to a C-style boot module string. */
|
||||||
|
uint32_t string;
|
||||||
|
/** Reserved and ignored. */
|
||||||
|
uint32_t reserved;
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: Define the MemoryMap struct
|
||||||
|
struct PACKED MemoryChunk
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: Define the Drive struct
|
||||||
|
struct PACKED Drive
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace multiboot */
|
||||||
|
|
||||||
|
#endif /* __MULTIBOOT_HH__ */
|
|
@ -41,7 +41,8 @@ _start:
|
||||||
# Global initialization done here.
|
# Global initialization done here.
|
||||||
call _init
|
call _init
|
||||||
|
|
||||||
# Here we go...
|
# Here we go... Give kmain the address of the multiboot info structure.
|
||||||
|
pushl %ebx
|
||||||
call kmain
|
call kmain
|
||||||
|
|
||||||
# In case the function returns, we'll want to put the computer into an
|
# In case the function returns, we'll want to put the computer into an
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue