Syncboot/kernel/gdt.c

50 lines
1.2 KiB
C
Raw Normal View History

#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();