mirror of
https://github.com/Tom-on64/kern.git
synced 2026-11-03 18:22:22 +00:00
110 lines
2.3 KiB
C
110 lines
2.3 KiB
C
#include <kernel.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <gdt.h>
|
|
|
|
static struct gdt_entries gdt;
|
|
static struct gdt_pointer gdtp;
|
|
static struct tss_pointer tss;
|
|
|
|
void gdt_reload(void) {
|
|
__asm__ volatile (
|
|
"lgdt %0\n"
|
|
"pushq %[kcs]\n"
|
|
"lea 1f(%%rip), %%rax\n"
|
|
"pushq %%rax\n"
|
|
"lretq\n"
|
|
"1:\n"
|
|
"mov %[kds], %%ax\n"
|
|
"mov %%ax, %%ds\n"
|
|
"mov %%ax, %%es\n"
|
|
"mov %%ax, %%fs\n"
|
|
"mov %%ax, %%gs\n"
|
|
"mov %%ax, %%ss\n"
|
|
:
|
|
: "m"(gdtp),
|
|
[kcs] "i"(GDT_KERNEL_CODE),
|
|
[kds] "i"(GDT_KERNEL_DATA)
|
|
: "rax", "memory"
|
|
);
|
|
}
|
|
|
|
void tss_load(struct tss_pointer* tss) {
|
|
size_t addr = (size_t)tss;
|
|
|
|
gdt.tss.length = 104;
|
|
gdt.tss.base_low = (uint16_t)addr;
|
|
gdt.tss.base_mid = (uint8_t)(addr >> 16);
|
|
gdt.tss.access = 0x89;
|
|
gdt.tss.flags = 0;
|
|
gdt.tss.base_high = (uint8_t)(addr >> 24);
|
|
gdt.tss.base_upper32 = (uint32_t)(addr >> 32);
|
|
gdt.tss.__reserved = 0;
|
|
|
|
__asm__ volatile ("ltr %0" : : "rm"(GDT_TSS) : "memory");
|
|
}
|
|
|
|
int gdt_init(void) {
|
|
// Null descriptor
|
|
gdt.entries[0].limit = 0;
|
|
gdt.entries[0].base_low = 0;
|
|
gdt.entries[0].base_mid = 0;
|
|
gdt.entries[0].access = 0;
|
|
gdt.entries[0].flags = 0;
|
|
gdt.entries[0].base_high = 0;
|
|
|
|
// Kernel code
|
|
gdt.entries[1].limit = 0xFFFF;
|
|
gdt.entries[1].base_low = 0;
|
|
gdt.entries[1].base_mid = 0;
|
|
gdt.entries[1].access = 0x9A;
|
|
gdt.entries[1].flags = 0xAF;
|
|
gdt.entries[1].base_high = 0;
|
|
|
|
// Kernel data
|
|
gdt.entries[2].limit = 0xFFFF;
|
|
gdt.entries[2].base_low = 0;
|
|
gdt.entries[2].base_mid = 0;
|
|
gdt.entries[2].access = 0x92;
|
|
gdt.entries[2].flags = 0xCF;
|
|
gdt.entries[2].base_high = 0;
|
|
|
|
// User data
|
|
gdt.entries[3].limit = 0xFFFF;
|
|
gdt.entries[3].base_low = 0;
|
|
gdt.entries[3].base_mid = 0;
|
|
gdt.entries[3].access = 0xF2;
|
|
gdt.entries[3].flags = 0xCF;
|
|
gdt.entries[3].base_high = 0;
|
|
|
|
// User code
|
|
gdt.entries[4].limit = 0xFFFF;
|
|
gdt.entries[4].base_low = 0;
|
|
gdt.entries[4].base_mid = 0;
|
|
gdt.entries[4].access = 0xFA;
|
|
gdt.entries[4].flags = 0xAF;
|
|
gdt.entries[4].base_high = 0;
|
|
|
|
// Task State Segment (TSS)
|
|
gdt.tss.length = 104;
|
|
gdt.tss.base_low = 0;
|
|
gdt.tss.base_mid = 0;
|
|
gdt.tss.access = 0x89; //0b10001001;
|
|
gdt.tss.flags = 0;
|
|
gdt.tss.base_high = 0;
|
|
gdt.tss.base_upper32 = 0;
|
|
gdt.tss.__reserved = 0;
|
|
|
|
// GDT Pointer
|
|
gdtp.limit = sizeof(gdt) - 1;
|
|
gdtp.base = (uint64_t)&gdt;
|
|
|
|
gdt_reload();
|
|
|
|
memset(&tss, 0, sizeof(tss));
|
|
tss_load(&tss);
|
|
|
|
return SUCCESS;
|
|
}
|
|
|