idt
This commit is contained in:
2
makefile
2
makefile
@@ -1,7 +1,7 @@
|
|||||||
CC = x86_64-elf-gcc
|
CC = x86_64-elf-gcc
|
||||||
LD = x86_64-elf-ld
|
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 =
|
LDFLAGS =
|
||||||
|
|
||||||
all: .build/nub-os.iso
|
all: .build/nub-os.iso
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ section .text
|
|||||||
bits 32
|
bits 32
|
||||||
global _start
|
global _start
|
||||||
_start:
|
_start:
|
||||||
|
cli
|
||||||
mov esp, stack_top
|
mov esp, stack_top
|
||||||
|
|
||||||
; Check if CPU supports 64-bit mode
|
; 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
|
%macro isr_err_stub 1
|
||||||
isr_stub_%+%1:
|
isr_stub_%+%1:
|
||||||
call exception_handler
|
push %1
|
||||||
|
call interrput_handler
|
||||||
|
add rsp, 8
|
||||||
iretq
|
iretq
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
%macro isr_no_err_stub 1
|
%macro isr_no_err_stub 1
|
||||||
isr_stub_%+%1:
|
isr_stub_%+%1:
|
||||||
call exception_handler
|
push %1
|
||||||
|
call interrput_handler
|
||||||
|
add rsp, 8
|
||||||
iretq
|
iretq
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
extern exception_handler
|
|
||||||
isr_no_err_stub 0
|
isr_no_err_stub 0
|
||||||
isr_no_err_stub 1
|
isr_no_err_stub 1
|
||||||
isr_no_err_stub 2
|
isr_no_err_stub 2
|
||||||
@@ -51,3 +56,11 @@ isr_stub_table:
|
|||||||
dq isr_stub_%+i
|
dq isr_stub_%+i
|
||||||
%assign i i + 1
|
%assign i i + 1
|
||||||
%endrep
|
%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 "vga.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define IDT_MAX_DESCRIPTORS 255
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint16_t isr_low; // The lower 16 bits of the ISR's address
|
uint16_t address_low;
|
||||||
uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR
|
uint16_t selector;
|
||||||
uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now
|
uint8_t ist;
|
||||||
uint8_t attributes; // Type and attributes; see the IDT page
|
uint8_t flags;
|
||||||
uint16_t isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address
|
uint16_t address_mid;
|
||||||
uint32_t isr_high; // The higher 32 bits of the ISR's address
|
uint32_t address_high;
|
||||||
uint32_t reserved; // Set to zero
|
uint32_t reserved;
|
||||||
} __attribute__((packed)) idt_entry_t;
|
} __attribute__((packed)) interrupt_descriptor;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -21,45 +21,48 @@ typedef struct
|
|||||||
uint64_t base;
|
uint64_t base;
|
||||||
} __attribute__((packed)) idtr_t;
|
} __attribute__((packed)) idtr_t;
|
||||||
|
|
||||||
static idt_entry_t idt[256];
|
static interrupt_descriptor idt[256];
|
||||||
static idtr_t idtr;
|
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* 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)
|
void idt_init(void)
|
||||||
{
|
{
|
||||||
idtr.base = (uintptr_t)&idt[0];
|
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++)
|
for (uint8_t vector = 0; vector < 32; vector++)
|
||||||
{
|
{
|
||||||
idt_set_descriptor(vector, isr_stub_table[vector], 0x8E);
|
idt_set_descriptor(vector, isr_stub_table[vector], 0);
|
||||||
vectors[vector] = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__asm__ volatile("lidt %0" : : "m"(idtr));
|
__asm__ volatile("lidt %0" : : "m"(idtr));
|
||||||
__asm__ volatile("sti");
|
__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>
|
#include <stdint.h>
|
||||||
|
|
||||||
void idt_init(void);
|
void idt_init(void);
|
||||||
void exception_handler(void);
|
|
||||||
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags);
|
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags);
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ void kernel_main(void)
|
|||||||
vga_clear();
|
vga_clear();
|
||||||
|
|
||||||
idt_init();
|
idt_init();
|
||||||
|
vga_print_success("IDT intialzied\n");
|
||||||
|
|
||||||
vga_print("Welcome to nub OS\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_colored("success", VGA_GREEN);
|
||||||
vga_print(" ] ");
|
vga_print(" ] ");
|
||||||
vga_print(message);
|
vga_print(message);
|
||||||
vga_print("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void vga_print_error(const char* message)
|
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_colored("error", VGA_RED);
|
||||||
vga_print(" ] ");
|
vga_print(" ] ");
|
||||||
vga_print(message);
|
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_colored(const char* string, vga_color_t color);
|
||||||
void vga_print(const char* string);
|
void vga_print(const char* string);
|
||||||
|
|
||||||
void vga_print_success(const char* message);
|
void vga_print_success(const char* message);
|
||||||
void vga_print_error(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)
|
static inline vga_color_t vga_color(vga_color_t fg_color, vga_color_t bg_color)
|
||||||
{
|
{
|
||||||
return fg_color | bg_color << 4;
|
return fg_color | bg_color << 4;
|
||||||
|
|||||||
Reference in New Issue
Block a user