diff --git a/OVMFbin/OVMF_VARS-pure-efi.fd b/OVMFbin/OVMF_VARS-pure-efi.fd index 9bf4b9b..77e762c 100644 Binary files a/OVMFbin/OVMF_VARS-pure-efi.fd and b/OVMFbin/OVMF_VARS-pure-efi.fd differ diff --git a/kernel/bin/CustomOS.img b/kernel/bin/CustomOS.img index 1e056f2..655e3c1 100644 Binary files a/kernel/bin/CustomOS.img and b/kernel/bin/CustomOS.img differ diff --git a/kernel/bin/kernel.elf b/kernel/bin/kernel.elf index e778908..3b7fde3 100755 Binary files a/kernel/bin/kernel.elf and b/kernel/bin/kernel.elf differ diff --git a/kernel/lib/IO.o b/kernel/lib/IO.o new file mode 100644 index 0000000..5ac9739 Binary files /dev/null and b/kernel/lib/IO.o differ diff --git a/kernel/lib/interrupts/interrupts.o b/kernel/lib/interrupts/interrupts.o index 8d51695..9cd6d79 100644 Binary files a/kernel/lib/interrupts/interrupts.o and b/kernel/lib/interrupts/interrupts.o differ diff --git a/kernel/lib/kernel.o b/kernel/lib/kernel.o index 398d0c2..907aff0 100644 Binary files a/kernel/lib/kernel.o and b/kernel/lib/kernel.o differ diff --git a/kernel/lib/kernelUtil.o b/kernel/lib/kernelUtil.o index 2bf1569..51112a9 100644 Binary files a/kernel/lib/kernelUtil.o and b/kernel/lib/kernelUtil.o differ diff --git a/kernel/src/IO.cpp b/kernel/src/IO.cpp new file mode 100644 index 0000000..5afd648 --- /dev/null +++ b/kernel/src/IO.cpp @@ -0,0 +1,17 @@ +#include "IO.h" + +void outb(uint16_t port, uint8_t value){ + asm volatile ("outb %0, %1" : : "a"(value), "Nd"(port)); +} + +uint8_t inb(uint16_t port){ + uint8_t returnVal; + asm volatile ("inb %1, %0" + : "=a"(returnVal) + : "Nd"(port)); + return returnVal; +} + +void io_wait(){ + asm volatile ("outb %%al, $0x80" : : "a"(0)); +} \ No newline at end of file diff --git a/kernel/src/IO.h b/kernel/src/IO.h new file mode 100644 index 0000000..973af11 --- /dev/null +++ b/kernel/src/IO.h @@ -0,0 +1,6 @@ +#pragma once +#include + +void outb(uint16_t port, uint8_t value); +uint8_t inb(uint16_t port); +void io_wait(); \ No newline at end of file diff --git a/kernel/src/interrupts/interrupts.cpp b/kernel/src/interrupts/interrupts.cpp index ead8eb9..4cf7d17 100644 --- a/kernel/src/interrupts/interrupts.cpp +++ b/kernel/src/interrupts/interrupts.cpp @@ -1,5 +1,6 @@ #include "interrupts.h" #include "../panic.h" +#include "../IO.h" __attribute__((interrupt)) void PageFault_Handler(struct interrupt_frame* frame) { Panic("Page Fault"); @@ -14,4 +15,59 @@ __attribute__((interrupt)) void DoubleFault_Handler(struct interrupt_frame* fram __attribute__((interrupt)) void GPFault_Handler(struct interrupt_frame* frame) { Panic("General Protection Fault"); while (true); +} + +__attribute__((interrupt)) void KeyboardInterrupt_Handler(struct interrupt_frame* frame) { + GlobalRenderer->Print("A"); + + uint8_t scancode = inb(0x60); + + PIC_EndMaster(); +} + +void PIC_EndMaster() { + outb(PIC1_COMMAND, PIC_EOI); +} + +void PIC_EndSlave() { + outb(PIC2_COMMAND, PIC_EOI); + outb(PIC1_COMMAND, PIC_EOI); +} + +void RemapPIC() { + uint8_t a1, a2; + + a1 = inb(PIC1_DATA); + io_wait(); + a2 = inb(PIC2_DATA); + io_wait(); + + // init master + outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); + io_wait(); + // init slave + outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); + io_wait(); + + outb(PIC1_DATA, 0x20); + io_wait(); + outb(PIC2_DATA, 0x28); + io_wait(); + + // tell the pic chips how they correspond to eachother so they can chat + outb(PIC1_DATA, 4); + io_wait(); + outb(PIC2_DATA, 2); + io_wait(); + + outb(PIC1_DATA, ICW4_8086); + io_wait(); + outb(PIC2_DATA, ICW4_8086); + io_wait(); + + // restore bitmasks we saved earlier + outb(PIC1_DATA, a1); + io_wait(); + outb(PIC2_DATA, a2); + io_wait(); } \ No newline at end of file diff --git a/kernel/src/interrupts/interrupts.h b/kernel/src/interrupts/interrupts.h index c14ef68..5529e8c 100644 --- a/kernel/src/interrupts/interrupts.h +++ b/kernel/src/interrupts/interrupts.h @@ -1,8 +1,23 @@ #pragma once #include "../BasicRenderer.h" -struct interrupt_frame; +#define PIC1_COMMAND 0x20 +#define PIC1_DATA 0x21 +#define PIC2_COMMAND 0xA0 +#define PIC2_DATA 0xA1 +#define PIC_EOI 0x20 +#define ICW1_INIT 0x10 +#define ICW1_ICW4 0x01 +#define ICW4_8086 0x01 + +struct interrupt_frame; __attribute__((interrupt)) void PageFault_Handler(struct interrupt_frame* frame); __attribute__((interrupt)) void DoubleFault_Handler(struct interrupt_frame* frame); -__attribute__((interrupt)) void GPFault_Handler(struct interrupt_frame* frame); \ No newline at end of file +__attribute__((interrupt)) void GPFault_Handler(struct interrupt_frame* frame); + +__attribute__((interrupt)) void KeyboardInterrupt_Handler(struct interrupt_frame* frame); + +void RemapPIC(); +void PIC_EndMaster(); +void PIC_EndSlave(); \ No newline at end of file diff --git a/kernel/src/kernel.cpp b/kernel/src/kernel.cpp index b0c76ba..7f792e4 100644 --- a/kernel/src/kernel.cpp +++ b/kernel/src/kernel.cpp @@ -8,8 +8,6 @@ extern "C" void _start(BootInfo* bootInfo) { GlobalRenderer->Print("Kernel initialized successfully!"); GlobalRenderer->Next(); - asm("int $0x0e"); - // make sure we never return from our OS while (true); } \ No newline at end of file diff --git a/kernel/src/kernelUtil.cpp b/kernel/src/kernelUtil.cpp index 6de702c..178db35 100644 --- a/kernel/src/kernelUtil.cpp +++ b/kernel/src/kernelUtil.cpp @@ -8,6 +8,7 @@ extern "C" void __stack_chk_fail(void) { #include "gdt/gdt.h" #include "interrupts/IDT.h" #include "interrupts/interrupts.h" +#include "IO.h" KernelInfo kernelInfo; PageTableManager pageTableManager = NULL; @@ -64,8 +65,20 @@ void PrepareInterrupts() { int_GPFault->type_attr = IDT_TA_InterruptGate; int_GPFault->selector = 0x08; // kernel code segment + IDTDescEntry* int_Keyboard = (IDTDescEntry*)(idtr.Offset + 0x21 * sizeof(IDTDescEntry)); + int_Keyboard->SetOffset((uint64_t)KeyboardInterrupt_Handler); + int_Keyboard->type_attr = IDT_TA_InterruptGate; + int_Keyboard->selector = 0x08; // kernel code segment + // load idt asm("lidt %0" : : "m" (idtr)); + + // remap pic so we can get hardware interrupts + RemapPIC(); + outb(PIC1_DATA, 0b11111101); // unmask 2nd interrupt + outb(PIC2_DATA, 0b11111111); + + asm ("sti"); } BasicRenderer r = BasicRenderer(NULL, NULL);