I added some work on a keyboard driver here also changed the emulation system, since bochs was giving me headaches when it came to keyboard input added some todo stuff.. probably some cleanup, idk
80 lines
2.0 KiB
C
80 lines
2.0 KiB
C
#include <kernel/x86/gdt.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
|
|
#ifdef __TESTING__
|
|
#include <kernel/_kernel.h>
|
|
#endif
|
|
|
|
/**
|
|
* What is this file?
|
|
*
|
|
* Well, to properly set up a lot of the system, we need something called a GDT
|
|
* or, a Global Descriptor Table.
|
|
*
|
|
* This table, establishes a few things.
|
|
*
|
|
* Mainly it sets 4 segments,
|
|
* A kernel code segment, with RING 0 permissions
|
|
* A kernel data segment, with RING 0 permissions
|
|
* A user code segment, with RING 3 permissions
|
|
* A user data segment, with RING 3 permissions
|
|
*
|
|
* This allows for future userspace to properly segment code and data,
|
|
* anything in userspace shouldn't have access to hardware like the kernel does
|
|
* So by passing through this GDT, we can dish out authority to access certain data, functions,
|
|
* etc, by going through the CPU permission system (RING 0 - 3)
|
|
*/
|
|
|
|
uint64_t gdt[GDT_SIZE];
|
|
|
|
uint64_t create_descriptor(uint32_t base, uint32_t limit, uint16_t flag)
|
|
{
|
|
uint64_t descriptor;
|
|
|
|
descriptor = limit & 0x000F0000;
|
|
descriptor |= (flag << 8) & 0x00F0FF00;
|
|
descriptor |= (base >> 16) & 0x000000FF;
|
|
descriptor |= base & 0xFF000000;
|
|
|
|
descriptor <<= 32;
|
|
|
|
descriptor |= base << 16;
|
|
descriptor |= limit & 0x0000FFFF;
|
|
|
|
return descriptor;
|
|
}
|
|
|
|
#ifdef __TESTING__
|
|
void dump_gdt(void)
|
|
{
|
|
for (int i = 0; i < GDT_SIZE; i++) {
|
|
printf("GDT_ENTRY %d: %4 | %2\n", i, gdt[i], gdt[i]);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
void gdt_init(void)
|
|
{
|
|
#ifdef __TESTING__
|
|
kinfo("Initializing the GDT");
|
|
#endif
|
|
gdt[0] = create_descriptor(0, 0, 0); // null
|
|
gdt[1] = create_descriptor(0, 0x000FFFFF, (GDT_CODE_PL0)); // kernel code
|
|
gdt[2] = create_descriptor(0, 0x000FFFFF, (GDT_DATA_PL0)); // kernel data
|
|
//gdt[3] = create_descriptor(0, 0x000FFFFF, (GDT_CODE_PL3)); // user code
|
|
//gdt[4] = create_descriptor(0, 0x000FFFFF, (GDT_DATA_PL3)); // user data
|
|
|
|
setGdt((sizeof(uint64_t) * GDT_SIZE) - 1, &(gdt[0])); // limit, base
|
|
reloadSegments();
|
|
#ifdef __TESTING__
|
|
kinfo("Initialized the GDT");
|
|
#endif
|
|
#ifdef __TESTING__
|
|
dump_gdt();
|
|
#endif
|
|
}
|
|
|
|
|