117 lines
2.3 KiB
C
117 lines
2.3 KiB
C
#include "gdt.h"
|
|
|
|
static struct gdt gdt = { 0 };
|
|
|
|
static void create_kernel_ds(void)
|
|
{
|
|
struct gdt_entry *entry = gdt.entries + KERNEL_DS_INDEX;
|
|
|
|
uint32_t limit = 0xfffff;
|
|
uint32_t base = 0x0;
|
|
|
|
entry->granularity = 1;
|
|
entry->db = 1;
|
|
entry->l = 0;
|
|
entry->available = 0;
|
|
|
|
entry->present = 1;
|
|
entry->desc_priv = 0;
|
|
entry->desc_type = 1;
|
|
entry->ex = 0;
|
|
entry->dc = 0;
|
|
entry->rw = 1;
|
|
entry->accessed = 0;
|
|
|
|
entry->limit_1 = limit & 0xffff;
|
|
entry->limit_2 = (limit >> 16) & 0xf;
|
|
|
|
entry->base_1 = base & 0xffff;
|
|
entry->base_2 = (base >> 16) & 0xff;
|
|
entry->base_3 = (base >> 24) & 0xff;
|
|
}
|
|
|
|
static void create_kernel_cs(void)
|
|
{
|
|
struct gdt_entry *entry = gdt.entries + KERNEL_CS_INDEX;
|
|
|
|
uint32_t limit = 0xfffff;
|
|
uint32_t base = 0x0;
|
|
|
|
entry->granularity = 1;
|
|
entry->db = 1;
|
|
entry->l = 0;
|
|
entry->available = 0;
|
|
|
|
entry->present = 1;
|
|
entry->desc_priv = 0;
|
|
entry->desc_type = 1;
|
|
entry->ex = 1;
|
|
entry->dc = 0;
|
|
entry->rw = 1;
|
|
entry->accessed = 0;
|
|
|
|
entry->limit_1 = limit & 0xffff;
|
|
entry->limit_2 = (limit >> 16) & 0xf;
|
|
|
|
entry->base_1 = base & 0xffff;
|
|
entry->base_2 = (base >> 16) & 0xff;
|
|
entry->base_3 = (base >> 24) & 0xff;
|
|
}
|
|
|
|
static void create_gdt(void)
|
|
{
|
|
create_kernel_ds();
|
|
create_kernel_cs();
|
|
}
|
|
|
|
static void load_gdt(void)
|
|
{
|
|
struct gdt_r gdtr;
|
|
gdtr.addr = (uint32_t)&gdt;
|
|
gdtr.limit = GDT_SIZE - 1;
|
|
|
|
asm volatile("lgdt %0\n"
|
|
:
|
|
: "m" (gdtr)
|
|
: "memory");
|
|
}
|
|
|
|
static void load_ds(void)
|
|
{
|
|
struct segment_selector selector = KERNEL_DS_SEGMENT_SELECTOR;
|
|
|
|
asm volatile("movw %0, %%ax\n"
|
|
"movw %%ax, %%ds\n"
|
|
"movw %%ax, %%fs\n"
|
|
"movw %%ax, %%gs\n"
|
|
"movw %%ax, %%ss\n"
|
|
:
|
|
: "m" (selector)
|
|
: "ax");
|
|
}
|
|
|
|
static void load_cs(void)
|
|
{
|
|
struct segment_selector selector = KERNEL_CS_SEGMENT_SELECTOR;
|
|
|
|
asm volatile("pushl %0\n"
|
|
"pushl $1f\n"
|
|
"lret\n"
|
|
"1:\n"
|
|
:
|
|
: "m" (selector));
|
|
}
|
|
|
|
static void reload_segment_selectors(void)
|
|
{
|
|
load_ds();
|
|
load_cs();
|
|
}
|
|
|
|
void init_gdt(void)
|
|
{
|
|
create_gdt();
|
|
load_gdt();
|
|
reload_segment_selectors();
|
|
}
|