diff options
| -rw-r--r-- | Makefile | 6 | ||||
| -rw-r--r-- | include/debug.h | 3 | ||||
| -rw-r--r-- | include/font.h | 2 | ||||
| -rw-r--r-- | include/idt.h | 34 | ||||
| -rw-r--r-- | include/io.h | 9 | ||||
| -rw-r--r-- | include/irq.h | 58 | ||||
| -rw-r--r-- | include/keyboard.h | 9 | ||||
| -rw-r--r-- | include/pic.h | 30 | ||||
| -rw-r--r-- | kernel/boot.S | 44 | ||||
| -rw-r--r-- | kernel/boot64.S | 3 | ||||
| -rw-r--r-- | kernel/debug.c | 15 | ||||
| -rw-r--r-- | kernel/graphics.c | 2 | ||||
| -rw-r--r-- | kernel/idt.c | 88 | ||||
| -rw-r--r-- | kernel/io.c | 13 | ||||
| -rw-r--r-- | kernel/irq.c | 289 | ||||
| -rw-r--r-- | kernel/irq_stub.S | 108 | ||||
| -rw-r--r-- | kernel/keyboard.c | 20 | ||||
| -rw-r--r-- | kernel/main.c | 25 | ||||
| -rw-r--r-- | kernel/pic.c | 24 |
19 files changed, 734 insertions, 48 deletions
@@ -25,6 +25,12 @@ OBJS = \ $K/graphics.o \ $K/multiboot2.o \ $K/debug.o \ + $K/idt.o \ + $K/irq.o \ + $K/irq_stub.o \ + $K/io.o \ + $K/pic.o \ + $K/keyboard.o \ kernel.iso: kernel.bin $K/grub.cfg mkdir -p isodir/boot/grub diff --git a/include/debug.h b/include/debug.h index 1c53148..ebe3a52 100644 --- a/include/debug.h +++ b/include/debug.h @@ -4,8 +4,5 @@ #include <stdint.h> void bochs_breakpoint(void); -void put_in_r8(uint64_t value); -void put_in_r9(uint64_t value); -void put_in_r10(uint64_t value); #endif diff --git a/include/font.h b/include/font.h index c95e7bc..678a6c2 100644 --- a/include/font.h +++ b/include/font.h @@ -4,7 +4,7 @@ #include <stdint.h> #define PSF_FONT_MAGIC 0x864ab572 - + typedef struct { uint32_t magic; /* magic bytes to identify PSF */ uint32_t version; /* zero */ diff --git a/include/idt.h b/include/idt.h new file mode 100644 index 0000000..9ca9c3a --- /dev/null +++ b/include/idt.h @@ -0,0 +1,34 @@ +#ifndef IDT_H +#define IDT_H + +#include <stdint.h> + +#define GDT_CODE_SEG 0x08 + +#define INTERRUPT_GATE 0x8E +#define TRAP_GATE 0x8F + +struct idt_entry { + uint16_t offset_1; // offset bits 0..15 + uint16_t selector; // a code segment selector in GDT or LDT + uint8_t ist; // bits 0..2 holds Interrupt Stack Table offset, rest of bits zero. + uint8_t type_attributes; // gate type, dpl, and p fields + uint16_t offset_2; // offset bits 16..31 + uint32_t offset_3; // offset bits 32..63 + uint32_t zero; // reserved +} __attribute__((packed)); +typedef struct idt_entry idt_entry; + +struct idtp { + uint16_t size; + uint64_t offset; +} __attribute__((packed)); +typedef struct idtp idtp; + +void init_idt(void); +void load_idt(idtp* pointer); +void init_idt_table(void); +void add_to_idt(uint16_t num, uint64_t offset, uint16_t selector, uint8_t type); + + +#endif diff --git a/include/io.h b/include/io.h new file mode 100644 index 0000000..76c401d --- /dev/null +++ b/include/io.h @@ -0,0 +1,9 @@ +#ifndef IO_H +#define IO_H + +#include <stdint.h> + +uint8_t inb(uint32_t port); +void outb(uint32_t port, uint8_t value); + +#endif diff --git a/include/irq.h b/include/irq.h new file mode 100644 index 0000000..f0e38d6 --- /dev/null +++ b/include/irq.h @@ -0,0 +1,58 @@ +#ifndef IRQ_H +#define IRQ_H + +#include <stdint.h> + +// exceptions +void isr0(void); +void isr1(void); +void isr2(void); +void isr3(void); +void isr4(void); +void isr5(void); +void isr6(void); +void isr7(void); +void isr8(uint64_t error); +void isr9(void); +void isr10(uint64_t error); +void isr11(uint64_t error); +void isr12(uint64_t error); +void isr13(uint64_t error); +void isr14(uint64_t error); +void isr15(void); +void isr16(void); +void isr17(uint64_t error); +void isr18(void); +void isr19(void); +void isr20(void); +void isr21(uint64_t error); +void isr22(void); +void isr23(void); +void isr24(void); +void isr25(void); +void isr26(void); +void isr27(void); +void isr28(void); +void isr29(uint64_t error); +void isr30(uint64_t error); +void isr31(void); + +// interrupts +void irq0(void); +void irq1(void); +void irq2(void); +void irq3(void); +void irq4(void); +void irq5(void); +void irq6(void); +void irq7(void); +void irq8(void); +void irq9(void); +void irq10(void); +void irq11(void); +void irq12(void); +void irq13(void); +void irq14(void); +void irq15(void); + +#endif diff --git a/include/keyboard.h b/include/keyboard.h new file mode 100644 index 0000000..3a1b7f1 --- /dev/null +++ b/include/keyboard.h @@ -0,0 +1,9 @@ +#ifndef KEYBOARD_H +#define KEYBOARD_H + +#define KEYBOARD_DATA_PORT 0x60 +#define KEYBOARD_STATUS_PORT 0x64 + +void keyboard_handler(void); + +#endif diff --git a/include/pic.h b/include/pic.h new file mode 100644 index 0000000..f1f4e44 --- /dev/null +++ b/include/pic.h @@ -0,0 +1,30 @@ +#ifndef PIC_H +#define PIC_H + +#define PIC1 0x20 /* IO base address for master PIC */ +#define PIC2 0xA0 /* IO base address for slave PIC */ +#define PIC1_COMMAND PIC1 +#define PIC1_DATA (PIC1+1) +#define PIC2_COMMAND PIC2 +#define PIC2_DATA (PIC2+1) + +#define PIC_EOI 0x20 /* End-of-interrupt command code */ + +/* reinitialize the PIC controllers, giving them specified vector offsets + rather than 8h and 70h, as configured by default */ + +#define ICW1_ICW4 0x01 /* ICW4 (not) needed */ +#define ICW1_SINGLE 0x02 /* Single (cascade) mode */ +#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */ +#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */ +#define ICW1_INIT 0x10 /* Initialization - required! */ + +#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */ +#define ICW4_AUTO 0x02 /* Auto (normal) EOI */ +#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */ +#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */ +#define ICW4_SFNM 0x10 /* Special fully nested (not) */ + +void remap_pic(void); + +#endif diff --git a/kernel/boot.S b/kernel/boot.S index e870c37..ee35eeb 100644 --- a/kernel/boot.S +++ b/kernel/boot.S @@ -5,6 +5,7 @@ .code32 _start: + cli mov $stack_top, %esp pushl $0 pushl %eax @@ -18,8 +19,8 @@ _start: call setup_page_tables call enable_paging - lgdt gdt64_pointer - ljmp $gdt64_code_segment, $begin_long_mode + lgdt gdt_pointer + ljmp $0x08, $begin_long_mode check_multiboot: @@ -143,11 +144,38 @@ page_table_lvl3: page_table_lvl2: .skip 4096*4 +// Access bits .section .rodata -gdt64: +.set PRESENT, 1 << 7 +.set NOT_SYS, 1 << 4 +.set EXEC, 1 << 3 +.set DC, 1 << 2 +.set RW, 1 << 1 +.set ACCESSED, 1 << 0 + +// Flags bits +.set GRAN_4K, 1 << 7 +.set SZ_32, 1 << 6 +.set LONG_MODE, 1 << 5 + +gdt: +gdt_null = . - gdt .quad 0 -gdt64_code_segment = . - gdt64 - .quad 1<<43 + 1<<44 + 1<<47 + 1<<53 -gdt64_pointer: - .word . - gdt64 - 1 - .quad gdt64 +gdt_code = . - gdt + .long 0xFFFF // Limit & Base (low, bits 0-15) + .byte 0 // Base (mid, bits 16-23) + .byte PRESENT | NOT_SYS | EXEC | RW // Access + .byte GRAN_4K | LONG_MODE | 0xF // Flags & Limit (high, bits 16-19) + .byte 0 // Base (high, bits 24-31) +gdt_data = . - gdt + .long 0xFFFF + .byte 0 + .byte PRESENT | NOT_SYS | RW + .byte GRAN_4K | SZ_32 | 0xF + .byte 0 +gdt_tss = . - gdt + .long 0x00000068 + .long 0x00CF8900 +gdt_pointer: + .word . - gdt - 1 + .quad gdt diff --git a/kernel/boot64.S b/kernel/boot64.S index 561fe6b..be87412 100644 --- a/kernel/boot64.S +++ b/kernel/boot64.S @@ -5,7 +5,7 @@ begin_long_mode: // reload segment registers - mov $0, %eax + mov $0x10, %eax mov %eax, %ss mov %eax, %ds mov %eax, %es @@ -15,6 +15,5 @@ begin_long_mode: popq %rdi popq %rsi - cli call kernel_main hlt diff --git a/kernel/debug.c b/kernel/debug.c index 3ce4866..5f3c327 100644 --- a/kernel/debug.c +++ b/kernel/debug.c @@ -4,18 +4,3 @@ void bochs_breakpoint(void) { __asm__ volatile ("xchgw %bx, %bx;"); } - -void put_in_r8(uint64_t value) -{ - __asm__ volatile ("movq %0, %%r8;" : : "r"(value) : "%r8"); -} - -void put_in_r9(uint64_t value) -{ - __asm__ volatile ("movq %0, %%r9;" : : "r"(value) : "%r9"); -} - -void put_in_r10(uint64_t value) -{ - __asm__ volatile ("movq %0, %%r10;" : : "r"(value) : "%r10"); -} diff --git a/kernel/graphics.c b/kernel/graphics.c index d27a3e3..d4fc7c7 100644 --- a/kernel/graphics.c +++ b/kernel/graphics.c @@ -88,6 +88,8 @@ void fb_draw_line(fb_t fb, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32 void fb_draw_character(fb_t fb, char c, uint32_t x, uint32_t y, uint32_t char_col, uint32_t bg_col) { + if (c < 0) return; + uint32_t offset = 32 + c * 16; for (uint32_t i = 0 ; i < 16; i++) { diff --git a/kernel/idt.c b/kernel/idt.c new file mode 100644 index 0000000..bf285b7 --- /dev/null +++ b/kernel/idt.c @@ -0,0 +1,88 @@ +#include <idt.h> +#include <irq.h> +#include <pic.h> + +__attribute__((aligned(0x10))) static idt_entry idt_table[256]; +idtp idt_pointer; + +void load_idt(idtp* pointer) +{ + __asm__ volatile ("lidt (%0); sti;" : : "r"(pointer) : ); +} + +void add_to_idt(uint16_t num, uint64_t offset, uint16_t selector, uint8_t type) +{ + idt_table[num].offset_1 = offset & 0xFFFF; + idt_table[num].offset_2 = (offset >> 16) & 0xFFFF; + idt_table[num].offset_3 = offset >> 32; + idt_table[num].selector = selector; + idt_table[num].type_attributes = type; + idt_table[num].ist = 0; + idt_table[num].zero = 0; +} + +void init_idt_table(void) +{ + // exceptions + add_to_idt(0, (uint64_t)isr0, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(1, (uint64_t)isr1, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(2, (uint64_t)isr2, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(3, (uint64_t)isr3, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(4, (uint64_t)isr4, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(5, (uint64_t)isr5, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(6, (uint64_t)isr6, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(7, (uint64_t)isr7, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(8, (uint64_t)isr8, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(9, (uint64_t)isr9, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(10, (uint64_t)isr10, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(11, (uint64_t)isr11, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(12, (uint64_t)isr12, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(13, (uint64_t)isr13, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(14, (uint64_t)isr14, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(15, (uint64_t)isr15, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(16, (uint64_t)isr16, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(17, (uint64_t)isr17, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(18, (uint64_t)isr18, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(19, (uint64_t)isr19, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(20, (uint64_t)isr20, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(21, (uint64_t)isr21, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(22, (uint64_t)isr22, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(23, (uint64_t)isr23, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(24, (uint64_t)isr24, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(25, (uint64_t)isr25, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(26, (uint64_t)isr26, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(27, (uint64_t)isr27, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(28, (uint64_t)isr28, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(29, (uint64_t)isr29, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(30, (uint64_t)isr30, GDT_CODE_SEG, TRAP_GATE); + add_to_idt(31, (uint64_t)isr31, GDT_CODE_SEG, TRAP_GATE); + + // interrupts + add_to_idt(32, (uint64_t)irq0, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(33, (uint64_t)irq1, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(34, (uint64_t)irq2, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(35, (uint64_t)irq3, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(36, (uint64_t)irq4, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(37, (uint64_t)irq5, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(38, (uint64_t)irq6, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(39, (uint64_t)irq7, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(40, (uint64_t)irq8, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(41, (uint64_t)irq9, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(42, (uint64_t)irq10, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(43, (uint64_t)irq11, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(44, (uint64_t)irq12, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(45, (uint64_t)irq13, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(46, (uint64_t)irq14, GDT_CODE_SEG, INTERRUPT_GATE); + add_to_idt(47, (uint64_t)irq15, GDT_CODE_SEG, INTERRUPT_GATE); +} + +void init_idt() +{ + init_idt_table(); + idt_pointer.size = sizeof(idt_entry) * 256 - 1; + idt_pointer.offset = (uint64_t)&idt_table; + + remap_pic(); + + load_idt(&idt_pointer); +} diff --git a/kernel/io.c b/kernel/io.c new file mode 100644 index 0000000..6bf67d0 --- /dev/null +++ b/kernel/io.c @@ -0,0 +1,13 @@ +#include <stdint.h> + +uint8_t inb(uint32_t port) +{ + uint8_t ret; + __asm__ volatile ("inb %%dx, %%al" : "=a"(ret) : "d"(port)); + return ret; +} + +void outb(uint32_t port, uint8_t value) +{ + __asm__ volatile ("outb %%al, %%dx" : : "d"(port), "a"(value)); +} diff --git a/kernel/irq.c b/kernel/irq.c new file mode 100644 index 0000000..1e02f23 --- /dev/null +++ b/kernel/irq.c @@ -0,0 +1,289 @@ +#include <stdint.h> +#include <pic.h> +#include <io.h> +#include <keyboard.h> +#include <graphics.h> + +char* exception_name[] = { + "Divide-by-zero Error", + "Debug", + "Non-maskable Interrupt", + "Breakpoint", + "Overflow", + "Bound Range Exceeded", + "Invalid Opcode", + "Device Not Available", + "Double Fault", + "Coprocessor Segment Overrun", + "Invalid TSS", + "Segment Not Present", + "Stack-Segment Fault", + "General Protection Fault", + "Page Fault", + "Reserved", + "x87 Floating-Point Exception", + "Alignment Check", + "Machine Check", + "SIMD Floating-Point Exception", + "Virtualization Exception", + "Control Protection Exception", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Hypervisor Injection Exception", + "VMM Communication Exception", + "Security Exception", + "Reserved", +}; + +void isr0_handler(void) +{ + fb_draw_string(fb, exception_name[0], 0, 0, WHITE, BLACK); +} + +void isr1_handler(void) +{ + fb_draw_string(fb, exception_name[1], 0, 0, WHITE, BLACK); +} + +void isr2_handler(void) +{ + fb_draw_string(fb, exception_name[2], 0, 0, WHITE, BLACK); +} + +void isr3_handler(void) +{ + fb_draw_string(fb, exception_name[3], 0, 0, WHITE, BLACK); +} + +void isr4_handler(void) +{ + fb_draw_string(fb, exception_name[4], 0, 0, WHITE, BLACK); +} + +void isr5_handler(void) +{ + fb_draw_string(fb, exception_name[5], 0, 0, WHITE, BLACK); +} + +void isr6_handler(void) +{ + fb_draw_string(fb, exception_name[6], 0, 0, WHITE, BLACK); +} + +void isr7_handler(void) +{ + fb_draw_string(fb, exception_name[7], 0, 0, WHITE, BLACK); +} + +void isr8_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[8], 0, 0, WHITE, BLACK); +} + +void isr9_handler(void) +{ + fb_draw_string(fb, exception_name[9], 0, 0, WHITE, BLACK); +} + +void isr10_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[10], 0, 0, WHITE, BLACK); +} + +void isr11_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[11], 0, 0, WHITE, BLACK); +} + +void isr12_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[12], 0, 0, WHITE, BLACK); +} + +void isr13_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[13], 0, 0, WHITE, BLACK); +} + +void isr14_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[14], 0, 0, WHITE, BLACK); +} + +void isr15_handler(void) +{ + fb_draw_string(fb, exception_name[15], 0, 0, WHITE, BLACK); +} + +void isr16_handler(void) +{ + fb_draw_string(fb, exception_name[16], 0, 0, WHITE, BLACK); +} + +void isr17_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[17], 0, 0, WHITE, BLACK); +} + +void isr18_handler(void) +{ + fb_draw_string(fb, exception_name[18], 0, 0, WHITE, BLACK); +} + +void isr19_handler(void) +{ + fb_draw_string(fb, exception_name[19], 0, 0, WHITE, BLACK); +} + +void isr20_handler(void) +{ + fb_draw_string(fb, exception_name[20], 0, 0, WHITE, BLACK); +} + +void isr21_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[21], 0, 0, WHITE, BLACK); +} + +void isr22_handler(void) +{ + fb_draw_string(fb, exception_name[22], 0, 0, WHITE, BLACK); +} + +void isr23_handler(void) +{ + fb_draw_string(fb, exception_name[23], 0, 0, WHITE, BLACK); +} + +void isr24_handler(void) +{ + fb_draw_string(fb, exception_name[24], 0, 0, WHITE, BLACK); +} + +void isr25_handler(void) +{ + fb_draw_string(fb, exception_name[25], 0, 0, WHITE, BLACK); +} + +void isr26_handler(void) +{ + fb_draw_string(fb, exception_name[26], 0, 0, WHITE, BLACK); +} + +void isr27_handler(void) +{ + fb_draw_string(fb, exception_name[27], 0, 0, WHITE, BLACK); +} + +void isr28_handler(void) +{ + fb_draw_string(fb, exception_name[28], 0, 0, WHITE, BLACK); +} + +void isr29_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[29], 0, 0, WHITE, BLACK); +} + +void isr30_handler(uint64_t error) +{ + fb_draw_string(fb, exception_name[30], 0, 0, WHITE, BLACK); +} + +void isr31_handler(void) +{ + fb_draw_string(fb, exception_name[31], 0, 0, WHITE, BLACK); +} + +void irq0_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); +} + +void irq1_handler(void) +{ + keyboard_handler(); + outb(PIC1_COMMAND, PIC_EOI); +} + +void irq2_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); +} + +void irq3_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); +} + +void irq4_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); +} + +void irq5_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); +} + +void irq6_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); +} + +void irq7_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); +} + +void irq8_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); + outb(PIC2_COMMAND, PIC_EOI); +} + +void irq9_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); + outb(PIC2_COMMAND, PIC_EOI); +} + +void irq10_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); + outb(PIC2_COMMAND, PIC_EOI); +} + +void irq11_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); + outb(PIC2_COMMAND, PIC_EOI); +} + +void irq12_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); + outb(PIC2_COMMAND, PIC_EOI); +} + +void irq13_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); + outb(PIC2_COMMAND, PIC_EOI); +} + +void irq14_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); + outb(PIC2_COMMAND, PIC_EOI); +} + +void irq15_handler(void) +{ + outb(PIC1_COMMAND, PIC_EOI); + outb(PIC2_COMMAND, PIC_EOI); +} diff --git a/kernel/irq_stub.S b/kernel/irq_stub.S new file mode 100644 index 0000000..ddd197a --- /dev/null +++ b/kernel/irq_stub.S @@ -0,0 +1,108 @@ +.macro pushall + push %rax + push %rcx + push %rdx + push %rsi + push %rdi + push %r8 + push %r9 + push %r10 + push %r11 + pushfq +.endm + +.macro popall + popfq + pop %r11 + pop %r10 + pop %r9 + pop %r8 + pop %rdi + pop %rsi + pop %rdx + pop %rcx + pop %rax +.endm + + +.macro isr_no_error number +.global isr\number +isr\number: + pushall + cld + call isr\number\()_handler + popall + iretq +.endm + +.macro isr_error number +.global isr\number +isr\number: + # rdi not saved + pop %rdi + pushall + cld + call isr\number\()_handler + popall + iretq +.endm + +isr_no_error 0 +isr_no_error 1 +isr_no_error 2 +isr_no_error 3 +isr_no_error 4 +isr_no_error 5 +isr_no_error 6 +isr_no_error 7 +isr_error 8 +isr_no_error 9 +isr_error 10 +isr_error 11 +isr_error 12 +isr_error 13 +isr_error 14 +isr_no_error 15 +isr_no_error 16 +isr_error 17 +isr_no_error 18 +isr_no_error 19 +isr_no_error 20 +isr_no_error 21 +isr_no_error 22 +isr_no_error 23 +isr_no_error 24 +isr_no_error 25 +isr_no_error 26 +isr_no_error 27 +isr_no_error 28 +isr_error 29 +isr_error 30 +isr_no_error 31 + +.macro irq number +.global irq\number +irq\number: + pushall + cld + call irq\number\()_handler + popall + iretq +.endm + +irq 0 +irq 1 +irq 2 +irq 3 +irq 4 +irq 5 +irq 6 +irq 7 +irq 8 +irq 9 +irq 10 +irq 11 +irq 12 +irq 13 +irq 14 +irq 15 diff --git a/kernel/keyboard.c b/kernel/keyboard.c new file mode 100644 index 0000000..105c3a8 --- /dev/null +++ b/kernel/keyboard.c @@ -0,0 +1,20 @@ +#include <stdint.h> +#include <pic.h> +#include <io.h> +#include <graphics.h> +#include <debug.h> + +#define KEYBOARD_DATA_PORT 0x60 +#define KEYBOARD_STATUS_PORT 0x64 + +uint8_t i = 0; + +void keyboard_handler(void) +{ + uint8_t status = inb(KEYBOARD_STATUS_PORT); + if (!(status & 0x1)) { + return; + } + uint8_t keycode = inb(KEYBOARD_DATA_PORT); + fb_draw_character(fb, keycode, 0, 0, RED, BLACK); +} diff --git a/kernel/main.c b/kernel/main.c index 86b095d..96f3572 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -1,31 +1,18 @@ #include <stdint.h> #include <multiboot2.h> #include <graphics.h> +#include <idt.h> #include <debug.h> int kernel_main(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic) { + init_idt(); init_fb(multiboot_bootinfo, multiboot_magic); - for (int x = 0; x < fb.width; x++) { - for (int y = 0; y < fb.width; y++) { - fb_draw_pixel(fb, x , y, BLUE); - } - } - - fb_draw_line(fb, 0, 0, 100, 100, WHITE); - fb_draw_line(fb, 0, 0, 100, 200, WHITE); - fb_draw_line(fb, 0, 0, 100, 300, WHITE); - - fb_draw_line(fb, 100, 100, 200, 200, YELLOW); - fb_draw_line(fb, 100, 100, 300, 200, YELLOW); - fb_draw_line(fb, 100, 100, 400, 200, YELLOW); - - fb_draw_line(fb, 500, 100, 300, 500, RED); - fb_draw_line(fb, 300, 500, 700, 500, RED); - fb_draw_line(fb, 700, 500, 500, 100, RED); - - fb_draw_string(fb, "aleksa vuckovic 1234", 420, 300, WHITE, BLUE); + fb_draw_string(fb, "Still working...", 8, 0, WHITE, BLACK); + for(;;) { + __asm__ volatile ("hlt;"); + } return 0; } diff --git a/kernel/pic.c b/kernel/pic.c new file mode 100644 index 0000000..801556d --- /dev/null +++ b/kernel/pic.c @@ -0,0 +1,24 @@ +#include <io.h> +#include <pic.h> + +void remap_pic(void) +{ + // save masks +// uint8_t a1 = inb(PIC1_DATA); +// uint8_t a2 = inb(PIC2_DATA); + + // starts the initialization sequence (in cascade mode) + outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); + outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); + outb(PIC1_DATA, 0x20); // ICW2: Master PIC vector offset + outb(PIC2_DATA, 0x28); // ICW2: Slave PIC vector offset + outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100) + outb(PIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010) + + outb(PIC1_DATA, ICW4_8086); + outb(PIC2_DATA, ICW4_8086); + + // mask interrupts + outb(PIC1_DATA, 0xfd); + outb(PIC2_DATA, 0xff); +} |
