From f15f5f4fc4233aae79f532ef82a93fc0eae71985 Mon Sep 17 00:00:00 2001 From: Gitea Date: Tue, 1 Dec 2020 20:59:57 -0600 Subject: [PATCH] Some vague attempts at GDT stuff --- arch/i386/gdt.S | 34 ++++++++++++++++++++++++++++++++++ arch/i386/gdt.c | 28 ++++++++++++++++++++++++++++ arch/i386/gdt.h | 14 ++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 arch/i386/gdt.S create mode 100644 arch/i386/gdt.c create mode 100644 arch/i386/gdt.h diff --git a/arch/i386/gdt.S b/arch/i386/gdt.S new file mode 100644 index 0000000..1a9740a --- /dev/null +++ b/arch/i386/gdt.S @@ -0,0 +1,34 @@ + .globl set_gdt + .type set_gdt,%function + +gdtr: + .word 0 + .int 0 + +set_gdt: + .fnstart + mov 4(%esp), %eax + mov %eax, 2($gdtr) + mov 8(%esp), %ax + mov %ax, $gdtr + lgdt $gdtr + ret + .fnend + + .globl reload_segments + .type reload_segments,%function + +reload_segments: + .fnstart + jmp 0x08:reload_CS + .fnend + +reload_CS: + mov 0x10, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss + ret + diff --git a/arch/i386/gdt.c b/arch/i386/gdt.c new file mode 100644 index 0000000..b3f9168 --- /dev/null +++ b/arch/i386/gdt.c @@ -0,0 +1,28 @@ +void encode_gdt_entry(unsigned short int * target, struct GDT source) { + if((source.limit > 65536) && ((source.limit & 0xFFF) != 0xFFF)) { + /* This needs to error out. */ + return; + } + if(source.limit > 65536) { + /* Granularity adjustments */ + source.limit = source.limit >> 12; + target[6] = 0xC0; + } + else { + target[6] = 0x40; + } + + /* Encode limit */ + target[0] = source.limit & 0xFF; + target[1] = (source.limit >> 8) & 0xFF; + target[6] |= (source.limit >> 16) & 0xF; + + /* Encode base */ + target[2] = source.base & 0xFF; + target[3] = (source.base >> 8) & 0xFF; + target[4] = (source.base >> 16) & 0xFF; + target[7] = (source.base >> 24) & 0xFF; + + /* Encode type */ + target[5] = source.type; +} diff --git a/arch/i386/gdt.h b/arch/i386/gdt.h new file mode 100644 index 0000000..b8581df --- /dev/null +++ b/arch/i386/gdt.h @@ -0,0 +1,14 @@ +#ifndef _ARCH_I386_GDT_H +#define _ARCH_I386_GDT_H + +struct GDT { + unsigned int limit; + unsigned long int base; + unsigned short int type; +}; + +void encode_gdt_entry(unsigned short int *, struct GDT); +extern void set_gdt(void); +extern void reload_segments(void); + +#endif