Fixed some of gdt.c and .h and also idt.h and isr

This commit is contained in:
Gregory Kenneth Bowne 2023-10-02 13:01:41 -07:00
parent 058f61d3ba
commit 2b7ed92a07
4 changed files with 52 additions and 37 deletions

View File

@ -1,4 +1,5 @@
#include "gdt.h" #include "gdt.h"
#include "idt.h"
#include "isr.h" #include "isr.h"
#include <inttypes.h> #include <inttypes.h>
#include <stdbool.h> #include <stdbool.h>
@ -9,6 +10,14 @@
#include <string.h> #include <string.h>
#include <sys/cdefs.h> #include <sys/cdefs.h>
#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 // GDT table
struct gdt_entry *gdt; struct gdt_entry *gdt;
@ -31,11 +40,11 @@ enum GDT_BASE_LIMIT
// Initialize a GDT entry // Initialize a GDT entry
void gdt_set_gate(uint32_t num, uint32_t base, uint32_t limit, uint8_t access, 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_low = (base & GDT_LIMIT_MASK);
gdt[num].base_middle = (base >> GDT_BASE_MIDDLE_SHIFT) & 0xFF; gdt[num].base_middle = (base >> GDT_BASE_MIDDLE_SHIFT) & BYTE_MASK;
gdt[num].base_high = (base >> GDT_BASE_HIGH_SHIFT) & 0xFF; gdt[num].base_high = (base >> GDT_BASE_HIGH_SHIFT) & BYTE_MASK;
gdt[num].limit_low = (limit & GDT_LIMIT_MASK); gdt[num].limit_low = (limit & GDT_LIMIT_MASK);
gdt[num].granularity = gdt[num].granularity =
(limit >> GDT_GRANULARITY_SHIFT) & GDT_GRANULARITY_MASK; (limit >> GDT_GRANULARITY_SHIFT) & GDT_GRANULARITY_MASK;
@ -50,6 +59,24 @@ void gdt_init()
gp.limit = (sizeof(struct gdt_entry) * 3) - 1; gp.limit = (sizeof(struct gdt_entry) * 3) - 1;
gdt = (struct gdt_entry *)malloc(sizeof(struct gdt_entry) * 3); gdt = (struct gdt_entry *)malloc(sizeof(struct gdt_entry) * 3);
memset(gdt, 0, 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 // Exception handlers
@ -65,15 +92,18 @@ extern void keyboard();
extern void device(); extern void device();
// ISR table // ISR table
void (*isr_table[256])(void) = {0}; void (*isr_table[ISR_TABLE_SIZE])(void) = {0};
// Register an ISR // 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 // 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]; handler = isr_table[regs->int_no];
if (handler) if (handler)
@ -86,20 +116,20 @@ void isr_handler(struct idt_regs *regs);
void isr_init() void isr_init()
{ {
// Initialize ISR table // Initialize ISR table
for (int i = 0; i < 256; i++) for (int i = 0; i < ISR_TABLE_SIZE; i++)
{ {
isr_table[i] = NULL; isr_table[i] = NULL;
} }
// Register exception handlers // Register exception handlers
isr_register(0, divide_error); isr_register(0, divide_error);
isr_register(14, page_fault); isr_register(PAGE_FAULT, page_fault);
isr_register(13, general_protection_fault); isr_register(13, general_protection_fault);
isr_register(8, double_fault); isr_register(DOUBLE_FAULT, double_fault);
// Register interrupt handlers // Register interrupt handlers
isr_register(0x80, system_call); isr_register(SYSTEM_CALL, system_call);
isr_register(0x20, timer); isr_register(TIMER, timer);
isr_register(0x21, keyboard); isr_register(0x21, keyboard);
isr_register(0x30, device); isr_register(0x30, device);
} }

View File

@ -4,16 +4,14 @@
#include <stdint.h> #include <stdint.h>
// GDT table
extern struct gdt_entry *gdt;
// GDT entry structure // GDT entry structure
struct gdt_entry struct gdt_entry
{ {
uint16_t limit_low; // The lower 16 bits of the limit uint16_t limit_low; // The lower 16 bits of the limit
uint16_t base_low; // The lower 16 bits of the base uint16_t base_low; // The lower 16 bits of the base
uint8_t base_middle; // The next 8 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
access; // Access flags, determine what ring this segment can be used in
uint8_t granularity; 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)); } __attribute__((packed));
@ -28,7 +26,4 @@ struct gdt_ptr
// Initialize the GDT // Initialize the GDT
void gdt_init(); 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 #endif

View File

@ -4,10 +4,6 @@
#include <stdint.h> #include <stdint.h>
// Define the isr_regs structure // Define the isr_regs structure
struct idt_regs
{
// Add the necessary members for your ISR context
};
// IDT entry structure // IDT entry structure
struct idt_entry struct idt_entry
@ -28,12 +24,9 @@ struct idt_ptr
// Exception handlers // Exception handlers
void divide_error(); void divide_error();
void page_fault(struct idt_regs *);
void general_protection_fault(struct idt_regs *);
void double_fault(); void double_fault();
// Interrupt handlers // Interrupt handlers
void system_call(struct idt_regs *);
void timer(); void timer();
void keyboard(); void keyboard();
void device(); void device();

View File

@ -4,7 +4,7 @@
#include <stdint.h> #include <stdint.h>
// Structure for storing register values during an ISR // Structure for storing register values during an ISR
struct isr_regs struct idt_regs
{ {
uint32_t ds; // Data segment selector uint32_t ds; // Data segment selector
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, uint32_t edi, esi, ebp, esp, ebx, edx, ecx,
@ -15,9 +15,6 @@ struct isr_regs
ss; // Pushed by the processor automatically ss; // Pushed by the processor automatically
}; };
// Register an ISR
void isr_register(uint8_t num, void (*handler)(struct isr_regs *regs));
// ISR handler // ISR handler
void isr_handler(struct idt_regs *regs); void isr_handler(struct idt_regs *regs);