31d2e10b69
Basically, added error handling, interrupts and basic hardware communication is now possible. Yay.
56 lines
1.3 KiB
C
Executable File
56 lines
1.3 KiB
C
Executable File
#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();
|
|
|
|
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();
|
|
} |