aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--devices/Makefile4
-rw-r--r--devices/pic_8259.c2
-rw-r--r--devices/ps2_keyboard.c40
-rw-r--r--devices/ps2_keyboard.h4
-rw-r--r--devices/uart_16550.h1
-rw-r--r--i686/Makefile4
-rw-r--r--i686/idt.h8
-rw-r--r--i686/init.s2
-rw-r--r--i686/isr.c42
-rw-r--r--i686/lidt.c12
-rw-r--r--lib/stdio/printf.c4
-rw-r--r--src/Makefile2
-rw-r--r--src/isr.c38
-rw-r--r--src/kernel.c3
15 files changed, 117 insertions, 50 deletions
diff --git a/Makefile b/Makefile
index f623e7a..da1daa4 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/i686/idt.h b/i686/idt.h
index 22dc6de..f96e2b1 100644
--- a/i686/idt.h
+++ b/i686/idt.h
@@ -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)
;