From 46e5b3f3d6de3de664a17fb39c8b23909ae55145 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Mon, 16 Jan 2023 15:24:10 +0200 Subject: [PATCH] Kernel: Move GDT to its own namespace and cleanup --- kernel/arch/i386/GDT.cpp | 148 +++++++++++++++++++++++++----------- kernel/include/kernel/GDT.h | 54 +------------ kernel/kernel/kernel.cpp | 2 +- 3 files changed, 107 insertions(+), 97 deletions(-) diff --git a/kernel/arch/i386/GDT.cpp b/kernel/arch/i386/GDT.cpp index 259442ea7..60301af53 100644 --- a/kernel/arch/i386/GDT.cpp +++ b/kernel/arch/i386/GDT.cpp @@ -1,56 +1,114 @@ #include -#include -struct GDTR +#include + + +namespace GDT { - uint16_t size; - void* address; -} __attribute__((packed)); -static GDTR s_gdtr; -static SegmentDesriptor s_gdt[5]; + union SegmentDesriptor + { + struct + { + uint16_t limit_lo; + uint16_t base_lo; + uint8_t base_hi1; -extern "C" void load_gdt(void* gdt_ptr); -asm( -".global load_gdt;" -"load_gdt:" - "movl 4(%esp),%eax;" - "lgdt (%eax);" + uint8_t type : 4; + uint8_t system : 1; + uint8_t DPL : 2; + uint8_t present : 1; - "movw $0x10, %ax;" - "movw %ax, %ds;" - "movw %ax, %es;" - "movw %ax, %fs;" - "movw %ax, %gs;" - "movw %ax, %ss;" - "jmp $0x08,$flush;" + uint8_t limit_hi : 4; + uint8_t flags : 4; -"flush:" - "ret;" -); + uint8_t base_hi2; + } __attribute__((packed)); + + struct + { + uint32_t low; + uint32_t high; + } __attribute__((packed)); -void write_gdt_entry_raw(uint8_t segment, uint32_t low, uint32_t high) -{ - uint8_t index = segment >> 3; - s_gdt[index].low = low; - s_gdt[index].high = high; -} + SegmentDesriptor() : low(0), high(0) {} + SegmentDesriptor(uint32_t base, uint32_t limit, uint8_t access, uint8_t _flags) + : low(0), high(0) + { + set_base(base); + set_limit(limit); -void write_gdt_entry(uint8_t segment, SegmentDesriptor descriptor) -{ - write_gdt_entry_raw(segment, descriptor.low, descriptor.high); -} + high |= ((uint16_t)access) << 8; + flags = _flags; + } -void gdt_initialize() -{ - s_gdtr.address = s_gdt; - s_gdtr.size = sizeof(s_gdt) - 1; + void set_base(uint32_t base) + { + base_lo = base & 0xFFFF; + base_hi1 = (base >> 16) & 0x00FF; + base_hi2 = (base >> 24) & 0x00FF; + } - 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 - - load_gdt(&s_gdtr); -} + void set_limit(uint32_t limit) + { + limit_lo = limit & 0xFFFF; + limit_hi = (limit >> 16) & 0x00FF; + } + + } __attribute__((packed)); + + struct GDTR + { + uint16_t size; + void* address; + } __attribute__((packed)); + + static GDTR s_gdtr; + static SegmentDesriptor s_gdt[5]; + + 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;" + ); + + void write_entry_raw(uint8_t segment, uint32_t low, uint32_t high) + { + uint8_t index = segment >> 3; + s_gdt[index].low = low; + s_gdt[index].high = high; + } + + void write_entry(uint8_t segment, SegmentDesriptor descriptor) + { + write_entry_raw(segment, descriptor.low, descriptor.high); + } + + void initialize() + { + s_gdtr.address = s_gdt; + s_gdtr.size = sizeof(s_gdt) - 1; + + write_entry(0x00, { 0, 0x00000, 0x00, 0x0 }); // null + write_entry(0x08, { 0, 0xFFFFF, 0x9A, 0xC }); // kernel code + write_entry(0x10, { 0, 0xFFFFF, 0x92, 0xC }); // kernel data + write_entry(0x18, { 0, 0xFFFFF, 0xFA, 0xC }); // user code + write_entry(0x20, { 0, 0xFFFFF, 0xF2, 0xC }); // user data + + load_gdt(&s_gdtr); + } + +} \ No newline at end of file diff --git a/kernel/include/kernel/GDT.h b/kernel/include/kernel/GDT.h index 6f355b8dd..9e23c4b21 100644 --- a/kernel/include/kernel/GDT.h +++ b/kernel/include/kernel/GDT.h @@ -1,56 +1,8 @@ #pragma once -#include - -union SegmentDesriptor +namespace GDT { - struct - { - uint16_t limit_lo; - uint16_t base_lo; - uint8_t base_hi1; - uint8_t type : 4; - uint8_t system : 1; - uint8_t DPL : 2; - uint8_t present : 1; + void initialize(); - uint8_t limit_hi : 4; - uint8_t flags : 4; - - uint8_t base_hi2; - }; - - struct - { - uint32_t low; - uint32_t high; - }; - - SegmentDesriptor() : low(0), high(0) {} - SegmentDesriptor(uint32_t base, uint32_t limit, uint8_t access, uint8_t _flags) - : low(0), high(0) - { - set_base(base); - set_limit(limit); - - high |= ((uint16_t)access) << 8; - flags = _flags; - } - - void set_base(uint32_t base) - { - base_lo = base & 0xFFFF; - base_hi1 = (base >> 16) & 0x00FF; - base_hi2 = (base >> 24) & 0x00FF; - } - - void set_limit(uint32_t limit) - { - limit_lo = limit & 0xFFFF; - limit_hi = (limit >> 16) & 0x00FF; - } - -} __attribute__((packed)); - -void gdt_initialize(); +} \ No newline at end of file diff --git a/kernel/kernel/kernel.cpp b/kernel/kernel/kernel.cpp index 550efc55e..176f87d33 100644 --- a/kernel/kernel/kernel.cpp +++ b/kernel/kernel/kernel.cpp @@ -70,7 +70,7 @@ extern "C" void kernel_main() kmalloc_initialize(); dprintln("kmalloc initialized"); - gdt_initialize(); + GDT::initialize(); dprintln("GDT initialized"); IDT::initialize(); dprintln("IDT initialized");