idt
This commit is contained in:
2
makefile
2
makefile
@@ -1,7 +1,7 @@
|
||||
CC = x86_64-elf-gcc
|
||||
LD = x86_64-elf-ld
|
||||
|
||||
CFLAGS = -m64 -ffreestanding -fno-builtin -Wall -Wextra -Wshadow -std=c23
|
||||
CFLAGS = -m64 -ffreestanding -fno-builtin -Wall -Wextra -Werror -Wshadow -std=c23
|
||||
LDFLAGS =
|
||||
|
||||
all: .build/nub-os.iso
|
||||
|
||||
@@ -31,6 +31,7 @@ section .text
|
||||
bits 32
|
||||
global _start
|
||||
_start:
|
||||
cli
|
||||
mov esp, stack_top
|
||||
|
||||
; Check if CPU supports 64-bit mode
|
||||
|
||||
19
src/idt.asm
19
src/idt.asm
@@ -1,16 +1,21 @@
|
||||
extern interrput_handler
|
||||
|
||||
%macro isr_err_stub 1
|
||||
isr_stub_%+%1:
|
||||
call exception_handler
|
||||
push %1
|
||||
call interrput_handler
|
||||
add rsp, 8
|
||||
iretq
|
||||
%endmacro
|
||||
|
||||
%macro isr_no_err_stub 1
|
||||
isr_stub_%+%1:
|
||||
call exception_handler
|
||||
push %1
|
||||
call interrput_handler
|
||||
add rsp, 8
|
||||
iretq
|
||||
%endmacro
|
||||
|
||||
extern exception_handler
|
||||
isr_no_err_stub 0
|
||||
isr_no_err_stub 1
|
||||
isr_no_err_stub 2
|
||||
@@ -51,3 +56,11 @@ isr_stub_table:
|
||||
dq isr_stub_%+i
|
||||
%assign i i + 1
|
||||
%endrep
|
||||
|
||||
.text
|
||||
global idt_hang
|
||||
idt_hang:
|
||||
cli
|
||||
.loop:
|
||||
hlt
|
||||
jmp .loop
|
||||
79
src/idt.c
79
src/idt.c
@@ -1,19 +1,19 @@
|
||||
#include "idt.h"
|
||||
#include "vga.h"
|
||||
#include <stdbool.h>
|
||||
#include <stddef.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;
|
||||
uint16_t address_low;
|
||||
uint16_t selector;
|
||||
uint8_t ist;
|
||||
uint8_t flags;
|
||||
uint16_t address_mid;
|
||||
uint32_t address_high;
|
||||
uint32_t reserved;
|
||||
} __attribute__((packed)) interrupt_descriptor;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -21,45 +21,48 @@ typedef struct
|
||||
uint64_t base;
|
||||
} __attribute__((packed)) idtr_t;
|
||||
|
||||
static idt_entry_t idt[256];
|
||||
static interrupt_descriptor 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[];
|
||||
extern void idt_hang();
|
||||
|
||||
void idt_set_descriptor(uint8_t vector, void* handler, uint8_t dpl)
|
||||
{
|
||||
interrupt_descriptor* entry = &idt[vector];
|
||||
|
||||
entry->address_low = (uint64_t)handler & 0xFFFF;
|
||||
entry->address_mid = ((uint64_t)handler >> 16) & 0xFFFF;
|
||||
entry->address_high = (uint64_t)handler >> 32;
|
||||
entry->selector = 0x08;
|
||||
entry->flags = 0b1110 | ((dpl & 0b11) << 5) | (1 << 7);
|
||||
entry->ist = 0;
|
||||
entry->reserved = 0;
|
||||
}
|
||||
|
||||
void idt_init(void)
|
||||
{
|
||||
idtr.base = (uintptr_t)&idt[0];
|
||||
idtr.limit = (uint16_t)sizeof(idt_entry_t) * IDT_MAX_DESCRIPTORS - 1;
|
||||
idtr.limit = (uint16_t)sizeof(interrupt_descriptor) * 256 - 1;
|
||||
|
||||
for (uint8_t vector = 0; vector < 32; vector++)
|
||||
{
|
||||
idt_set_descriptor(vector, isr_stub_table[vector], 0x8E);
|
||||
vectors[vector] = true;
|
||||
idt_set_descriptor(vector, isr_stub_table[vector], 0);
|
||||
}
|
||||
|
||||
__asm__ volatile("lidt %0" : : "m"(idtr));
|
||||
__asm__ volatile("sti");
|
||||
|
||||
vga_print_success("IDT intialzied");
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t vector_number;
|
||||
uint64_t error_code;
|
||||
} cpu_status_t;
|
||||
|
||||
void interrput_handler(uint64_t vector_number)
|
||||
{
|
||||
vga_print("An exception occurred: ");
|
||||
vga_print_uint(vector_number);
|
||||
vga_print("\n");
|
||||
idt_hang();
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void idt_init(void);
|
||||
void exception_handler(void);
|
||||
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags);
|
||||
|
||||
@@ -6,8 +6,7 @@ void kernel_main(void)
|
||||
vga_clear();
|
||||
|
||||
idt_init();
|
||||
vga_print_success("IDT intialzied\n");
|
||||
|
||||
vga_print("Welcome to nub OS\n");
|
||||
|
||||
int x = 1 / 0;
|
||||
}
|
||||
62
src/vga.c
62
src/vga.c
@@ -116,7 +116,6 @@ void vga_print_success(const char* message)
|
||||
vga_print_colored("success", VGA_GREEN);
|
||||
vga_print(" ] ");
|
||||
vga_print(message);
|
||||
vga_print("\n");
|
||||
}
|
||||
|
||||
void vga_print_error(const char* message)
|
||||
@@ -125,5 +124,64 @@ void vga_print_error(const char* message)
|
||||
vga_print_colored("error", VGA_RED);
|
||||
vga_print(" ] ");
|
||||
vga_print(message);
|
||||
vga_print("\n");
|
||||
}
|
||||
|
||||
static void reverse(char* str, int length)
|
||||
{
|
||||
int start = 0;
|
||||
int end = length - 1;
|
||||
while (start < end)
|
||||
{
|
||||
char temp = str[start];
|
||||
str[start] = str[end];
|
||||
str[end] = temp;
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
}
|
||||
|
||||
static int uitoa(unsigned int value, char* buffer)
|
||||
{
|
||||
int i = 0;
|
||||
if (value == 0)
|
||||
{
|
||||
buffer[i++] = '0';
|
||||
buffer[i] = '\0';
|
||||
return i;
|
||||
}
|
||||
|
||||
while (value > 0)
|
||||
{
|
||||
buffer[i++] = (value % 10) + '0';
|
||||
value /= 10;
|
||||
}
|
||||
|
||||
buffer[i] = '\0';
|
||||
reverse(buffer, i);
|
||||
return i;
|
||||
}
|
||||
|
||||
void vga_print_uint(unsigned int value)
|
||||
{
|
||||
char buffer[11];
|
||||
uitoa(value, buffer);
|
||||
vga_print(buffer);
|
||||
}
|
||||
|
||||
void vga_print_int(int value)
|
||||
{
|
||||
char buffer[12];
|
||||
|
||||
if (value < 0)
|
||||
{
|
||||
vga_print("-");
|
||||
unsigned int abs_val = (unsigned int)(-value);
|
||||
uitoa(abs_val, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
uitoa((unsigned int)value, buffer);
|
||||
}
|
||||
|
||||
vga_print(buffer);
|
||||
}
|
||||
@@ -26,9 +26,13 @@ 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);
|
||||
|
||||
void vga_print_uint(unsigned int value);
|
||||
void vga_print_int(int value);
|
||||
|
||||
static inline vga_color_t vga_color(vga_color_t fg_color, vga_color_t bg_color)
|
||||
{
|
||||
return fg_color | bg_color << 4;
|
||||
|
||||
Reference in New Issue
Block a user