diff --git a/prototypes/base/Makefile b/prototypes/base/Makefile index eb84f45..08ef646 100644 --- a/prototypes/base/Makefile +++ b/prototypes/base/Makefile @@ -45,7 +45,7 @@ kernel-base.ker: $(OBJS) run: - qemu-system-i386 -kernel kernel-base.ker + qemu-system-i386 -kernel kernel-base.ker -m 64 bnr: kernel-base.ker run diff --git a/prototypes/base/include/gdt.hpp b/prototypes/base/include/gdt.hpp new file mode 100644 index 0000000..a60948d --- /dev/null +++ b/prototypes/base/include/gdt.hpp @@ -0,0 +1,83 @@ +#pragma once + +#include + +enum class SegmentAccess : uint8_t +{ + None = 0, + Accessed = (1 << 0), + + Readable = (1<<1), + Writable = (1<<1), + + Direction = (1<<2), + Conforming = (1<<2), + + Executable = (1 << 3), + Segment = (1 << 4), + + Ring0 = 0, + Ring1 = (1<<5), + Ring2 = (1<<6), + Ring3 = (1<<5) | (1<<6), + + Present = (1 << 7), +}; + +static inline SegmentAccess operator | (SegmentAccess lhs, SegmentAccess rhs) +{ + return static_cast(static_cast(lhs) | static_cast(rhs)); +} + +static inline SegmentAccess operator & (SegmentAccess lhs, SegmentAccess rhs) +{ + return static_cast(static_cast(lhs) & static_cast(rhs)); +} + +struct SegmentDescriptor +{ + uint16_t limit0; + uint16_t base0; + uint8_t base1; + SegmentAccess access; + uint8_t limit1 : 4; + uint8_t flags : 4; + uint8_t base2; + + uint32_t limit() + { + return this->limit0 | (this->limit1 << 16); + } + + void setLimit(uint32_t value) + { + this->limit0 = (value & 0x0FFFF) >> 0; + this->limit1 = (value & 0xFFFFF) >> 16; + } + + uint32_t base() + { + return this->base0 | (this->base1 << 16) | (this->base2 << 24); + } + + void setBase(uint32_t value) + { + this->base0 = (value & 0x0000FFFF) >> 0; + this->base1 = (value & 0x00FF0000) >> 16; + this->base2 = (value & 0xFF000000) >> 24; + } +} __attribute__((packed)); + +static_assert(sizeof(SegmentDescriptor) == 8, "SegmentDescriptor must be 8 bytes large."); + +class GDT +{ +public: + static const uint32_t length = 8; +private: + static SegmentDescriptor descriptors[length]; + GDT() = delete; +public: + + static SegmentDescriptor & descriptor(uint32_t index); +}; \ No newline at end of file diff --git a/prototypes/base/src/gdt.cpp b/prototypes/base/src/gdt.cpp new file mode 100644 index 0000000..099bc03 --- /dev/null +++ b/prototypes/base/src/gdt.cpp @@ -0,0 +1,12 @@ +#include "gdt.hpp" + +SegmentDescriptor GDT::descriptors[GDT::length]; + +SegmentDescriptor & GDT::descriptor(uint32_t index) +{ + static SegmentDescriptor invalid; + if(index >= GDT::length) { + return invalid; + } + return GDT::descriptors[index]; +} \ No newline at end of file