Begin support for Global Descriptor Tables

This commit is contained in:
Jenny Curle 2019-04-06 20:00:11 +01:00
parent 904cb38128
commit a3e0852ec7
5 changed files with 78 additions and 2 deletions

View File

@ -10,12 +10,30 @@
.long FLAGS
.long CHECKSUM
# C stack startup
.section .bss
.align 16
stack_bottom:
.skip 16384
stack_top:
# GDT segment register setup
.global _gdt_flush
.extern _gp
_gdt_flush:
lgdt (_gp) #load the GDT with the special pointer
mov %ax, 0x10 #offset from GDT to data segment
mov %ds, ax
mov %es, ax
mov %fs, ax
mov %gs, ax
mov %ss, ax
jmp 0x08:flush2 #long jump
flush2:
ret #return to c code
# start function - calls kernel_main
.section .text
.global _start
.type _start, @function

4
include/kernel/gdt.h Executable file
View File

@ -0,0 +1,4 @@
#pragma once
void gdt_set_gate(int, unsigned long, unsigned long, unsigned char, unsigned char);
void gdt_install();

50
kernel/gdt.c Executable file
View File

@ -0,0 +1,50 @@
#include <kernel/utils.h>
struct gdt_item {
unsigned short low_limit;
unsigned short low_base;
unsigned char middle_base;
unsigned char access;
unsigned char granular;
unsigned char high_base;
} __attribute__((packed)); //Prevent compiler optimisation by packing
struct gdt_ptr {
unsigned short limit;
unsigned int base;
} __attribute__((packed));
struct gdt_item gdt[3]; //3-entry gdt
struct gdt_ptr gp;
extern void gdt_flush();
void gdt_set_gate(int num, unsigned long base,
unsigned long limit, unsigned char access,
unsigned char gran) {
//Implementation taken from osdever.net
gdt[num].low_base = (base & 0xFFFF);
gdt[num].middle_base = (base >> 16) & 0xFF;
gdt[num].high_base = (base >> 24) & 0xFF;
gdt[num].low_limit = (limit & 0xFFFF);
gdt[num].granular = ((limit >> 16) & 0x0F);
gdt[num].granular != (gran & 0xF0);
gdt[num].access = access;
}
void gdt_install() {
gp.limit = (sizeof(struct gdt_item) * 3) - 1;
gp.base = &gdt;
gdt_set_gate(0, 0, 0, 0, 0); //NULL item
//Code Segment - base 0, 4KiB granularity, 4GiB limit
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
//Data Segment - ditto
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
//Apply changes
gdt_flush();

View File

@ -1,8 +1,11 @@
//#include <stdio.h>
#include "kernel/tty.h"
#include <kernel/tty.h>
#include <kernel/gdt.h>
int kernel_main(void) {
//Prepare the GDT
gdt_install()
//Prepare the screen, and blank it out.
screen_initialize();

View File

@ -30,6 +30,7 @@ LIBS:=$(LIBS) $(KERNEL_ARCH_LIBS)
KERNEL_OBJS= \
$(KERNEL_ARCH_OBJS) \
kernel/utils.o \
kernel/gdt.o \
kernel/kernel.o
OBJS=\