mirror of
https://github.com/gbowne1/ClassicOS.git
synced 2025-05-15 09:01:27 -07:00
49 lines
1.4 KiB
C
49 lines
1.4 KiB
C
#include "gdt.h"
|
||
|
||
// Structure of a GDT entry (8 bytes)
|
||
struct gdt_entry {
|
||
uint16_t limit_low; // Limit bits 0–15
|
||
uint16_t base_low; // Base bits 0–15
|
||
uint8_t base_middle; // Base bits 16–23
|
||
uint8_t access; // Access flags
|
||
uint8_t granularity; // Granularity + limit bits 16–19
|
||
uint8_t base_high; // Base bits 24–31
|
||
} __attribute__((packed));
|
||
|
||
// Structure of the GDT pointer
|
||
struct gdt_ptr {
|
||
uint16_t limit;
|
||
uint32_t base;
|
||
} __attribute__((packed));
|
||
|
||
// Declare GDT with 3 entries
|
||
static struct gdt_entry gdt[3];
|
||
static struct gdt_ptr gp;
|
||
|
||
// External ASM function to load GDT
|
||
extern void gdt_flush(uint32_t);
|
||
|
||
// Set an individual GDT entry
|
||
static void gdt_set_gate(int num, uint32_t base, uint32_t limit, uint8_t access, uint8_t granularity) {
|
||
gdt[num].base_low = (base & 0xFFFF);
|
||
gdt[num].base_middle = (base >> 16) & 0xFF;
|
||
gdt[num].base_high = (base >> 24) & 0xFF;
|
||
|
||
gdt[num].limit_low = (limit & 0xFFFF);
|
||
gdt[num].granularity = ((limit >> 16) & 0x0F) | (granularity & 0xF0);
|
||
|
||
gdt[num].access = access;
|
||
}
|
||
|
||
// Initialize the GDT
|
||
void gdt_init(void) {
|
||
gp.limit = (sizeof(struct gdt_entry) * 3) - 1;
|
||
gp.base = (uint32_t)&gdt;
|
||
|
||
gdt_set_gate(0, 0, 0, 0, 0); // Null segment
|
||
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
|
||
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
|
||
|
||
gdt_flush((uint32_t)&gp);
|
||
}
|