Begin support for Global Descriptor Tables
This commit is contained in:
parent
904cb38128
commit
a3e0852ec7
|
@ -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
4
include/kernel/gdt.h
Executable 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
50
kernel/gdt.c
Executable 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();
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user