interrupts
This commit is contained in:
4
grub.cfg
4
grub.cfg
@@ -1,3 +1,7 @@
|
|||||||
menuentry "nub-os" {
|
menuentry "nub-os" {
|
||||||
multiboot2 /boot/kernel
|
multiboot2 /boot/kernel
|
||||||
|
boot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set default="nub-os"
|
||||||
|
set timeout=0
|
||||||
|
|||||||
12
makefile
12
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 -Werror -Wshadow -std=c23
|
CFLAGS = -m64 -ffreestanding -fno-builtin -Wall -Wextra -Wshadow -std=c23
|
||||||
LDFLAGS =
|
LDFLAGS =
|
||||||
|
|
||||||
all: .build/nub-os.iso
|
all: .build/nub-os.iso
|
||||||
@@ -18,8 +18,8 @@ build-dir:
|
|||||||
cp .build/kernel .build/iso/boot/
|
cp .build/kernel .build/iso/boot/
|
||||||
grub-mkrescue -o .build/nub-os.iso .build/iso/
|
grub-mkrescue -o .build/nub-os.iso .build/iso/
|
||||||
|
|
||||||
.build/kernel: build-dir .build/boot.o .build/kernel.o .build/vga.o
|
.build/kernel: build-dir .build/boot.o .build/kernel.o .build/vga.o .build/idt.o .build/idt2.o
|
||||||
$(LD) $(LDFLAGS) -T src/boot.ld -o .build/kernel .build/boot.o .build/kernel.o .build/vga.o
|
$(LD) $(LDFLAGS) -T src/boot.ld -o .build/kernel .build/boot.o .build/kernel.o .build/vga.o .build/idt.o .build/idt2.o
|
||||||
|
|
||||||
.build/kernel.o: build-dir src/kernel.c
|
.build/kernel.o: build-dir src/kernel.c
|
||||||
$(CC) $(CFLAGS) -c -o .build/kernel.o src/kernel.c
|
$(CC) $(CFLAGS) -c -o .build/kernel.o src/kernel.c
|
||||||
@@ -27,5 +27,11 @@ build-dir:
|
|||||||
.build/vga.o: build-dir src/vga.c
|
.build/vga.o: build-dir src/vga.c
|
||||||
$(CC) $(CFLAGS) -c -o .build/vga.o src/vga.c
|
$(CC) $(CFLAGS) -c -o .build/vga.o src/vga.c
|
||||||
|
|
||||||
|
.build/idt.o: build-dir src/idt.c
|
||||||
|
$(CC) $(CFLAGS) -c -o .build/idt.o src/idt.c
|
||||||
|
|
||||||
|
.build/idt2.o: build-dir src/idt.asm
|
||||||
|
nasm -f elf64 -o .build/idt2.o src/idt.asm
|
||||||
|
|
||||||
.build/boot.o: build-dir src/boot.asm
|
.build/boot.o: build-dir src/boot.asm
|
||||||
nasm -f elf64 -o .build/boot.o src/boot.asm
|
nasm -f elf64 -o .build/boot.o src/boot.asm
|
||||||
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"
|
#include "vga.h"
|
||||||
|
|
||||||
void kernel_main(void)
|
void kernel_main(void)
|
||||||
{
|
{
|
||||||
vga_clear();
|
vga_clear();
|
||||||
|
|
||||||
|
idt_init();
|
||||||
|
|
||||||
vga_print("Welcome to nub OS\n");
|
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)
|
void vga_print(const char* string)
|
||||||
{
|
{
|
||||||
vga_print_colored(string, vga_default_color());
|
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_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_error(const char* message);
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user