banan-os/kernel/arch/i386/GDT.cpp

61 lines
1.2 KiB
C++
Raw Normal View History

2022-11-16 19:49:09 +02:00
#include <kernel/GDT.h>
#include <kernel/kmalloc.h>
struct GDTR
{
uint16_t size;
void* address;
} __attribute__((packed));
static GDTR s_gdtr;
static SegmentDesriptor* s_gdt;
2022-12-07 02:41:18 +02:00
extern "C" void load_gdt(void* gdt_ptr);
asm(
".global load_gdt;"
"load_gdt:"
"movl 4(%esp),%eax;"
"lgdt (%eax);"
"movw $0x10, %ax;"
"movw %ax, %ds;"
"movw %ax, %es;"
"movw %ax, %fs;"
"movw %ax, %gs;"
"movw %ax, %ss;"
"jmp $0x08,$flush;"
"flush:"
"ret;"
);
2022-12-07 02:41:18 +02:00
void write_gdt_entry_raw(uint8_t segment, uint32_t low, uint32_t high)
2022-11-16 19:49:09 +02:00
{
2022-12-07 02:41:18 +02:00
uint8_t index = segment >> 3;
2022-11-16 19:49:09 +02:00
s_gdt[index].low = low;
s_gdt[index].high = high;
}
2022-12-07 02:41:18 +02:00
void write_gdt_entry(uint8_t segment, SegmentDesriptor descriptor)
2022-11-16 19:49:09 +02:00
{
2022-12-07 02:41:18 +02:00
write_gdt_entry_raw(segment, descriptor.low, descriptor.high);
2022-11-16 19:49:09 +02:00
}
void gdt_initialize()
{
2022-12-07 02:41:18 +02:00
constexpr uint8_t GDT_SIZE = 5;
s_gdt = new SegmentDesriptor[GDT_SIZE];
2022-11-16 19:49:09 +02:00
s_gdtr.address = s_gdt;
2022-12-07 02:41:18 +02:00
s_gdtr.size = GDT_SIZE * 8 - 1;
write_gdt_entry(0x00, { 0, 0x00000, 0x00, 0x0 }); // null
write_gdt_entry(0x08, { 0, 0xFFFFF, 0x9A, 0xC }); // kernel code
write_gdt_entry(0x10, { 0, 0xFFFFF, 0x92, 0xC }); // kernel data
write_gdt_entry(0x18, { 0, 0xFFFFF, 0xFA, 0xC }); // user code
write_gdt_entry(0x20, { 0, 0xFFFFF, 0xF2, 0xC }); // user data
2022-11-16 19:49:09 +02:00
2022-12-07 02:41:18 +02:00
load_gdt(&s_gdtr);
2022-11-16 19:49:09 +02:00
}