Files
freywaros/src/kernel/gdt.c
T
2026-06-11 20:19:24 +03:00

68 lines
2.0 KiB
C

#include "src/kernel/gdt.h"
#include "src/kernel/tss.h"
typedef struct {
uint16_t limit_low;
uint16_t base_low;
uint8_t base_mid;
uint8_t access;
uint8_t flags_limit_high;
uint8_t base_high;
} __attribute__((packed)) gdt_entry_t;
typedef struct {
gdt_entry_t base;
uint32_t base_upper;
uint32_t reserved;
} __attribute__((packed)) gdt_system_entry_t;
typedef struct {
gdt_entry_t gdt[6];
gdt_system_entry_t tss_entry;
} __attribute__((packed)) gdt_table_t;
typedef struct {
uint16_t limit;
uint64_t offset;
} __attribute__((packed)) gdt_descriptor_t;
static gdt_table_t gdt;
static gdt_descriptor_t desc;
static void set_entry(gdt_entry_t *e, uint8_t access, uint8_t flags) {
e->limit_low = 0xFFFF;
e->base_low = 0;
e->base_mid = 0;
e->access = access;
e->flags_limit_high = flags | 0x0F;
e->base_high = 0;
}
static void set_tss_entry(void *base) {
uint64_t ibase = (uint64_t)base;
gdt.tss_entry.base.limit_low = sizeof(tss_t) - 1;
gdt.tss_entry.base.base_low = ibase & 0xFFFF;
gdt.tss_entry.base.base_mid = (ibase >> 16) & 0xFF;
gdt.tss_entry.base.access = 0x89; // present, type=TSS available
gdt.tss_entry.base.flags_limit_high = 0x00;
gdt.tss_entry.base.base_high = (ibase >> 24) & 0xFF;
gdt.tss_entry.base_upper = ibase >> 32;
gdt.tss_entry.reserved = 0;
}
void gdt_init() {
gdt.gdt[0] = (gdt_entry_t){0};
set_entry(&gdt.gdt[1], 0x9A, 0xCF); // present, ring 0, code, executable, readable, 32-bit, 4KB granularity
set_entry(&gdt.gdt[2], 0x9A, 0xA0); // present, ring 0, code, executable, readable, 64-bit
set_entry(&gdt.gdt[3], 0x92, 0x00); // present, ring 0, data, writable
set_entry(&gdt.gdt[4], 0xF2, 0x00); // present, ring 3, data, writable
set_entry(&gdt.gdt[5], 0xFA, 0xA0); // present, ring 3, code, executable, readable, 64-bit
set_tss_entry(&tss);
desc.limit = sizeof(gdt) - 1;
desc.offset = (uint64_t)&gdt;
__asm__ volatile("lgdt %0" : : "m"(desc));
__asm__ volatile("ltr %0" : : "r"((uint16_t)TSS_SEL));
}