diff options
author | aqua <aqua@iserlohn-fortress.net> | 2022-10-31 15:39:51 +0200 |
---|---|---|
committer | aqua <aqua@iserlohn-fortress.net> | 2022-10-31 21:59:49 +0200 |
commit | cbd3cdf7cb34529e269bb27c654765a0c9c21799 (patch) | |
tree | 4ee555d5cb575af003e10e597666b4a7b17b17a7 | |
parent | makefile: auto-generate OBJS from SRCS (diff) | |
download | kernel-cbd3cdf7cb34529e269bb27c654765a0c9c21799.tar.xz |
add ps2_keyboard driver
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | devices/Makefile | 4 | ||||
-rw-r--r-- | devices/pic_8259.c | 2 | ||||
-rw-r--r-- | devices/ps2_keyboard.c | 40 | ||||
-rw-r--r-- | devices/ps2_keyboard.h | 4 | ||||
-rw-r--r-- | devices/uart_16550.h | 1 | ||||
-rw-r--r-- | i686/Makefile | 4 | ||||
-rw-r--r-- | i686/idt.h | 8 | ||||
-rw-r--r-- | i686/init.s | 2 | ||||
-rw-r--r-- | i686/isr.c | 42 | ||||
-rw-r--r-- | i686/lidt.c | 12 | ||||
-rw-r--r-- | lib/stdio/printf.c | 4 | ||||
-rw-r--r-- | src/Makefile | 2 | ||||
-rw-r--r-- | src/isr.c | 38 | ||||
-rw-r--r-- | src/kernel.c | 3 |
15 files changed, 117 insertions, 50 deletions
@@ -43,6 +43,7 @@ glitch.iso: glitch.elf grub/grub.cfg @grub-file --is-x86-multiboot2 glitch.elf @mkdir -p isodir/boot/grub @mkdir -p isodir/boot/glitch + @grub-script-check grub/grub.cfg @cp grub/grub.cfg isodir/boot/grub/grub.cfg @cp glitch.elf isodir/boot/glitch/glitch.elf @grub-mkrescue -o glitch.iso isodir diff --git a/devices/Makefile b/devices/Makefile index 41edaaa..0e07a83 100644 --- a/devices/Makefile +++ b/devices/Makefile @@ -1,10 +1,10 @@ include ../${ARCH}/toolchain.mk -CCFLAGS += -I. -I../${ARCH} +CCFLAGS += -I. -I../${ARCH} -I../lib all: devs.a -devs,SRCS = pic_8259.c uart_16550.c vga.c +devs,SRCS = pic_8259.c uart_16550.c vga.c ps2_keyboard.c include ../rules.mk diff --git a/devices/pic_8259.c b/devices/pic_8259.c index 43b090f..74c576a 100644 --- a/devices/pic_8259.c +++ b/devices/pic_8259.c @@ -28,7 +28,7 @@ pic_init() outb(ICW4_8086, PIC2 + DATA); // PIC masks - outb(0xff, PIC1 + DATA); + outb(0xfc, PIC1 + DATA); outb(0xff, PIC2 + DATA); } diff --git a/devices/ps2_keyboard.c b/devices/ps2_keyboard.c new file mode 100644 index 0000000..6171d18 --- /dev/null +++ b/devices/ps2_keyboard.c @@ -0,0 +1,40 @@ +#include "ps2_keyboard.h" +#include <stdint.h> +#include <stdio.h> +#include <sys/io.h> + +const uint8_t comm_port = 0x64; // r status register + // w command register +const uint8_t comm_enable_first_ps2 = 0xae; +const uint8_t comm_read_ctrl_config = 0x20; +const uint8_t comm_write_ctrl_config = 0x60; +const uint8_t data_port = 0x60; // rw +const uint8_t data_enable_scanning = 0xf4; + +const char scancodes[] = {'E', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', 'T', 'q', 'w', 'e', + 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 'C', 'a', 's', 'd', 'f', 'g', 'h', 'j', + 'k', 'l', ';', '\'', '`', 'L', '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 'R'}; + +void +ps2_keyboard_init() +{ + // eat all previous keystrikes + while (inb(comm_port) & 0x1) inb(data_port); + outb(comm_port, comm_enable_first_ps2); + outb(comm_port, comm_read_ctrl_config); + const uint8_t conf = (inb(data_port) | 1) & ~0x10; + outb(comm_port, comm_write_ctrl_config); + outb(data_port, conf); + outb(data_port, data_enable_scanning); +} + +void +ps2_keyboard_irq_handler() +{ + const uint8_t key = inb(data_port); + if (key >= 0x80) return; + + if (key < 0x37) printf("%c", scancodes[key - 1]); + else + printf("key pressed: %x\n", key); +} diff --git a/devices/ps2_keyboard.h b/devices/ps2_keyboard.h new file mode 100644 index 0000000..5f4fcc2 --- /dev/null +++ b/devices/ps2_keyboard.h @@ -0,0 +1,4 @@ +#pragma once + +void ps2_keyboard_init(); +void ps2_keyboard_irq_handler(); diff --git a/devices/uart_16550.h b/devices/uart_16550.h index d053985..0e181b2 100644 --- a/devices/uart_16550.h +++ b/devices/uart_16550.h @@ -53,4 +53,5 @@ enum UART { }; int uart_init(enum UART port); +void uart_write(enum UART port, char a); int uart_puts(enum UART port, const char *string, int length); diff --git a/i686/Makefile b/i686/Makefile index e77f1c6..d472ebe 100644 --- a/i686/Makefile +++ b/i686/Makefile @@ -1,12 +1,12 @@ include ../${ARCH}/toolchain.mk -CCFLAGS += -I../grub/include +CCFLAGS += -I../grub/include -I../lib all: arch.a arch,SRCS = boot.S init.s \ gdt.c lgdt.c \ - lidt.c + lidt.c isr.c include ../rules.mk @@ -10,9 +10,13 @@ struct interrupt_frame { uint32_t ss; }; +// typedef void (*irq_handler)(); + +/* isr.c */ void abort_handler(struct interrupt_frame *frame); -void interrupt_handler(struct interrupt_frame *frame); -void interrupt_handler_e(struct interrupt_frame *frame, uint32_t error); void syscall_handler(struct interrupt_frame *frame); +void irq0x00(struct interrupt_frame *frame); // timer interrupt +void irq0x01(struct interrupt_frame *frame); // keyboard interrupt +/* lidt.c */ void idt_install(); diff --git a/i686/init.s b/i686/init.s index c0c25c0..d16de51 100644 --- a/i686/init.s +++ b/i686/init.s @@ -37,9 +37,9 @@ k_init: mov $k_stack, %esp # point stack pointer to the stack # hardware init - call pic_init # Programmable Interrupt Controller call gdt_install # Global Descriptor Table call idt_install # Interrupt Descriptor Table + call pic_init # Programmable Interrupt Controller # jump into kernel call kmain diff --git a/i686/isr.c b/i686/isr.c new file mode 100644 index 0000000..4f6729b --- /dev/null +++ b/i686/isr.c @@ -0,0 +1,42 @@ +/* + * Interrupt Service Routines + */ + +#include "idt.h" +#include "sys/control.h" +#include <stdio.h> + +__attribute__((interrupt)) void +abort_handler(struct interrupt_frame *frame) +{ + printf("### system abort ###\n"); + printf("# ip: %x cs=%x\n", frame->ip, frame->cs); + printf("# sp: %x ss=%x\n", frame->sp, frame->ss); + printf("# flags: %x\n", frame->flags); + abort(); +} + +__attribute__((interrupt)) void +syscall_handler(struct interrupt_frame *) +{ + printf("syscall\n"); + abort(); +} + +extern void pic_clear(unsigned char irq); + +__attribute__((interrupt)) void +irq0x00(struct interrupt_frame *) +{ + // printf("irq0x00\n"); + pic_clear(0x00); +} + +extern void ps2_keyboard_irq_handler(); +__attribute__((interrupt)) void +irq0x01(struct interrupt_frame *) +{ + // printf("irq0x01\n"); + ps2_keyboard_irq_handler(); + pic_clear(0x00); +} diff --git a/i686/lidt.c b/i686/lidt.c index 3e261ac..aa6185b 100644 --- a/i686/lidt.c +++ b/i686/lidt.c @@ -1,5 +1,6 @@ #include "idt.h" #include <stdint.h> +#include <stdio.h> struct __attribute__((packed)) Pointer { uint16_t limit; @@ -21,7 +22,7 @@ struct __attribute__((packed)) Gate_t { _Static_assert(sizeof(struct Gate_t) == 8); void -Gate(struct Gate_t *entry, void *f, uint16_t selector) +Gate(struct Gate_t *entry, void (*f)(struct interrupt_frame *), uint16_t selector) { uint32_t f_addr = (uint32_t)f; entry->offset_15_0 = f_addr & 0xffff; @@ -36,7 +37,14 @@ static struct Gate_t interrupt_table[256] __attribute((aligned(4096))); void idt_install() { - for (int i = 0; i <= 0x2f; ++i) Gate(&interrupt_table[i], &interrupt_handler, 0x10); + // exceptions 0x00~0x13 + for (int i = 0; i <= 0x13; ++i) Gate(&interrupt_table[i], &abort_handler, 0x10); + // irq 0x20~0x2f + // for (int i = 0; i < 16; ++i) irq_table[i] = NULL; + for (int i = 0x20; i <= 0x2f; ++i) Gate(&interrupt_table[i], &abort_handler, 0x10); + Gate(&interrupt_table[0x20], &irq0x00, 0x10); + Gate(&interrupt_table[0x21], &irq0x01, 0x10); + // syscall 0x80 Gate(&interrupt_table[0x80], &abort_handler, 0x10); const struct Pointer ptr = {.limit = sizeof(interrupt_table) - 1, .base = (unsigned)&interrupt_table}; diff --git a/lib/stdio/printf.c b/lib/stdio/printf.c index 269b9b6..7adf76e 100644 --- a/lib/stdio/printf.c +++ b/lib/stdio/printf.c @@ -25,6 +25,10 @@ printf(const char *restrict format, ...) case 's': written += uart_puts(COM1, va_arg(params, const char *), -1); break; + case 'c': + written++; + uart_write(COM1, va_arg(params, int)); + break; case 'd': written += uart_puts(COM1, itoa(buffer, va_arg(params, int), 10), -1); break; diff --git a/src/Makefile b/src/Makefile index e93d337..881b7c2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -9,7 +9,7 @@ conf.h: conf.h.in @sed -i 's/@VERSION@/$(shell git describe)/' conf.h @sed -i 's/@CC@/$(shell ${CC} --version | head -n1)/' conf.h -kernel,SRCS := multiboot2.c mmap.c kernel.c isr.c mem/vmm.c +kernel,SRCS := multiboot2.c mmap.c kernel.c mem/vmm.c kernel,OBJS := conf.h include ../rules.mk diff --git a/src/isr.c b/src/isr.c deleted file mode 100644 index b89ecd2..0000000 --- a/src/isr.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Interrupt Service Routines - */ - -#include <idt.h> -#include <stdio.h> -#include <sys/control.h> - -__attribute__((interrupt)) void -abort_handler(struct interrupt_frame *frame) -{ - printf("system abort\n"); - printf("ip: %x cs=%x\n", frame->ip, frame->cs); - printf("sp: %x ss=%x\n", frame->sp, frame->ss); - printf("flags: %x\n", frame->flags); - abort(); -} - -__attribute__((interrupt)) void -interrupt_handler(struct interrupt_frame *frame) -{ - printf("interrupt\n"); - abort(); -} - -__attribute__((interrupt)) void -interrupt_handler_e(struct interrupt_frame *frame, uint32_t error) -{ - printf("interrupt\n"); - abort(); -} - -__attribute__((interrupt)) void -syscall_handler(struct interrupt_frame *frame) -{ - printf("interrupt\n"); - abort(); -} diff --git a/src/kernel.c b/src/kernel.c index a9fc126..41025d7 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -25,6 +25,7 @@ void kmain() { printf("CPU: %s family %u model %u stepping %u\n", vendor, family(v), model(v), v.stepping); printf("hello %s world\n", "kernel"); + printf("Hello %c\n", 'C'); printf("we are number %d\n", 1); printf("a negative %d as hex %x\n", -1, -1); printf("hex 255=0x%x\n", 255); @@ -35,7 +36,7 @@ void kmain() { char *c = (char *)0xc0700000; if (*c == 0) printf("c is 0\r\n"); - asm volatile("int $0x80"); + // asm volatile("int $0x80"); while (1) ; |