diff --git a/src/kernel/arch/x86/gdt.c b/src/kernel/arch/x86/gdt.c index f93ac52..7fb6662 100644 --- a/src/kernel/arch/x86/gdt.c +++ b/src/kernel/arch/x86/gdt.c @@ -1,4 +1,5 @@ #include "gdt.h" +#include "idt.h" #include "isr.h" #include #include @@ -9,6 +10,14 @@ #include #include +#define BYTE_MASK 0xFF +#define PAGE_FAULT 14 +#define DOUBLE_FAULT 8 +#define SYSTEM_CALL 80 +#define TIMER 20 + +#define ISR_TABLE_SIZE 256 + // GDT table struct gdt_entry *gdt; @@ -31,11 +40,11 @@ enum GDT_BASE_LIMIT // Initialize a GDT entry void gdt_set_gate(uint32_t num, uint32_t base, uint32_t limit, uint8_t access, - uint8_t gran) + uint8_t gran, struct gdt_entry *const gdt) { gdt[num].base_low = (base & GDT_LIMIT_MASK); - gdt[num].base_middle = (base >> GDT_BASE_MIDDLE_SHIFT) & 0xFF; - gdt[num].base_high = (base >> GDT_BASE_HIGH_SHIFT) & 0xFF; + gdt[num].base_middle = (base >> GDT_BASE_MIDDLE_SHIFT) & BYTE_MASK; + gdt[num].base_high = (base >> GDT_BASE_HIGH_SHIFT) & BYTE_MASK; gdt[num].limit_low = (limit & GDT_LIMIT_MASK); gdt[num].granularity = (limit >> GDT_GRANULARITY_SHIFT) & GDT_GRANULARITY_MASK; @@ -50,6 +59,24 @@ void gdt_init() gp.limit = (sizeof(struct gdt_entry) * 3) - 1; gdt = (struct gdt_entry *)malloc(sizeof(struct gdt_entry) * 3); memset(gdt, 0, sizeof(struct gdt_entry) * 3); + + // Initialize GDT entries + gdt_set_gate(0, 0, 0, 0, 0, gdt); // Null segment + gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF, gdt); // Code segment + gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF, gdt); // Data segment + + // Load GDT + struct gdt_ptr gdtp; + gdtp.limit = gp.limit; + gdtp.base = (uint32_t)gdt; + __asm__ volatile("lgdt %0" : : "m"(gdtp)); + __asm__ volatile("mov $0x10, %ax\n\t" + "mov %ax, %ds\n\t" + "mov %ax, %es\n\t" + "mov %ax, %fs\n\t" + "mov %ax, %gs\n\t" + "ljmp $0x08, $next\n\t" + "next:"); } // Exception handlers @@ -65,15 +92,18 @@ extern void keyboard(); extern void device(); // ISR table -void (*isr_table[256])(void) = {0}; +void (*isr_table[ISR_TABLE_SIZE])(void) = {0}; // Register an ISR -void isr_register(uint8_t num, void (*handler)(struct isr_regs *regs)); +void isr_register(uint8_t num, void (*handler)(void)) +{ + isr_table[num] = handler; +} // ISR handler -void isr_handler(struct idt_regs *regs); +void isr_handler(struct idt_regs *regs) { - void (*handler)(void); + void (*handler)(void) = isr_table[regs->int_no]; handler = isr_table[regs->int_no]; if (handler) @@ -86,20 +116,20 @@ void isr_handler(struct idt_regs *regs); void isr_init() { // Initialize ISR table - for (int i = 0; i < 256; i++) + for (int i = 0; i < ISR_TABLE_SIZE; i++) { isr_table[i] = NULL; } // Register exception handlers isr_register(0, divide_error); - isr_register(14, page_fault); + isr_register(PAGE_FAULT, page_fault); isr_register(13, general_protection_fault); - isr_register(8, double_fault); + isr_register(DOUBLE_FAULT, double_fault); // Register interrupt handlers - isr_register(0x80, system_call); - isr_register(0x20, timer); + isr_register(SYSTEM_CALL, system_call); + isr_register(TIMER, timer); isr_register(0x21, keyboard); isr_register(0x30, device); -} \ No newline at end of file +} diff --git a/src/kernel/arch/x86/gdt.h b/src/kernel/arch/x86/gdt.h index f181d31..d951da4 100644 --- a/src/kernel/arch/x86/gdt.h +++ b/src/kernel/arch/x86/gdt.h @@ -4,31 +4,26 @@ #include -// GDT table -extern struct gdt_entry *gdt; - // GDT entry structure struct gdt_entry { - uint16_t limit_low; // The lower 16 bits of the limit - uint16_t base_low; // The lower 16 bits of the base - uint8_t base_middle; // The next 8 bits of the base - uint8_t access; // Access flags, determine what ring this segment can be used in + uint16_t limit_low; // The lower 16 bits of the limit + uint16_t base_low; // The lower 16 bits of the base + uint8_t base_middle; // The next 8 bits of the base + uint8_t + access; // Access flags, determine what ring this segment can be used in uint8_t granularity; - uint8_t base_high; // The last 8 bits of the base + uint8_t base_high; // The last 8 bits of the base } __attribute__((packed)); // GDT pointer structure struct gdt_ptr { - uint16_t limit; // The upper 16 bits of all selector limits - uint32_t base; // The address of the first gdt_entry_t struct + uint16_t limit; // The upper 16 bits of all selector limits + uint32_t base; // The address of the first gdt_entry_t struct } __attribute__((packed)); // Initialize the GDT void gdt_init(); -// Set a GDT entry -void gdt_set_gate(uint32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran); - #endif \ No newline at end of file diff --git a/src/kernel/arch/x86/idt.h b/src/kernel/arch/x86/idt.h index ab6fa36..0e94d4a 100644 --- a/src/kernel/arch/x86/idt.h +++ b/src/kernel/arch/x86/idt.h @@ -4,10 +4,6 @@ #include // Define the isr_regs structure -struct idt_regs -{ - // Add the necessary members for your ISR context -}; // IDT entry structure struct idt_entry @@ -28,12 +24,9 @@ struct idt_ptr // Exception handlers void divide_error(); -void page_fault(struct idt_regs *); -void general_protection_fault(struct idt_regs *); void double_fault(); // Interrupt handlers -void system_call(struct idt_regs *); void timer(); void keyboard(); void device(); diff --git a/src/kernel/arch/x86/isr.h b/src/kernel/arch/x86/isr.h index f540fee..86d753c 100644 --- a/src/kernel/arch/x86/isr.h +++ b/src/kernel/arch/x86/isr.h @@ -4,7 +4,7 @@ #include // Structure for storing register values during an ISR -struct isr_regs +struct idt_regs { uint32_t ds; // Data segment selector uint32_t edi, esi, ebp, esp, ebx, edx, ecx, @@ -15,9 +15,6 @@ struct isr_regs ss; // Pushed by the processor automatically }; -// Register an ISR -void isr_register(uint8_t num, void (*handler)(struct isr_regs *regs)); - // ISR handler void isr_handler(struct idt_regs *regs);