GDT WORKS HOLY CRAP
This commit is contained in:
parent
94a8f74ada
commit
6c076be975
3 changed files with 71 additions and 6 deletions
|
@ -6,10 +6,19 @@
|
||||||
* Oh god oh god. Descriptor tables.
|
* Oh god oh god. Descriptor tables.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "Descriptors.hh"
|
||||||
|
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SegmentDescriptors are entries in the GDT and LDT that describe memory
|
||||||
|
* segments. Each descriptor is two double-words (8 bytes, 64 bits) long.
|
||||||
|
*/
|
||||||
|
typedef uint64_t SegmentDescriptor;
|
||||||
|
|
||||||
|
|
||||||
/** Descriptor privilege level. */
|
/** Descriptor privilege level. */
|
||||||
enum class DPL {
|
enum class DPL {
|
||||||
Ring0 = 0x0,
|
Ring0 = 0x0,
|
||||||
|
@ -18,6 +27,7 @@ enum class DPL {
|
||||||
Ring3 = 0x3
|
Ring3 = 0x3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** A four bit value describing the type of the segment. */
|
/** A four bit value describing the type of the segment. */
|
||||||
enum class Type {
|
enum class Type {
|
||||||
// Data segment types
|
// Data segment types
|
||||||
|
@ -41,13 +51,18 @@ enum class Type {
|
||||||
CodeEXRCA = 0xf // Execute/read, conforming, accessed
|
CodeEXRCA = 0xf // Execute/read, conforming, accessed
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* SegmentDescriptors are entries in the GDT and LDT that describe memory
|
|
||||||
* segments. Each descriptor is two double-words (8 bytes, 64 bits) long.
|
|
||||||
*/
|
|
||||||
typedef uint64_t SegmentDescriptor;
|
|
||||||
|
|
||||||
SegmentDescriptor sGDT[4];
|
/** Six byte field containing the length and a linear address where the GDT lives. */
|
||||||
|
struct GDTPointer
|
||||||
|
{
|
||||||
|
uint16_t limit;
|
||||||
|
uint32_t base;
|
||||||
|
} __attribute((__packed__));
|
||||||
|
|
||||||
|
|
||||||
|
static const size_t GDTSize = 5;
|
||||||
|
static SegmentDescriptor sGDT[GDTSize];
|
||||||
|
|
||||||
|
|
||||||
static inline SegmentDescriptor
|
static inline SegmentDescriptor
|
||||||
createSegmentDescriptor(uint32_t base,
|
createSegmentDescriptor(uint32_t base,
|
||||||
|
@ -81,4 +96,39 @@ createSegmentDescriptor(uint32_t base,
|
||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Static
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
initGDT()
|
||||||
|
{
|
||||||
|
sGDT[0] = 0; // First descriptor is always NULL.
|
||||||
|
sGDT[1] = createSegmentDescriptor(0x00000000, 0x000FFFFF, Type::CodeEXR, DPL::Ring0);
|
||||||
|
sGDT[2] = createSegmentDescriptor(0x00000000, 0x000FFFFF, Type::DataRW, DPL::Ring0);
|
||||||
|
sGDT[3] = 0; // Unused for now.
|
||||||
|
sGDT[4] = 0; // Unused for now.
|
||||||
|
|
||||||
|
GDTPointer gdt {GDTSize * sizeof(SegmentDescriptor) - 1, uint32_t(&sGDT)};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load the new GDT with the pointer defined above. The GDT isn't actually
|
||||||
|
* used until the segment registers are reladed. Below, CS is reloaded by
|
||||||
|
* a long jump into the new code segment. The rest of the segment registers
|
||||||
|
* can be loaded directly.
|
||||||
|
*/
|
||||||
|
asm volatile(
|
||||||
|
"lgdt %0\n"
|
||||||
|
"ljmpl $0x08, $reloadSegments\n"
|
||||||
|
"reloadSegments:\n"
|
||||||
|
"movl $0x10, %%eax\n"
|
||||||
|
"movl %%eax, %%ds\n"
|
||||||
|
"movl %%eax, %%es\n"
|
||||||
|
"movl %%eax, %%fs\n"
|
||||||
|
"movl %%eax, %%gs\n"
|
||||||
|
"movl %%eax, %%ss\n"
|
||||||
|
: : "m" (gdt)
|
||||||
|
: "%eax");
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace kernel */
|
} /* namespace kernel */
|
||||||
|
|
12
src/Descriptors.hh
Normal file
12
src/Descriptors.hh
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/* Descriptors.hh vim: set tw=80: Eryn Wells <eryn@erynwells.me>
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Declaration of relevant classes and functions for dealing with the GDT and
|
||||||
|
* IDT.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace kernel {
|
||||||
|
|
||||||
|
void initGDT();
|
||||||
|
|
||||||
|
} /* namespace kernel */
|
|
@ -1,6 +1,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "Console.hh"
|
#include "Console.hh"
|
||||||
|
#include "Descriptors.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,6 +20,8 @@ kearly()
|
||||||
console.clear(kernel::Console::Color::Blue);
|
console.clear(kernel::Console::Color::Blue);
|
||||||
console.writeString("Loading system ...\n");
|
console.writeString("Loading system ...\n");
|
||||||
|
|
||||||
|
kernel::initGDT();
|
||||||
|
|
||||||
volatile int foo = 0;
|
volatile int foo = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue