diff --git a/src/gdt.cpp b/src/gdt.cpp index e69de29..9c105c0 100644 --- a/src/gdt.cpp +++ b/src/gdt.cpp @@ -0,0 +1,32 @@ +#include "gdt.h" + +#define _64_MEGABYTES 64*1024*1024 +#define CSS_FLAGS 0x9A +#define DSS_FLAGS 0x92 +#define EXPECTED_BYTES_NUM 2 +#define GDT_ADDRESS 0 +#define SEGMENT_INTEGER_HIGH_BYTES 1 +#define HIGH_BYTES_LSHIFT 16 + +GlobalDescriptorTable::GlobalDescriptorTable() +: nullSegmentSelector(0, 0, 0), unusedSegmentSelector(0, 0, 0), +codeSegmentSelector(0, _64_MEGABYTES, CSS_FLAGS), +dataSegmentSelector(0, _64_MEGABYTES, DSS_FLAGS) { + + uint32_t expectedBytes[EXPECTED_BYTES_NUM]; + expectedBytes[GDT_ADDRESS] = (uint32_t)this; + expectedBytes[SEGMENT_INTEGER_HIGH_BYTES] = sizeof(GlobalDescriptorTable) << HIGH_BYTES_LSHIFT; + + asm volatile("lgdt (%0)": :"p" (((uint8_t*) expectedBytes+2))); +} + +// TODO: Unload the GDT. +GlobalDescriptorTable::~GlobalDescriptorTable(){} + +uint16_t GlobalDescriptorTable::GetDataSegmentSelectorOffset(){ + return (uint8_t*)&dataSegmentSelector - (uint8_t*)this; +} + +uint16_t GlobalDescriptorTable::GetCodeSegmentSelectorOffset() { + return (uint8_t*)&codeSegmentSelector - (uint8_t*)this; +} diff --git a/src/gdt.h b/src/gdt.h index b7bc83f..c5ebec3 100644 --- a/src/gdt.h +++ b/src/gdt.h @@ -22,7 +22,28 @@ class GlobalDescriptorTable { uint8_t access; uint8_t flags_and_limit_high_halfbyte; uint8_t base_highbyte_high; + + public: + SegmentDescriptor(uint32_t base, uint32_t limit, uint8_t access); + uint32_t GetBase(); + uint32_t GetLimit(); + } __attribute__((packed)); + + SegmentDescriptor nullSegmentSelector; + SegmentDescriptor unusedSegmentSelector; + // TODO: This is only an MVP, there should NOT be only 1 code and data segment, + // right now they spread through the whole memory, but this is a huge + // security vulnerability. + SegmentDescriptor codeSegmentSelector; + SegmentDescriptor dataSegmentSelector; + + GlobalDescriptorTable(); + ~GlobalDescriptorTable(); + + uint16_t GetCodeSegmentSelectorOffset(); + uint16_t GetDataSegmentSelectorOffset(); + }; #endif diff --git a/src/types.h b/src/types.h index 2e5500a..2a9e820 100644 --- a/src/types.h +++ b/src/types.h @@ -21,6 +21,6 @@ typedef int int32_t; typedef unsigned int uint32_t; typedef long long int int64_t; -typedef unsigned long long int uin64_t; +typedef unsigned long long int uint64_t; #endif