diff options
Diffstat (limited to 'src/gdt.h')
-rw-r--r-- | src/gdt.h | 66 |
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); |