Fix GDT subroutine

Also made some type changes in serial.h
This commit is contained in:
Jenny Curle 2019-04-07 16:36:51 +01:00
parent e4fcbb20b4
commit 15dc60aa12
7 changed files with 46 additions and 34 deletions

View File

@ -35,25 +35,6 @@ _start:
.size _start, . - _start .size _start, . - _start
# GDT segment register setup
.global gdt_flush
.extern gp
gdt_flush:
lgdt (gp) #load the GDT with the special pointer
mov %eax,0x10 #offset from GDT to data segment
mov %eax, %ds
mov %eax, %es
mov %eax, %fs
mov %eax, %gs
mov %eax, %ss
pushl 12(%esp)
push $flush2
ljmp *(%esp) #long jump
flush2:
ret #return to c code
.global idt_load .global idt_load
.extern idtp .extern idtp
idt_load: idt_load:

17
arch/i386/gdt.s Executable file
View File

@ -0,0 +1,17 @@
; This file is written with Intel ASM Syntax.
[GLOBAL load_gdt] ; Allows the C code to call gdt_flush().
load_gdt:
mov eax, [esp+4] ; Get the pointer to the GDT, passed as a parameter.
lgdt [eax] ; Load the new GDT pointer
mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment
mov ds, ax ; Load all data segment selectors
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x08:.flush ; 0x08 is the offset to our code segment: Far jump!
.flush:
ret

View File

@ -5,4 +5,5 @@ KERNEL_ARCH_LIBS=
KERNEL_ARCH_OBJS= \ KERNEL_ARCH_OBJS= \
$(ARCHDIR)/boot.o \ $(ARCHDIR)/boot.o \
$(ARCHDIR)/gdt.o \
$(ARCHDIR)/tty.o $(ARCHDIR)/tty.o

View File

@ -1,4 +1,6 @@
#pragma once #pragma once
#include <stdint.h>
#include <stddef.h>
extern void init_serial(); extern void init_serial();

View File

@ -1,27 +1,31 @@
#include <kernel/utils.h> #include <kernel/utils.h>
#include <kernel/serial.h>
#include <stddef.h>
#include <stdint.h>
struct gdt_item { struct gdt_item {
unsigned short low_limit; uint16_t low_limit;
unsigned short low_base; uint16_t low_base;
unsigned char middle_base; uint8_t middle_base;
unsigned char access; uint8_t access;
unsigned char granular; uint8_t granular;
unsigned char high_base; uint8_t high_base;
} __attribute__((packed)); //Prevent compiler optimisation by packing } __attribute__((packed)); //Prevent compiler optimisation by packing
struct gdt_ptr { struct gdt_ptr {
unsigned short limit; uint16_t limit;
unsigned int base; unsigned int base;
} __attribute__((packed)); } __attribute__((packed));
struct gdt_item gdt[3]; //3-entry gdt struct gdt_item gdt[3]; //3-entry gdt
struct gdt_ptr gp; struct gdt_ptr gp;
extern void gdt_flush(); extern void load_gdt(uint32_t);
void gdt_set_gate(int num, unsigned long base, void gdt_set_gate(int num, uint32_t base,
unsigned long limit, unsigned char access, uint32_t limit, uint8_t access,
unsigned char gran) { uint8_t gran) {
//Implementation taken from osdever.net //Implementation taken from osdever.net
gdt[num].low_base = (base & 0xFFFF); gdt[num].low_base = (base & 0xFFFF);
gdt[num].middle_base = (base >> 16) & 0xFF; gdt[num].middle_base = (base >> 16) & 0xFF;
@ -38,6 +42,7 @@ void gdt_install() {
gp.limit = (sizeof(struct gdt_item) * 3) - 1; gp.limit = (sizeof(struct gdt_item) * 3) - 1;
gp.base = (unsigned int)&gdt; gp.base = (unsigned int)&gdt;
gdt_set_gate(0, 0, 0, 0, 0); //NULL item gdt_set_gate(0, 0, 0, 0, 0); //NULL item
//Code Segment - base 0, 4KiB granularity, 4GiB limit //Code Segment - base 0, 4KiB granularity, 4GiB limit
@ -47,5 +52,5 @@ void gdt_install() {
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
//Apply changes //Apply changes
gdt_flush(); load_gdt((uint32_t) &gp);
} }

View File

@ -11,9 +11,12 @@ int kernel_main(void) {
// Prepare the serial console. // Prepare the serial console.
init_serial(); init_serial();
serial_print(0x3F8, "[INFO] Serial ready."); serial_print(0x3F8, "[INFO] Serial ready.");
// Prepare the GDT
//gdt_install(); // Prepare the GDT
serial_print(0x3F8, "[INFO] Beginning GDT subroutine.");
gdt_install();
// Prepare interrupts // Prepare interrupts
//idt_install(); //idt_install();

View File

@ -61,6 +61,9 @@ red.kernel: $(OBJS) $(ARCHDIR)/linker.ld
$(ARCHDIR)/crtbegin.o $(ARCHDIR)/crtend.o: $(ARCHDIR)/crtbegin.o $(ARCHDIR)/crtend.o:
OBJ=`$(CC) $(CFLAGS) $(LDFLAGS) -print-file-name=$(@F)` && cp "$$OBJ" $@ OBJ=`$(CC) $(CFLAGS) $(LDFLAGS) -print-file-name=$(@F)` && cp "$$OBJ" $@
$(ARCHDIR)/gdt.o:
nasm -f elf $(ARCHDIR)/gdt.s
.c.o: .c.o:
$(CC) -MD -c $< -o $@ -std=gnu11 $(CFLAGS) $(CPPFLAGS) $(CC) -MD -c $< -o $@ -std=gnu11 $(CFLAGS) $(CPPFLAGS)