diff options
Diffstat (limited to 'src/gdt.c')
-rw-r--r-- | src/gdt.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/gdt.c b/src/gdt.c new file mode 100644 index 0000000..22489ac --- /dev/null +++ b/src/gdt.c @@ -0,0 +1,44 @@ +#include <gdt.h> + +struct gdt_entry { + uint16_t limit_low; + uint16_t base_low; + uint8_t base_middle_low; + uint8_t access; + uint8_t gran; + uint8_t base_middle_high; + uint32_t base_high; + uint32_t reseved; +} __attribute__((packed)); + +struct gdt { + uint16_t limit; + uint64_t base; +} __attribute__((packed)); + +struct gdt_entry gdt[3]; +struct gdt gdt_ptr; + +extern void gdt_flush(); + +void gdt_set_gate(size_t num, uint64_t base, uint32_t limit, uint8_t access, uint8_t gran) { + gdt[num] = (struct gdt_entry) { + .base_low = base & 0xFFFF, + .base_middle_low = (base >> 16) & 0xFF, + .base_middle_high = (base >> 24) & 0xFF, + .base_high = (base >> 32) & 0xFFFFFFFF, + .limit_low = limit & 0xFFFF, + .gran = ((limit >> 16) & 0x0F) | (gran & 0xF0), + .access = access + }; +} + +void gdt_install() { + gdt_ptr.limit = (sizeof(struct gdt_entry) * 3) - 1; + gdt_ptr.base = (uint64_t) &gdt; + + gdt_set_gate(0, 0, 0, 0, 0); + gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); + gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); + gdt_flush(); +} |