From 2725b95a1f78d2feac553d37252f2e560c2f9aac Mon Sep 17 00:00:00 2001 From: Carlos Maiolino Date: Fri, 1 Aug 2025 21:03:16 +0200 Subject: Setup interrupt handling Remap master PIC to IOAddress 0x20 to avoid collisions with CPU exceptions. Setup a default interrupt handler and map all interrupts to this handler by default. Setup a Keyboard interrupt handler for testing purposes Wire everything up in the Makefile Signed-off-by: Carlos Maiolino --- Makefile | 6 +++++- src/boot/bootloader.asm | 4 +++- src/idt/idt.asm | 24 +++++++++++++++++++++++- src/idt/idt.c | 23 +++++++++++++++++++++++ src/kernel.asm | 13 +++++++++++++ src/kernel.c | 3 +++ 6 files changed, 70 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 51493cd..040c846 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,8 @@ KOBJ_FILES = $(KERNEL_ASM_OBJ) \ $(KERNEL_OBJ) \ ./build/vga.o \ ./build/idt/idt.asm.o \ - ./build/idt/idt.o + ./build/idt/idt.o \ + ./build/io/io.asm.o BOOT_TGT =./bin/boot.bin @@ -57,6 +58,8 @@ $(BUILD_DIR)/idt/idt.asm.o: ./src/idt/idt.asm $(BUILD_DIR)/idt/idt.o: ./src/idt/idt.c ./build/vga.o $(KOBJ_LIBS) i686-elf-gcc $(INCLUDES) $(FLAGS) -std=gnu99 -c ./src/idt/idt.c -o $(BUILD_DIR)/idt/idt.o +$(BUILD_DIR)/io/io.asm.o: ./src/io/io.asm + nasm -f elf -g ./src/io/io.asm -o $(BUILD_DIR)/io/io.asm.o $(KOBJ_LIBS): i686-elf-gcc $(INCLUDES) $(FLAGS) -std=gnu99 -c ./src/lib/string.c -o $(BUILD_DIR)/string.o @@ -70,4 +73,5 @@ clean: rm -f build/string.o rm -f build/idt/idt.asm.o rm -f build/idt/idt.o + rm -f build/io/io.asm.o rm -f bin/os.bin diff --git a/src/boot/bootloader.asm b/src/boot/bootloader.asm index 4b803fa..918ff9b 100644 --- a/src/boot/bootloader.asm +++ b/src/boot/bootloader.asm @@ -30,7 +30,9 @@ step2: sti ; Enable interrupts .load_protected: - cli + cli ; Interrupts will be disabled until we finish setting up the interrupt + ; table and remapping the PIC controllers + ; Interrupts will be enabled back in _start symbol in kernel.asm lgdt[gdt_table] mov eax, cr0 or eax, 0x1 diff --git a/src/idt/idt.asm b/src/idt/idt.asm index 998a242..235f46b 100644 --- a/src/idt/idt.asm +++ b/src/idt/idt.asm @@ -1,6 +1,12 @@ section .asm -global idt_load: +extern int21h_handler +extern default_int_handler + +global int21h +global default_handler +global idt_load + idt_load: push ebp @@ -11,3 +17,19 @@ idt_load: pop ebp ret + +int21h: + cli + pushad ; Push all general-purpose registers to the stack + call int21h_handler + popad + sti + iret + +default_handler: + cli + pushad ; Push all general-purpose registers to the stack + call default_int_handler + popad + sti + iret diff --git a/src/idt/idt.c b/src/idt/idt.c index d7a6743..a83c612 100644 --- a/src/idt/idt.c +++ b/src/idt/idt.c @@ -3,11 +3,28 @@ #include #include #include +#include struct int_descriptor int_table[TOTAL_INTERRUPTS]; struct int_reg_descriptor idtr_descriptor; extern void idt_load(struct int_reg_descriptor *desc); +extern void int21h(); +extern void default_handler(); + +void +int21h_handler(void) +{ + vprintl("Keyboard pressed\n"); + outb(0x20, 0x20); +} + +void +default_int_handler(void) +{ + /* Ack the Interrupt */ + outb(0x20, 0x20); +} static void idt_zero() @@ -30,12 +47,18 @@ idt_set(int int_num, void *addr) void interrupts_init(void) { + int i; + memset(int_table, 0, sizeof(int_table)); idtr_descriptor.limit = sizeof(int_table) - 1; idtr_descriptor.base = (uint32_t) int_table; + for (i = 0; i < TOTAL_INTERRUPTS; i++) + idt_set(i, default_handler); + idt_set(0, idt_zero); + idt_set(0x21, int21h); idt_load(&idtr_descriptor); } diff --git a/src/kernel.asm b/src/kernel.asm index 252fd7b..bd22761 100644 --- a/src/kernel.asm +++ b/src/kernel.asm @@ -24,6 +24,19 @@ _start: or al, 2 out 0x92, al + + ; Remap master PIC + mov al, 00010001b + out 0x20, al ; MasterPIC + + mov al, 0x20 ; Start master ISR at 0x20 + out 0x21, al + + mov al, 00000001b ; Put the PIC in x86 mode + out 0x21, al + + sti + ; Jump to C code call start_kernel jmp $ diff --git a/src/kernel.c b/src/kernel.c index c2a0150..8a8bd61 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -4,11 +4,14 @@ #include #include #include +#include void start_kernel() { init_display(2); vprintl("Hello World!!!\n"); + vprintl("Testing it!!!\n"); interrupts_init(); + } -- cgit v1.2.3