#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(); }