diff --git a/Makefile b/Makefile index 35e3688..ff90bb0 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,12 @@ default: run .FORCE: -include/shade/version.h: .FORCE +bin/shade.iso: bin/shade.bin + cp bin/shade.bin src/iso/boot/shade.bin + grub-mkrescue src/iso/ -o $@ + rm src/iso/boot/shade.bin + +bin/shade.bin: $(sboot_object_files) $(kernel_object_files) $(libc_object_files) echo "#ifndef VERSION_H" > include/shade/version.h echo "#define VERSION_H" >> include/shade/version.h echo "// This file was autogenerated by the shadeOS build system. It should not be modified." >> include/shade/version.h @@ -53,13 +58,6 @@ include/shade/version.h: .FORCE echo "#define SHADE_OS_COMPILE_DATE \"$(date)\"" >> include/shade/version.h echo "#define SHADE_OS_CODENAME \"$(codename)\"" >> include/shade/version.h echo "#endif" >> include/shade/version.h - -bin/shade.iso: bin/shade.bin - cp bin/shade.bin src/iso/boot/shade.bin - grub-mkrescue src/iso/ -o $@ - rm src/iso/boot/shade.bin - -bin/shade.bin: $(sboot_object_files) $(kernel_object_files) $(libc_object_files) mkdir -p "$(@D)" $(LD) $(LDFLAGS) -n -T $(shade_bin_ldfile) $^ -o $@ grub-file --is-x86-multiboot2 $@ diff --git a/bin/shade.bin b/bin/shade.bin index 67dff2a..612328a 100755 Binary files a/bin/shade.bin and b/bin/shade.bin differ diff --git a/bin/shade.iso b/bin/shade.iso index 5874439..a7b2e85 100644 Binary files a/bin/shade.iso and b/bin/shade.iso differ diff --git a/include/shade/platform/drivers/keyboard.h b/include/shade/platform/drivers/keyboard.h new file mode 100644 index 0000000..1b7cdec --- /dev/null +++ b/include/shade/platform/drivers/keyboard.h @@ -0,0 +1,6 @@ +#ifndef KEYBOARD_H +#define KEYBOARD_H + +void init_keyboard(); + +#endif \ No newline at end of file diff --git a/include/shade/platform/interrupts/isr.h b/include/shade/platform/interrupts/isr.h index 26c1fc8..eb6ec96 100644 --- a/include/shade/platform/interrupts/isr.h +++ b/include/shade/platform/interrupts/isr.h @@ -5,61 +5,38 @@ #define ERR_MAX 5 +#define IRQ_MIN 0x20 +#define IRQ_MAX 0x2f + +#define IRQ0 0x20 +#define IRQ1 0x21 +#define IRQ2 0x22 +#define IRQ3 0x23 +#define IRQ4 0x24 +#define IRQ5 0x25 +#define IRQ6 0x26 +#define IRQ7 0x27 +#define IRQ8 0x28 +#define IRQ9 0x29 +#define IRQ10 0x2a +#define IRQ11 0x2b +#define IRQ12 0x2c +#define IRQ13 0x2d +#define IRQ14 0x2e +#define IRQ15 0x2f + static int err_count = 0; -typedef struct { - struct { - uint64_t resv0; - uint64_t resv1; - uint64_t resv2; - uint64_t resv3; - } broken; - - struct { - uint64_t resv0; - uint64_t resv1; - uint64_t resv2; - uint64_t resv3; - uint64_t resv4; - uint64_t resv5; - } broken_2; - - struct { - uint64_t resv0; - uint64_t error_code; - uint64_t resv1; - uint64_t vector; - uint64_t resv2; - uint64_t resv3; - uint64_t resv4; - uint64_t resv5; - } base_frame; -} isr_xframe_t; - -/* -List of pushed things in order: -error_code -vector -rbp -rax -rbx -rcx -rdx -rsi -rdi -cr0 -cr2 -cr3 -cr4 -ds -0 - -*/ +static void (*interrupt_handlers[256]) (uint8_t vector, uint16_t err); __attribute__((noreturn)) void exception_handler(uint8_t vector, uint16_t err); -__attribute__((noreturn)) -void interrupt_handler(isr_xframe_t frame); +int register_interrupt_handler(int vector, void (*handler)(uint8_t, uint16_t)); +int unregister_interrupt_handler(int vector); + +void default_handler(uint8_t vector, uint16_t err); + +void fill_isr(); #endif \ No newline at end of file diff --git a/include/shade/platform/interrupts/pic.h b/include/shade/platform/interrupts/pic.h index 568e15a..d83689e 100644 --- a/include/shade/platform/interrupts/pic.h +++ b/include/shade/platform/interrupts/pic.h @@ -27,6 +27,22 @@ #define PIC_READ_IRR 0x0a /* OCW3 irq ready next CMD read */ #define PIC_READ_ISR 0x0b /* OCW3 irq service next CMD read */ +#define IRQ_PIT 0 +#define IRQ_KEYBOARD 1 +#define IRQ_INTERNAL 2 +#define IRQ_COM2 3 +#define IRQ_COM1 4 +#define IRQ_LPT2 5 +#define IRQ_FLOPPY 6 +#define IRQ_LPT1 7 +#define IRQ_CMOS 8 +#define IRQ_UNUSED 9 +#define IRQ_UNUSED 10 +#define IRQ_UNUSED 11 +#define IRQ_PS2_MOUSE 12 +#define IRQ_FPU 13 +#define IRQ_ATA_PRIMARY 14 +#define IRQ_ATA_SECONDARY 15 void pic_send_eoi(uint8_t irq); void pic_remap(int offset1, int offset2); diff --git a/include/shade/version.h b/include/shade/version.h index b2db027..d1f2ec2 100644 --- a/include/shade/version.h +++ b/include/shade/version.h @@ -3,7 +3,7 @@ // This file was autogenerated by the shadeOS build system. It should not be modified. #define SHADE_OS_KERNEL_VERSION "0.1.1-alpha" #define SHADE_OS_KERNEL "shade-development" -#define SHADE_OS_BUILD "b4e6b2e" -#define SHADE_OS_COMPILE_DATE "Sun May 15 05:41:17 PM EDT 2022" +#define SHADE_OS_BUILD "20b96b2" +#define SHADE_OS_COMPILE_DATE "Sun May 15 07:01:51 PM EDT 2022" #define SHADE_OS_CODENAME "willow" #endif diff --git a/obj/kernel/kernel.o b/obj/kernel/kernel.o index feca931..300f5fc 100644 Binary files a/obj/kernel/kernel.o and b/obj/kernel/kernel.o differ diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index aa7f52f..b8a19fc 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -1,7 +1,10 @@ #include #include #include +#include #include +#include +#include #include #include #include @@ -37,8 +40,20 @@ void kmain() { kprintf("The full license can be found at /sys/LICENCE on this system or ./LICENCE in the source tree.\n"); pic_remap(0x20, 0x28); + fill_isr(); // ISR must be filled before interrupts are enabled idt_assemble(); - kmsg_ok("Enabled interrupts\n"); + kmsg_ok("Enabled interrupts"); + + init_keyboard(); + + idt_disable_interrupts(); + outb(0x21,0xfd); + outb(0xa1,0xff); + idt_enable_interrupts(); + + kmsg_ok("Enabled keyboard"); + + __asm__ __volatile__ ("int $2"); for (;;) {} } \ No newline at end of file diff --git a/src/kernel/platform/drivers/keyboard.c b/src/kernel/platform/drivers/keyboard.c new file mode 100644 index 0000000..31a4569 --- /dev/null +++ b/src/kernel/platform/drivers/keyboard.c @@ -0,0 +1,209 @@ +#include +#include +#include +#include +#include +#include + +void keyboard_callback(uint8_t vector, uint16_t err) { + // PIC leaves scancode in port 0x60 + uint8_t scancode = inb(0x60); + print_letter(scancode); +} + +void init_keyboard() { + register_interrupt_handler(IRQ1, keyboard_callback); + pic_unmask_irq(IRQ_KEYBOARD); +} + +void print_letter(uint8_t scancode) { + switch (scancode) { + case 0x0: + kprintf("ERROR"); + break; + case 0x1: + kprintf("ESC"); + break; + case 0x2: + kprintf("1"); + break; + case 0x3: + kprintf("2"); + break; + case 0x4: + kprintf("3"); + break; + case 0x5: + kprintf("4"); + break; + case 0x6: + kprintf("5"); + break; + case 0x7: + kprintf("6"); + break; + case 0x8: + kprintf("7"); + break; + case 0x9: + kprintf("8"); + break; + case 0x0A: + kprintf("9"); + break; + case 0x0B: + kprintf("0"); + break; + case 0x0C: + kprintf("-"); + break; + case 0x0D: + kprintf("+"); + break; + case 0x0E: + kprintf("Backspace"); + break; + case 0x0F: + kprintf("Tab"); + break; + case 0x10: + kprintf("Q"); + break; + case 0x11: + kprintf("W"); + break; + case 0x12: + kprintf("E"); + break; + case 0x13: + kprintf("R"); + break; + case 0x14: + kprintf("T"); + break; + case 0x15: + kprintf("Y"); + break; + case 0x16: + kprintf("U"); + break; + case 0x17: + kprintf("I"); + break; + case 0x18: + kprintf("O"); + break; + case 0x19: + kprintf("P"); + break; + case 0x1A: + kprintf("["); + break; + case 0x1B: + kprintf("]"); + break; + case 0x1C: + kprintf("ENTER"); + break; + case 0x1D: + kprintf("LCtrl"); + break; + case 0x1E: + kprintf("A"); + break; + case 0x1F: + kprintf("S"); + break; + case 0x20: + kprintf("D"); + break; + case 0x21: + kprintf("F"); + break; + case 0x22: + kprintf("G"); + break; + case 0x23: + kprintf("H"); + break; + case 0x24: + kprintf("J"); + break; + case 0x25: + kprintf("K"); + break; + case 0x26: + kprintf("L"); + break; + case 0x27: + kprintf(";"); + break; + case 0x28: + kprintf("'"); + break; + case 0x29: + kprintf("`"); + break; + case 0x2A: + kprintf("LShift"); + break; + case 0x2B: + kprintf("\\"); + break; + case 0x2C: + kprintf("Z"); + break; + case 0x2D: + kprintf("X"); + break; + case 0x2E: + kprintf("C"); + break; + case 0x2F: + kprintf("V"); + break; + case 0x30: + kprintf("B"); + break; + case 0x31: + kprintf("N"); + break; + case 0x32: + kprintf("M"); + break; + case 0x33: + kprintf(","); + break; + case 0x34: + kprintf("."); + break; + case 0x35: + kprintf("/"); + break; + case 0x36: + kprintf("Rshift"); + break; + case 0x37: + kprintf("Keypad *"); + break; + case 0x38: + kprintf("LAlt"); + break; + case 0x39: + kprintf("Spc"); + break; + default: + /* 'keuyp' event corresponds to the 'keydown' + 0x80 + * it may still be a scancode we haven't implemented yet, or + * maybe a control/escape sequence */ + /* + if (scancode <= 0x7f) { + kprintf("Unknown key down"); + } else if (scancode <= 0x39 + 0x80) { + kprintf("key up "); + print_letter(scancode - 0x80); + } else kprintf("Unknown key up"); + */ + break; + } +} \ No newline at end of file diff --git a/src/kernel/platform/interrupts/isr.c b/src/kernel/platform/interrupts/isr.c index 2790c63..c94bcf1 100644 --- a/src/kernel/platform/interrupts/isr.c +++ b/src/kernel/platform/interrupts/isr.c @@ -1,11 +1,35 @@ #include #include +#include void exception_handler(uint8_t vector, uint16_t err) { + (*interrupt_handlers[vector])(vector, err); + if (vector >= IRQ_MIN && vector <= IRQ_MAX) { + // needs EOI + pic_send_eoi(vector); + } +} + +int register_interrupt_handler(int vector, void (*handler)(uint8_t, uint16_t)) { + interrupt_handlers[vector] = handler; +} + +int unregister_interrupt_handler(int vector) { + interrupt_handlers[vector] = default_handler; +} + +void default_handler(uint8_t vector, uint16_t err) { kprintf(" %i: cpu: check_exception 0x%x err_code => %x\n", err_count, vector, err); + kprintf(" %i: cpu: no irq for vector 0x%x\n", err_count, vector); err_count++; if (err_count > ERR_MAX) { kprintf("cpu: ierr hit err_max, halt\n"); __asm__ __volatile__("cli; hlt"); } +} + +void fill_isr() { + for (int i = 0; i < 256; i++) { + register_interrupt_handler(i, default_handler); + } } \ No newline at end of file diff --git a/src/kernel/platform/interrupts/pic.c b/src/kernel/platform/interrupts/pic.c index e312c8a..542c913 100644 --- a/src/kernel/platform/interrupts/pic.c +++ b/src/kernel/platform/interrupts/pic.c @@ -1,5 +1,6 @@ #include #include +#include void pic_send_eoi(uint8_t irq) { if (irq >= 8) { @@ -37,6 +38,7 @@ void pic_remap(int offset1, int offset2) { } void pic_mask_irq(uint8_t irq) { + idt_disable_interrupts(); uint16_t port; uint8_t value; @@ -48,9 +50,11 @@ void pic_mask_irq(uint8_t irq) { } value = inb(port) | (1 << irq); outb(port, value); + idt_enable_interrupts(); } void pic_unmask_irq(uint8_t irq) { + idt_disable_interrupts(); uint16_t port; uint8_t value; @@ -62,6 +66,7 @@ void pic_unmask_irq(uint8_t irq) { } value = inb(port) & ~(1 << irq); outb(port, value); + idt_enable_interrupts(); } static uint16_t __pic_get_irq_reg(int ocw3) {