Sync/kernel/gdt.c

56 lines
1.3 KiB
C
Raw Normal View History

#include <kernel/utils.h>
#include <kernel/serial.h>
#include <stddef.h>
#include <stdint.h>
struct gdt_item {
uint16_t low_limit;
uint16_t low_base;
uint8_t middle_base;
uint8_t access;
uint8_t granular;
uint8_t high_base;
} __attribute__((packed)); //Prevent compiler optimisation by packing
struct gdt_ptr {
uint16_t limit;
unsigned int base;
} __attribute__((packed));
struct gdt_item gdt[3]; //3-entry gdt
struct gdt_ptr gp;
extern void load_gdt(uint32_t);
void gdt_set_gate(int num, uint32_t base,
uint32_t limit, uint8_t access,
uint8_t 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 = (unsigned int)&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
load_gdt((uint32_t) &gp);
2019-04-06 19:25:31 +00:00
}