interrupts
This commit is contained in:
53
src/idt.asm
Normal file
53
src/idt.asm
Normal file
@@ -0,0 +1,53 @@
|
||||
%macro isr_err_stub 1
|
||||
isr_stub_%+%1:
|
||||
call exception_handler
|
||||
iretq
|
||||
%endmacro
|
||||
|
||||
%macro isr_no_err_stub 1
|
||||
isr_stub_%+%1:
|
||||
call exception_handler
|
||||
iretq
|
||||
%endmacro
|
||||
|
||||
extern exception_handler
|
||||
isr_no_err_stub 0
|
||||
isr_no_err_stub 1
|
||||
isr_no_err_stub 2
|
||||
isr_no_err_stub 3
|
||||
isr_no_err_stub 4
|
||||
isr_no_err_stub 5
|
||||
isr_no_err_stub 6
|
||||
isr_no_err_stub 7
|
||||
isr_err_stub 8
|
||||
isr_no_err_stub 9
|
||||
isr_err_stub 10
|
||||
isr_err_stub 11
|
||||
isr_err_stub 12
|
||||
isr_err_stub 13
|
||||
isr_err_stub 14
|
||||
isr_no_err_stub 15
|
||||
isr_no_err_stub 16
|
||||
isr_err_stub 17
|
||||
isr_no_err_stub 18
|
||||
isr_no_err_stub 19
|
||||
isr_no_err_stub 20
|
||||
isr_no_err_stub 21
|
||||
isr_no_err_stub 22
|
||||
isr_no_err_stub 23
|
||||
isr_no_err_stub 24
|
||||
isr_no_err_stub 25
|
||||
isr_no_err_stub 26
|
||||
isr_no_err_stub 27
|
||||
isr_no_err_stub 28
|
||||
isr_no_err_stub 29
|
||||
isr_err_stub 30
|
||||
isr_no_err_stub 31
|
||||
|
||||
global isr_stub_table
|
||||
isr_stub_table:
|
||||
%assign i 0
|
||||
%rep 32
|
||||
dq isr_stub_%+i
|
||||
%assign i i+1
|
||||
%endrep
|
||||
65
src/idt.c
Normal file
65
src/idt.c
Normal file
@@ -0,0 +1,65 @@
|
||||
#include "vga.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define IDT_MAX_DESCRIPTORS 255
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t isr_low; // The lower 16 bits of the ISR's address
|
||||
uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR
|
||||
uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now
|
||||
uint8_t attributes; // Type and attributes; see the IDT page
|
||||
uint16_t isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address
|
||||
uint32_t isr_high; // The higher 32 bits of the ISR's address
|
||||
uint32_t reserved; // Set to zero
|
||||
} __attribute__((packed)) idt_entry_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t limit;
|
||||
uint64_t base;
|
||||
} __attribute__((packed)) idtr_t;
|
||||
|
||||
static idt_entry_t idt[256];
|
||||
static idtr_t idtr;
|
||||
|
||||
void exception_handler(void)
|
||||
{
|
||||
vga_print_error("An unhandled exception occurred");
|
||||
__asm__ volatile("cli; hlt");
|
||||
}
|
||||
|
||||
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags)
|
||||
{
|
||||
idt_entry_t* descriptor = &idt[vector];
|
||||
|
||||
descriptor->isr_low = (uint64_t)isr & 0xFFFF;
|
||||
descriptor->kernel_cs = 0x08;
|
||||
descriptor->ist = 0;
|
||||
descriptor->attributes = flags;
|
||||
descriptor->isr_mid = ((uint64_t)isr >> 16) & 0xFFFF;
|
||||
descriptor->isr_high = ((uint64_t)isr >> 32) & 0xFFFFFFFF;
|
||||
descriptor->reserved = 0;
|
||||
}
|
||||
|
||||
static bool vectors[IDT_MAX_DESCRIPTORS];
|
||||
|
||||
extern void* isr_stub_table[];
|
||||
|
||||
void idt_init(void)
|
||||
{
|
||||
idtr.base = (uintptr_t)&idt[0];
|
||||
idtr.limit = (uint16_t)sizeof(idt_entry_t) * IDT_MAX_DESCRIPTORS - 1;
|
||||
|
||||
for (uint8_t vector = 0; vector < 32; vector++)
|
||||
{
|
||||
idt_set_descriptor(vector, isr_stub_table[vector], 0x8E);
|
||||
vectors[vector] = true;
|
||||
}
|
||||
|
||||
__asm__ volatile("lidt %0" : : "m"(idtr));
|
||||
__asm__ volatile("sti");
|
||||
|
||||
vga_print_success("IDT intialzied");
|
||||
}
|
||||
5
src/idt.h
Normal file
5
src/idt.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#include <stdint.h>
|
||||
|
||||
void idt_init(void);
|
||||
void exception_handler(void);
|
||||
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags);
|
||||
@@ -1,7 +1,13 @@
|
||||
#include "idt.h"
|
||||
#include "vga.h"
|
||||
|
||||
void kernel_main(void)
|
||||
{
|
||||
vga_clear();
|
||||
|
||||
idt_init();
|
||||
|
||||
vga_print("Welcome to nub OS\n");
|
||||
|
||||
int x = 1 / 0;
|
||||
}
|
||||
18
src/vga.c
18
src/vga.c
@@ -108,4 +108,22 @@ void vga_print_colored(const char* string, vga_color_t color)
|
||||
void vga_print(const char* string)
|
||||
{
|
||||
vga_print_colored(string, vga_default_color());
|
||||
}
|
||||
|
||||
void vga_print_success(const char* message)
|
||||
{
|
||||
vga_print("[ ");
|
||||
vga_print_colored("success", VGA_GREEN);
|
||||
vga_print(" ] ");
|
||||
vga_print(message);
|
||||
vga_print("\n");
|
||||
}
|
||||
|
||||
void vga_print_error(const char* message)
|
||||
{
|
||||
vga_print("[ ");
|
||||
vga_print_colored("error", VGA_RED);
|
||||
vga_print(" ] ");
|
||||
vga_print(message);
|
||||
vga_print("\n");
|
||||
}
|
||||
@@ -26,6 +26,8 @@ void vga_set_cursor_position(uint8_t row, uint8_t col);
|
||||
|
||||
void vga_print_colored(const char* string, vga_color_t color);
|
||||
void vga_print(const char* string);
|
||||
void vga_print_success(const char* message);
|
||||
void vga_print_error(const char* message);
|
||||
|
||||
static inline vga_color_t vga_color(vga_color_t fg_color, vga_color_t bg_color)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user