Huge GDT update:

GDT control is how I would like it to be but there are some issues, namely:
1. far jumping to flush the code segment crashes the whole os(not good)
2. Segment selectors seem fine apart from the code segment thing
3. some administrative issues regarding the structure of the project which is slowly making things painful
This commit is contained in:
shockrah 2019-10-14 00:23:37 -07:00
parent 7d9800f1eb
commit c94252c3f2
7 changed files with 80 additions and 16 deletions

39
gdt.c Normal file
View File

@ -0,0 +1,39 @@
#include "gdt.h"
// Congirures a given gdt entry base on the entry index given
void gdt_configure_entry(u32 entry, u32 base, u32 limit, u8 access, u8 gran) {
// base address
gdt_entries[entry].low_base = (base & 0xffff);
gdt_entries[entry].middle_base = (base >> 16) & 0xff;
gdt_entries[entry].high_base = (base >> 24) & 0xff;
// descriptor limits
gdt_entries[entry].low_limit = (limit & 0xffff);
gdt_entries[entry].granular = ((limit >> 16) & 0x0f);
gdt_entries[entry].granular |= (gran & 0xf0);
gdt_entries[entry].access = access;
}
// Configure the gdt pointer desribed in gdt.h as type GDT_PTR
void gdt_configure() {
// gdt_ptr configuration
gdt_ptr.size = (sizeof(struct GDT_Entry) * NO_GDT_ENTRIES) - 1;
// First entry is just the null descriptor and is left along overall
gdt_configure_entry(0, 0, 0, 0, 0);
// Second entry: code segment base adders
// Base address: 0
// limit: 4GB
// Granularity: 4KB
// 32-bit opcodes
// Code segment selector
gdt_configure_entry(1, 0, 0xffffffff, 0x9a, 0xcf);
// Finally the data segment
// All the same except the desriptor type specifies that its data
gdt_configure_entry(2, 0, 0xffffffff, 0x92, 0xcf);
// Load in the new changes to the gdt
load_gdt();
}

22
gdt.h
View File

@ -1,19 +1,29 @@
#include "gdt.h"
#include "types.h"
// Container for our gdt entries
#define NO_GDT_ENTRIES 3
struct GDT_Entry {
};
u16 low_limit;
u16 low_base;
u8 middle_base;
u8 access;
u8 granular;
u8 high_base;
}__attribute__((packed));
struct GDT {
// Contains the pointer to the first gdt entry as well as the size(of the whole table(?))
struct GDT_PTR {
u16 size;
u32 address;
}__attribute__((packed));
struct GDT_Entry entries[2];
struct GDT GDT_P;
struct GDT_Entry gdt_entries[NO_GDT_ENTRIES];
struct GDT_PTR gdt_ptr;
// this func is actually taken care of in gdt_seg.s
extern void load_gdt();
void gdt_configure_entry(u32 entry, u32 base, u32 limit, u8 access, u8 gran);
void gdt_configure();

8
gdt.s
View File

@ -1,8 +0,0 @@
global load_gdt
; lgdt can only be used from assembly so here we are
extern GDT_PTR
load_gdt:
lgdt [eax]
ret

17
gdt_seg.s Normal file
View File

@ -0,0 +1,17 @@
global load_gdt
extern gdt_ptr
load_gdt:
lgdt [gdt_ptr]
mov ax, 0x10 ; offset in the gdt to our data segment
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x08:flush_cs ; far jump to the code segment
flush_cs:
ret ; here we go back to the caller code but with our segments configured

View File

@ -9,6 +9,8 @@ GDT _GDT[6]; // because there are only 6 segments we care about
u32 kinit() {
init_segment_selectors(); // found in gdt.s
}
// called by the loader to do lots of fun things
void kmain() {
}

View File

@ -5,10 +5,11 @@ global loader
MAGIC_NUMBER equ 0x1BADB002
FLAGS equ 0x0
CHECKSUM equ -MAGIC_NUMBER
KERNEL_STACK_SIZE equ 4096
; size in bytes of stack
KERNEL_STACK_SIZE equ 4096
extern gdt_configure
extern test_dispatcher
section .text
@ -22,6 +23,9 @@ align 4
; sets up our gdt and segment selectors for later use
loader:
; load the gdt that I setup
call load_gdt
;call gdt_configure
call test_dispatcher
.loop:

View File

@ -3,7 +3,7 @@ ASM=nasm
LINK=ld
ISO=genisoimage
OBJECTS=interrupts.o interrupt_entry.o loader.o serial.o framebuffer.o ports.o stlio.o tests.o
OBJECTS=gdt_seg.o gdt.o loader.o serial.o framebuffer.o ports.o stlio.o tests.o
AFLAGS=-f elf32
CFLAGS=-m32 -nostdlib -nostdinc -fno-builtin -fno-stack-protector -nostartfiles \
-nodefaultlibs -Wall -Wextra -Werror -c