Fix GDT subroutine
Also made some type changes in serial.h
This commit is contained in:
parent
e4fcbb20b4
commit
15dc60aa12
|
@ -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
17
arch/i386/gdt.s
Executable 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
|
|
@ -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
|
|
@ -1,4 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
extern void init_serial();
|
extern void init_serial();
|
||||||
|
|
||||||
|
|
29
kernel/gdt.c
29
kernel/gdt.c
|
@ -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);
|
||||||
}
|
}
|
|
@ -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();
|
||||||
|
|
||||||
|
|
3
makefile
3
makefile
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user