Begin support for Global Descriptor Tables
This commit is contained in:
parent
904cb38128
commit
a3e0852ec7
|
@ -10,12 +10,30 @@
|
||||||
.long FLAGS
|
.long FLAGS
|
||||||
.long CHECKSUM
|
.long CHECKSUM
|
||||||
|
|
||||||
|
# C stack startup
|
||||||
.section .bss
|
.section .bss
|
||||||
.align 16
|
.align 16
|
||||||
stack_bottom:
|
stack_bottom:
|
||||||
.skip 16384
|
.skip 16384
|
||||||
stack_top:
|
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
|
.section .text
|
||||||
.global _start
|
.global _start
|
||||||
.type _start, @function
|
.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 <stdio.h>
|
||||||
|
|
||||||
#include "kernel/tty.h"
|
#include <kernel/tty.h>
|
||||||
|
#include <kernel/gdt.h>
|
||||||
|
|
||||||
int kernel_main(void) {
|
int kernel_main(void) {
|
||||||
|
//Prepare the GDT
|
||||||
|
gdt_install()
|
||||||
//Prepare the screen, and blank it out.
|
//Prepare the screen, and blank it out.
|
||||||
screen_initialize();
|
screen_initialize();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user