This commit is contained in:
nub31
2025-09-01 15:15:00 +02:00
parent 365ad14122
commit 25342b507d
5 changed files with 138 additions and 78 deletions

View File

@@ -1,5 +1,6 @@
global _start
extern kernel_main
extern setup_idt
%define FLAGS 0b10
%define MAGIC 0x1BADB002
@@ -25,6 +26,17 @@ section .bss
pd:
resb 4096
section .bss
align 8
idt64:
resb 4096
section .data
align 8
idt64_descriptor:
dw 4095 ; IDT size (256 entries * 16 bytes - 1)
dq idt64 ; IDT base address
section .data
align 8
gdt64:
@@ -140,6 +152,10 @@ section .text
mov fs, ax
mov gs, ax
mov ss, ax
call setup_idt
sti
call kernel_main
.hang:
hlt

114
src/idt.asm Normal file
View File

@@ -0,0 +1,114 @@
global setup_idt
extern handle_isr
%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
%macro GENERATE_NUB_ISR_NOERR 2
%assign i %1
%rep (%2 - %1 + 1)
ISR_NOERR i
%assign i i+1
%endrep
%endmacro
section .text
bits 64
setup_idt:
ret
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 handle_isr
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
; CPU exceptions 0-31. Some of there contain error codes, so we define them manually
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
; The remaining isr-s does not have an error code
GENERATE_ISRS 32, 255
%macro GENERATE_ISR_TABLE 2
%assign i %1
%rep (%2 - %1 + 1)
dq isr_stub_%[i]
%assign i i+1
%endrep
%endmacro
section .data
global isr_stub_table
isr_stub_table:
GENERATE_ISR_TABLE 0, 255

View File

@@ -1,31 +1,18 @@
#include "idt.h"
#include "vga.h"
#define IDT_SIZE 256
#include "kernel.h"
#define PIC1_COMMAND 0x20
#define PIC1_DATA 0x21
#define PIC2_COMMAND 0xA0
#define PIC2_DATA 0xA1
typedef struct
{
u16 address_low;
u16 selector;
u8 ist;
u8 flags;
u16 address_mid;
u32 address_high;
u32 reserved;
} __attribute__((packed)) interrupt_descriptor;
typedef struct
{
u16 limit;
u64 base;
} __attribute__((packed)) idtr_t;
extern void* isr_stub_table[];
static irq_handler_t irq_handlers[16] = {0};
static const char* exception_messages[32] = {
@@ -63,32 +50,17 @@ static const char* exception_messages[32] = {
"reserved",
};
static interrupt_descriptor idt[IDT_SIZE];
static void pic_remap(int offset1, int offset2)
void register_irq_handler(u8 irq, irq_handler_t handler)
{
u8 a1, a2;
if (irq >= 16)
{
kernel_panic();
}
a1 = inb(PIC1_DATA);
a2 = inb(PIC2_DATA);
outb(PIC1_COMMAND, 0x11);
outb(PIC2_COMMAND, 0x11);
outb(PIC1_DATA, offset1);
outb(PIC2_DATA, offset2);
outb(PIC1_DATA, 4);
outb(PIC2_DATA, 2);
outb(PIC1_DATA, 0x01);
outb(PIC2_DATA, 0x01);
outb(PIC1_DATA, a1);
outb(PIC2_DATA, a2);
irq_handlers[irq] = handler;
}
static void pic_send_eoi(u8 irq)
static inline void pic_send_eoi(u8 irq)
{
if (irq >= 8)
{
@@ -98,42 +70,6 @@ static void pic_send_eoi(u8 irq)
outb(PIC1_COMMAND, 0x20);
}
void register_irq_handler(u8 irq, irq_handler_t handler)
{
irq_handlers[irq] = handler;
}
static inline void idt_set_descriptor(u8 vector, void* handler, u8 dpl)
{
interrupt_descriptor* entry = &idt[vector];
entry->address_low = (u64)handler & 0xFFFF;
entry->address_mid = ((u64)handler >> 16) & 0xFFFF;
entry->address_high = (u64)handler >> 32;
entry->selector = 0x08;
entry->flags = 0b1110 | ((dpl & 0b11) << 5) | (1 << 7);
entry->ist = 0;
entry->reserved = 0;
}
void init_idt(void)
{
pic_remap(0x20, 0x28);
for (int i = 0; i < 256; i++)
{
idt_set_descriptor(i, isr_stub_table[i], 0);
}
idtr_t idtr = {
.base = (uintptr_t)&idt[0],
.limit = (u16)sizeof(interrupt_descriptor) * IDT_SIZE - 1,
};
__asm__ volatile("lidt %0" : : "m"(idtr));
__asm__ volatile("sti");
}
void handle_isr(isr_frame_t* frame)
{
if (frame->int_no < 32)

View File

@@ -13,8 +13,6 @@ typedef struct
typedef void (*irq_handler_t)(const isr_frame_t*);
void init_idt(void);
static inline void outb(u16 port, u8 val)
{
__asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port));

View File

@@ -9,10 +9,6 @@ void kernel_main()
vga_print_success();
vga_print(" VGA intialzied\n");
init_idt();
vga_print_success();
vga_print(" IDT intialzied\n");
init_keyboard();
vga_print_success();
vga_print(" Keyboard intialzied\n");