aboutsummaryrefslogtreecommitdiff
path: root/src/gdt.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gdt.h')
-rw-r--r--src/gdt.h66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/gdt.h b/src/gdt.h
new file mode 100644
index 0000000..99a6da2
--- /dev/null
+++ b/src/gdt.h
@@ -0,0 +1,66 @@
+#pragma once
+
+#include <types.h>
+
+/* From OSDev wiki:
+ *
+ * Segment
+ * a logically contiguous chunk of memory with consistent properties (CPU's speaking)
+ *
+ * Segment Register
+ * a register of your CPU that refers to a segment for a special use (e.g. SS, CS, DS ...)
+ *
+ * Selector
+ * a reference to a descriptor you can load into a segment register; the selector is an offset of a descriptor table
+ * entry. These entries are 8 bytes long. Therefore, bits 3 and up only declare the descriptor table entry offset, while
+ * bit 2 specifies if this selector is a GDT or LDT selector (LDT - bit set, GDT - bit cleared), and bits 0 - 1 declare
+ * the ring level that needs to correspond to the descriptor table entry's DPL field. If it doesn't, a General
+ * Protection Fault occurs; if it does correspond then the CPL level of the selector used is changed accordingly.
+ *
+ * Descriptor
+ * a memory structure (part of a table) that tells the CPU the attributes of a given segment
+ */
+
+class GDT {
+public:
+ GDT();
+ ~GDT() = default;
+
+ struct Pointer {
+ uint16_t limit;
+ uint32_t base;
+ } __attribute((packed));
+
+ class SegmentDescriptor {
+ public:
+ SegmentDescriptor(uint32_t base = 0, uint32_t limit = 0, uint8_t type = 0);
+ [[nodiscard]] uint32_t base() const;
+ [[nodiscard]] uint32_t limit() const;
+
+ private:
+ /*
+ * |31| | | | | | |24|23|22| |20|19| | |16|15| | |12|11| | | 8| 7| | | | | | | 0|
+ * | base (24~31) | G|DB| | A| lim(16~19)| P| DPL | S| Type | base (16~23) |
+ * | base (0~15) | limit (0~15) |
+ * |31| | | | | | | | | | | | | | |16|15| | | | | | | | | | | | | | | 0|
+ *
+ * limit size of segment - 1, either in bytes or in 4KiB chunks (check flags)
+ * base address of segment
+ * access
+ * flags defines the segment chunks and 16/32 bit
+ */
+
+ uint16_t limit_low;
+ uint16_t base_low;
+ uint8_t base_high;
+ uint8_t type;
+ uint8_t flags_limit_high;
+ uint8_t base_vhigh;
+ } __attribute__((packed));
+
+private:
+ SegmentDescriptor segments[256];
+};
+
+static_assert(sizeof(GDT::Pointer) == 6);
+static_assert(sizeof(GDT::SegmentDescriptor) == 8);