mirror of
https://github.com/Tom-on64/kern.git
synced 2026-11-03 18:22:22 +00:00
The great 64-bit rewrite
* We did loose tasking and only have a paging skeleton, but hey it took like 4 months so i'm happy that there's something :p
This commit is contained in:
+85
-33
@@ -2,54 +2,106 @@
|
||||
#include <string.h>
|
||||
#include <gdt.h>
|
||||
|
||||
static struct gdt_entry gdt[GDT_ENTRIES];
|
||||
static struct gdt_entries gdt;
|
||||
static struct gdt_pointer gdtp;
|
||||
static struct tss_pointer tss;
|
||||
|
||||
void gdt_reload(void) {
|
||||
__asm__ volatile (
|
||||
"cli\n"
|
||||
"lgdt (%0)\n"
|
||||
"movw $0x10, %%ax\n"
|
||||
"movw %%ax, %%ds\n"
|
||||
"movw %%ax, %%es\n"
|
||||
"movw %%ax, %%fs\n"
|
||||
"movw %%ax, %%gs\n"
|
||||
"movw %%ax, %%ss\n"
|
||||
"ljmp $0x08, $1f\n"
|
||||
"1:"
|
||||
:
|
||||
: "m" (gdtp)
|
||||
: "memory", "rax"
|
||||
"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_reload(void) {
|
||||
__asm__ volatile ("ltr %0" : : "rm"(GDT_TSS));
|
||||
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");
|
||||
}
|
||||
|
||||
void tss_esp0(uint32_t esp0) { tss.esp0 = esp0; }
|
||||
|
||||
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 = (uint32_t)&gdt;
|
||||
|
||||
// Setup TSS
|
||||
memset(&tss, 0, sizeof(tss));
|
||||
tss.ss0 = GDT_KERNEL_DATA;
|
||||
tss.iopb = sizeof(struct tss_pointer);
|
||||
|
||||
// Load descriptors
|
||||
gdt[0] = GDT_DESC(0, 0, 0, 0); // Null descriptor
|
||||
gdt[1] = GDT_DESC(0xFFFFFFFF, 0, 0x9A, 0xC0); // Kernel code
|
||||
gdt[2] = GDT_DESC(0xFFFFFFFF, 0, 0x92, 0xC0); // Kernel data
|
||||
gdt[3] = GDT_DESC(0xFFFFFFFF, 0, 0xFA, 0xC0); // User code
|
||||
gdt[4] = GDT_DESC(0xFFFFFFFF, 0, 0xF2, 0xC0); // User data
|
||||
gdt[5] = GDT_DESC(sizeof(tss) - 1, (uint32_t)&tss, 0x89, 0);
|
||||
gdtp.base = (uint64_t)&gdt;
|
||||
|
||||
gdt_reload();
|
||||
tss_reload();
|
||||
|
||||
memset(&tss, 0, sizeof(tss));
|
||||
tss_load(&tss);
|
||||
|
||||
debugf("[gdt] GDT loaded.\n");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user