irq improvements

This commit is contained in:
nub31
2025-08-24 20:39:23 +02:00
parent bbd4b62697
commit bffea5b0c1
5 changed files with 156 additions and 82 deletions

View File

@@ -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/idt.o .build/idt2.o .build/kernel: build-dir .build/boot.o .build/kernel.o .build/vga.o .build/idt.o .build/idt_stub.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 $(LD) $(LDFLAGS) -T src/boot.ld -o .build/kernel .build/boot.o .build/kernel.o .build/vga.o .build/idt.o .build/idt_stub.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
@@ -30,8 +30,8 @@ build-dir:
.build/idt.o: build-dir src/idt.c .build/idt.o: build-dir src/idt.c
$(CC) $(CFLAGS) -c -o .build/idt.o src/idt.c $(CC) $(CFLAGS) -c -o .build/idt.o src/idt.c
.build/idt2.o: build-dir src/idt.asm .build/idt_stub.o: build-dir src/idt_stub.asm
nasm -f elf64 -o .build/idt2.o src/idt.asm nasm -f elf64 -o .build/idt_stub.o src/idt_stub.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

View File

@@ -1,62 +0,0 @@
extern interrput_handler
%macro isr_err_stub 1
isr_stub_%+%1:
call interrput_handler
iretq
%endmacro
%macro isr_no_err_stub 1
isr_stub_%+%1:
call interrput_handler
iretq
%endmacro
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
.text
global idt_hang
idt_hang:
cli
.loop:
hlt
jmp .loop

View File

@@ -21,10 +21,20 @@ typedef struct
uint64_t base; uint64_t base;
} __attribute__((packed)) idtr_t; } __attribute__((packed)) idtr_t;
static interrupt_descriptor idt[256]; typedef struct
static idtr_t idtr; {
uint64_t r15, r14, r13, r12, r11, r10, r9, r8;
uint64_t rbp, rdi, rsi, rdx, rcx, rbx, rax;
uint64_t int_no;
uint64_t err_code;
uint64_t rip, cs, rflags, rsp, ss;
} __attribute__((packed)) isr_frame_t;
#define IDT_SIZE 256
extern void* isr_stub_table[]; extern void* isr_stub_table[];
extern void idt_hang();
static interrupt_descriptor idt[IDT_SIZE];
void idt_set_descriptor(uint8_t vector, void* handler, uint8_t dpl) void idt_set_descriptor(uint8_t vector, void* handler, uint8_t dpl)
{ {
@@ -39,22 +49,27 @@ void idt_set_descriptor(uint8_t vector, void* handler, uint8_t dpl)
entry->reserved = 0; entry->reserved = 0;
} }
void exception_handler(isr_frame_t* frame)
{
vga_print("Interrupt\n");
vga_print(" int_no:");
vga_print_uint(frame->int_no);
vga_print("\n");
vga_print(" err_code:");
vga_print_uint(frame->err_code);
vga_print("\n");
__asm__ volatile("cli; hlt");
}
void idt_init(void) void idt_init(void)
{ {
idtr.base = (uintptr_t)&idt[0]; for (int i = 0; i < 32; i++)
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], 0); idt_set_descriptor(i, isr_stub_table[i], 0);
} }
idtr_t idtr = { .base = (uintptr_t)&idt[0], .limit = (uint16_t)sizeof(interrupt_descriptor) * IDT_SIZE - 1 };
__asm__ volatile("lidt %0" : : "m"(idtr)); __asm__ volatile("lidt %0" : : "m"(idtr));
__asm__ volatile("sti"); __asm__ volatile("sti");
} }
void interrput_handler()
{
vga_print("An interrupt happened\n");
idt_hang();
}

121
src/idt_stub.asm Normal file
View File

@@ -0,0 +1,121 @@
extern exception_handler
%macro ISR_NOERR 1
isr_stub_%1:
push qword 0
push qword %1
jmp isr_common
%endmacro
%macro ISR_ERR 1
isr_stub_%1:
push qword %1
jmp isr_common
%endmacro
isr_common:
push rax
push rbx
push rcx
push rdx
push rsi
push rdi
push rbp
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
mov rdi, rsp
call exception_handler
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rbp
pop rdi
pop rsi
pop rdx
pop rcx
pop rbx
pop rax
add rsp, 16
iretq
ISR_NOERR 0
ISR_NOERR 1
ISR_NOERR 2
ISR_NOERR 3
ISR_NOERR 4
ISR_NOERR 5
ISR_NOERR 6
ISR_NOERR 7
ISR_ERR 8
ISR_NOERR 9
ISR_ERR 10
ISR_ERR 11
ISR_ERR 12
ISR_ERR 13
ISR_ERR 14
ISR_NOERR 15
ISR_NOERR 16
ISR_ERR 17
ISR_NOERR 18
ISR_NOERR 19
ISR_NOERR 20
ISR_NOERR 21
ISR_NOERR 22
ISR_NOERR 23
ISR_NOERR 24
ISR_NOERR 25
ISR_NOERR 26
ISR_NOERR 27
ISR_NOERR 28
ISR_NOERR 29
ISR_ERR 30
ISR_NOERR 31
global isr_stub_table
isr_stub_table:
dq isr_stub_0
dq isr_stub_1
dq isr_stub_2
dq isr_stub_3
dq isr_stub_4
dq isr_stub_5
dq isr_stub_6
dq isr_stub_7
dq isr_stub_8
dq isr_stub_9
dq isr_stub_10
dq isr_stub_11
dq isr_stub_12
dq isr_stub_13
dq isr_stub_14
dq isr_stub_15
dq isr_stub_16
dq isr_stub_17
dq isr_stub_18
dq isr_stub_19
dq isr_stub_20
dq isr_stub_21
dq isr_stub_22
dq isr_stub_23
dq isr_stub_24
dq isr_stub_25
dq isr_stub_26
dq isr_stub_27
dq isr_stub_28
dq isr_stub_29
dq isr_stub_30
dq isr_stub_31

View File

@@ -10,5 +10,5 @@ void kernel_main(void)
vga_print("Welcome to nub OS\n"); vga_print("Welcome to nub OS\n");
__asm__ volatile("int $255"); int i = 2 / 0;
} }