From c7b0fffe1369547c0e331a3a3cb5b4c66fede634 Mon Sep 17 00:00:00 2001 From: Morten Delenk Date: Sat, 10 Oct 2015 19:34:31 +0200 Subject: [PATCH] Added a working GDT. --- kernel/hal/x86/Makefile | 4 ++-- kernel/hal/x86/asm/snippets.S | 14 ++++++++++++++ kernel/hal/x86/include/base.hpp | 2 ++ kernel/hal/x86/include/gdt.hpp | 31 +++++++++++++++++++++++++++++++ kernel/hal/x86/init/gdt.cpp | 21 +++++++++++++++++++++ kernel/hal/x86/init/init.cpp | 10 ++++++++++ 6 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 kernel/hal/x86/asm/snippets.S create mode 100644 kernel/hal/x86/include/gdt.hpp create mode 100644 kernel/hal/x86/init/gdt.cpp diff --git a/kernel/hal/x86/Makefile b/kernel/hal/x86/Makefile index 860021b..fbd29a8 100644 --- a/kernel/hal/x86/Makefile +++ b/kernel/hal/x86/Makefile @@ -5,8 +5,8 @@ CPP = g++ CC = gcc LD = ld ASFLAGS = -m32 -CFLAGS = -m32 -Wall -g -fno-stack-protector -nostdinc -Ic_include/ -ffreestanding -fbuiltin -CPPFLAGS = -m32 -Wall -g -fno-stack-protector -nostdinc -std=c++14 -Iinclude/ -Ic_include/ -fno-rtti -fno-exceptions -ffreestanding -fbuiltin +CFLAGS = -m32 -Wall -g -fno-stack-protector -nostdinc -Ic_include/ -ffreestanding -fbuiltin -march=native +CPPFLAGS = -m32 -Wall -g -fno-stack-protector -nostdinc -std=c++14 -Iinclude/ -Ic_include/ -fno-rtti -fno-exceptions -ffreestanding -fbuiltin -march=native LDFLAGS = -r -melf_i386 hal.o: $(OBJS) diff --git a/kernel/hal/x86/asm/snippets.S b/kernel/hal/x86/asm/snippets.S new file mode 100644 index 0000000..301d377 --- /dev/null +++ b/kernel/hal/x86/asm/snippets.S @@ -0,0 +1,14 @@ +.global loadGDT +//void _stdcall loadGDT(struct gdtp* ptr); +loadGDT: + mov 0x4(%esp), %eax // Load argument + lgdt (%eax) + //GDT is loaded now + mov $0x10, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss + ljmp $0x8, $.1 +.1: diff --git a/kernel/hal/x86/include/base.hpp b/kernel/hal/x86/include/base.hpp index 02a211b..aeed7b0 100644 --- a/kernel/hal/x86/include/base.hpp +++ b/kernel/hal/x86/include/base.hpp @@ -5,10 +5,12 @@ namespace MTGosHAL { class Output; class Serial; class Screen; + class GDT; enum class BG_color: uint16_t; enum class FG_color: uint16_t; extern Serial* debug; extern Screen* out; extern Screen* err; + extern GDT* gdt; } #endif diff --git a/kernel/hal/x86/include/gdt.hpp b/kernel/hal/x86/include/gdt.hpp new file mode 100644 index 0000000..73352fe --- /dev/null +++ b/kernel/hal/x86/include/gdt.hpp @@ -0,0 +1,31 @@ +#ifndef _GDT_HPP +#define _GDT_HPP +#include +#define GDT_FLAG_DATASEG 0x02 +#define GDT_FLAG_CODESEG 0x0a +#define GDT_FLAG_TSS 0x09 + +#define GDT_FLAG_SEGMENT 0x10 +#define GDT_FLAG_RING0 0x00 +#define GDT_FLAG_RING3 0x60 +#define GDT_FLAG_PRESENT 0x80 + +#define GDT_FLAG_4K_GRAN 0x800 +#define GDT_FLAG_32_BIT 0x400 +extern "C" void loadGDT(void * gdtpr); +namespace MTGosHAL { + class GDT { + private: + uint64_t gdt[7]; + struct gdtp { + uint16_t limit; + void* pointer; + } __attribute__((packed)); + struct gdtp fin; + public: + GDT(); + auto setEntry(int i, unsigned int base, unsigned int limit, int flags) -> void; + auto apply() -> void; + }; +} +#endif diff --git a/kernel/hal/x86/init/gdt.cpp b/kernel/hal/x86/init/gdt.cpp new file mode 100644 index 0000000..d847a8f --- /dev/null +++ b/kernel/hal/x86/init/gdt.cpp @@ -0,0 +1,21 @@ +#include +#include +#include +namespace MTGosHAL { + GDT::GDT() { + gdt[0]=gdt[1]=gdt[2]=gdt[3]=gdt[4]=gdt[5]=gdt[6]=0x0ull; + } + auto GDT::setEntry(int i, unsigned int base, unsigned int limit, int flags) -> void { + gdt[i] = limit & 0xffffLL; + gdt[i] |= (base & 0xffffffLL) << 16; + gdt[i] |= (flags & 0xffLL) << 40; + gdt[i] |= ((limit >> 16) & 0xfLL) << 48; + gdt[i] |= ((flags >> 8 )& 0xffLL) << 52; + gdt[i] |= ((base >> 24) & 0xffLL) << 56; + } + auto GDT::apply() -> void { + *debug << "We are now trying to set our GDT. If the CPU triplefaults, something went wrong in MTGosHAL::GDT::apply() or loadGDT().\n"; + fin={(uint16_t)7*8-1, (void*)gdt}; + loadGDT((void*)(&fin)); + }; +} diff --git a/kernel/hal/x86/init/init.cpp b/kernel/hal/x86/init/init.cpp index 79cef21..dd1f110 100644 --- a/kernel/hal/x86/init/init.cpp +++ b/kernel/hal/x86/init/init.cpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace MTGosHAL { Serial* debug; Screen* out; @@ -9,11 +10,20 @@ namespace MTGosHAL { void main() { Serial serialOUT(115200); Screen display; + GDT gdt; debug=&serialOUT; err=&display; out=&display; *out << BG_color::BLACK << FG_color::WHITE << "Loading MTGos...\n"; *debug << "Hello debugger! This is MTGos version 0.0\nThese logs are probably very long, so please redirect the output to a file.\n"; + gdt.setEntry(0, 0, 0, 0); + gdt.setEntry(1, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT); + gdt.setEntry(2, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT); + gdt.setEntry(3, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3); + gdt.setEntry(4, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3); + gdt.setEntry(5, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_TSS | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT); + gdt.setEntry(6, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_TSS | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT); + gdt.apply(); for(;;); } }