diff options
Diffstat (limited to 'src/kernel')
| -rw-r--r-- | src/kernel/exceptions.c | 9 | ||||
| -rw-r--r-- | src/kernel/idt.c | 23 | ||||
| -rw-r--r-- | src/kernel/kernel.c | 55 | ||||
| -rw-r--r-- | src/kernel/keyboard/compile_flags.txt | 1 | ||||
| -rw-r--r-- | src/kernel/keyboard/isr.c | 49 | ||||
| -rw-r--r-- | src/kernel/keyboard/isr_wrap.s | 8 | ||||
| -rw-r--r-- | src/kernel/keyboard/pic.c | 65 | ||||
| -rw-r--r-- | src/kernel/print.c | 32 | ||||
| -rw-r--r-- | src/kernel/stub_table.asm | 33 | ||||
| -rw-r--r-- | src/kernel/tables/compile_flags.txt | 1 | ||||
| -rw-r--r-- | src/kernel/tables/gdt.c (renamed from src/kernel/gdt.c) | 4 | ||||
| -rw-r--r-- | src/kernel/tables/idt.c | 27 | ||||
| -rw-r--r-- | src/kernel/tables/stub.s | 53 |
13 files changed, 260 insertions, 100 deletions
diff --git a/src/kernel/exceptions.c b/src/kernel/exceptions.c new file mode 100644 index 0000000..ded9e9b --- /dev/null +++ b/src/kernel/exceptions.c @@ -0,0 +1,9 @@ +#include "print.h" + +__attribute__((noreturn)) void exception_handler(void); +void exception_handler() { + print_set_color(PRINT_COLOR_RED, PRINT_COLOR_BLACK); + print_clear(); + printf("KERNEL EXCEPTION"); + __asm__ volatile("cli; hlt"); +} diff --git a/src/kernel/idt.c b/src/kernel/idt.c deleted file mode 100644 index 2805889..0000000 --- a/src/kernel/idt.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "idt.h" -#include "gdt.h" -#include <stdint.h> - -static Gate_Descriptor_t idt[256]; -extern GDTR_t idtr; - -void get_idtr() { - idtr.offset = (uintptr_t)&idt[0]; - idtr.size = sizeof(Gate_Descriptor_t) * 256 - 1; - for (uint8_t vec = 0; vec < 32; vec++) { - make_gate(stub_table[vec], 0x8E, vec); - } -} - -void make_gate(uint32_t offset, uint8_t attrs, uint8_t vec) { - Gate_Descriptor_t *descriptor = &idt[vec]; - - descriptor->offset_low = offset & 0xFFFF; - descriptor->attrs = (0b1000 << 4) | attrs; - descriptor->offset_high = offset >> 16, descriptor->segment_selector = 0x08; - descriptor->reserved = 0; -} diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index b582e85..7dd3deb 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -1,5 +1,9 @@ -#include "kernel.h" +#include "asm.h" +#include "gdt.h" +#include "isr.h" #include "print.h" +extern GDTR_t idtr; +extern GDTR_t gdtr; #if defined(__linux__) #error "Not using cross compiler!" @@ -10,49 +14,20 @@ #error "Must use ix86-elf compiler" #endif -void motd() { - char *empty_row = " " - " \n"; - empty_row[0] = (char)186; - empty_row[79] = (char)186; - - printf("%c", 201); - for (int i = 0; i < 78; i++) - printf("%c", 205); - printf("%c\n", 187); - - printf(empty_row); - - printf("%c", 186); - for (int i = 0; i < 78 / 2 - 17 / 2; i++) - printf(" "); - printf("Welcome to gftos!"); - for (int i = 0; i < 78 / 2 - 17 / 2 - 1; i++) - printf(" "); - printf("%c\n", 186); - - for (int i = 0; i < 21; i++) { - printf(empty_row); - } - - printf("%c", 200); - for (int i = 0; i < 78; i++) - printf("%c", 205); - printf("%c", 188); -} - -void kernel_panic(const char *error) { - print_set_color(PRINT_COLOR_BLACK, PRINT_COLOR_RED); - print_clear(); - printf(" PANIC! ERROR: %s", error); - for (;;) - ; -} +void motd() { printf("Welcome to gftos!\n=================\n"); } void kernel_main(void) { + PIC_init(0x20, 0xA0); + IRQ_mask(0); + + print_set_color(PRINT_COLOR_PINK, PRINT_COLOR_DARK_GRAY); print_clear(); motd(); - /* kernel_panic("test_panic."); */ + for (;;) { + update_cursor(); + asm("hlt"); + } + // for (int r = 0; r < 24; r++) { // for (int c = 0; c < 80; c += 3) { // int color = (r + c) % 15 + 1; diff --git a/src/kernel/keyboard/compile_flags.txt b/src/kernel/keyboard/compile_flags.txt new file mode 100644 index 0000000..2af49c7 --- /dev/null +++ b/src/kernel/keyboard/compile_flags.txt @@ -0,0 +1 @@ +-I../../include/ diff --git a/src/kernel/keyboard/isr.c b/src/kernel/keyboard/isr.c new file mode 100644 index 0000000..223bf9f --- /dev/null +++ b/src/kernel/keyboard/isr.c @@ -0,0 +1,49 @@ +#include "asm.h" +#include "print.h" +#include "str.h" +#include <stdint.h> +static uint8_t shift_held = 0; +static uint8_t capslock = 0; + +void keyboard_handler() { + const char *scancodes = + "??1234567890-=?\tqwertyuiop[]\n?asdfghjkl;'`?\\zxcvbnm,./?*? "; + const char *SCANCODES = + "\?\?!@#$%^&*()_+?\tQWERTYUIOP{}\n?ASDFGHJKL:\"~?|ZXCVBNM<>??*? "; + + unsigned char sc = inb(0x60); + + uint8_t isheld = shift_held != 0; + char c = ((isheld | capslock) & !(isheld & capslock)) ? SCANCODES[sc] + : scancodes[sc]; + + if (capslock & (!isheld) && !isalpha(c)) + c = scancodes[sc]; + if (isheld && !isalpha(c)) + c = SCANCODES[sc]; + + if (sc < 0x59 && scancodes[sc] != '?') + printf("%c", c); + + switch (sc) { + case 0x2A: + shift_held |= 0b10; + break; + case 0x36: + shift_held |= 0b01; + break; + case 0xAA: + shift_held &= 0b01; + break; + case 0xB6: + shift_held &= 0b10; + break; + case 0x0E: + delete_char(); + break; + case 0x3A: + capslock = !capslock; + break; + } + outb(0x20, 0x20); +} diff --git a/src/kernel/keyboard/isr_wrap.s b/src/kernel/keyboard/isr_wrap.s new file mode 100644 index 0000000..6f6c58b --- /dev/null +++ b/src/kernel/keyboard/isr_wrap.s @@ -0,0 +1,8 @@ +extern keyboard_handler +extern wrap_keyboard_handler +wrap_keyboard_handler: + pushad + cld + call keyboard_handler + popad + iret diff --git a/src/kernel/keyboard/pic.c b/src/kernel/keyboard/pic.c index 0c81629..e1b4fb3 100644 --- a/src/kernel/keyboard/pic.c +++ b/src/kernel/keyboard/pic.c @@ -1 +1,66 @@ #include "asm.h" +#include <stdint.h> +#define PIC1 0x20 +#define PIC2 0xA0 +#define PIC1_COMMAND PIC1 +#define PIC1_DATA (PIC1 + 1) +#define PIC2_COMMAND PIC2 +#define PIC2_DATA (PIC2 + 1) + +void PIC_init(int offset1, int offset2) { + uint8_t a1, a2; + + a1 = inb(PIC1_DATA); + a2 = inb(PIC2_DATA); + + outb(PIC1_COMMAND, 0x11); // Init PIC1 + io_wait(); + outb(PIC2_COMMAND, 0x11); // Init PIC2 + io_wait(); + outb(PIC1_DATA, offset1); // ICW2: Master PIC vector offset + io_wait(); + outb(PIC2_DATA, offset2); // ICW2: Slave PIC vector offset + io_wait(); + outb(PIC1_DATA, 4); + io_wait(); + outb(PIC2_DATA, 2); + io_wait(); + outb(PIC1_DATA, 0x01); + io_wait(); + outb(PIC2_DATA, 0x01); + io_wait(); + + outb(PIC1_DATA, a1); // restore saved masks. + outb(PIC2_DATA, a2); +} + +void IRQ_mask(uint8_t line) { + uint16_t port = line < 8 ? PIC1_DATA : PIC2_DATA; + line = line > 8 ? line - 8 : line; + uint8_t val = inb(port) | (1 << line); + outb(port, val); +} + +void IRQ_unmask(uint8_t line) { + uint16_t port = line < 8 ? PIC1_DATA : PIC2_DATA; + line = line > 8 ? line - 8 : line; + uint8_t val = inb(port) & ~(1 << line); + outb(port, val); +} + +void PIC_disable(void) { + outb(PIC1_DATA, 0xff); + outb(PIC2_DATA, 0xff); +} + +uint16_t PIC_irr(void) { + outb(PIC1_COMMAND, 0x0a); + outb(PIC2_COMMAND, 0x0a); + return (inb(PIC2_COMMAND) << 8) | inb(PIC1_COMMAND); +} + +uint16_t PIC_isr(void) { + outb(PIC1_COMMAND, 0x0b); + outb(PIC2_COMMAND, 0x0b); + return (inb(PIC2_COMMAND) << 8) | inb(PIC1_COMMAND); +} diff --git a/src/kernel/print.c b/src/kernel/print.c index d5e8790..7a54c7b 100644 --- a/src/kernel/print.c +++ b/src/kernel/print.c @@ -1,9 +1,12 @@ #include "print.h" +#include "asm.h" #include "str.h" #include <stdarg.h> +#include <stdint.h> // Constants static const size_t NUM_COLS = 80; static const size_t NUM_ROWS = 25; +static uint8_t cursor = 0; // Char struct struct Char { @@ -34,6 +37,18 @@ void clear_row(size_t row) { } } +void delete_char() { + if (col == 0) { + row--; + col = NUM_COLS; + } + col--; + buffer[col + NUM_COLS * row] = (struct Char){ + ' ', + color, + }; +} + // Call clear_row for every row void print_clear() { for (size_t i = 0; i < NUM_ROWS; i++) { @@ -62,6 +77,15 @@ void print_newline() { clear_row(NUM_ROWS - 1); } +void update_cursor() { + uint16_t pos = col + NUM_COLS * row; + + outb(0x3D4, 0x0F); + outb(0x3D5, (uint8_t)(pos & 0xFF)); + outb(0x3D4, 0x0E); + outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF)); +} + // printchar void print_char(char character) { // If \n, call newline @@ -76,7 +100,7 @@ void print_char(char character) { } // if cols is too large, overflow - if (col > NUM_COLS) { + if (col >= NUM_COLS) { print_newline(); } @@ -105,7 +129,7 @@ void print_set_color(uint8_t foreground, uint8_t background) { void printf(const char *str, ...) { va_list args; va_start(args, str); - char temp_str[256]; + char temp_str[256] = ""; for (size_t i = 0; str[i] != '\0'; ++i) { if (str[i] == '%') { @@ -114,6 +138,10 @@ void printf(const char *str, ...) { case 'd': print_str(itoa(va_arg(args, int), temp_str, 10)); break; + case 'x': + print_str("0x"); + print_str(itoa(va_arg(args, int), temp_str, 16)); + break; case 's': print_str(va_arg(args, char *)); break; diff --git a/src/kernel/stub_table.asm b/src/kernel/stub_table.asm deleted file mode 100644 index 9901cea..0000000 --- a/src/kernel/stub_table.asm +++ /dev/null @@ -1,33 +0,0 @@ -extern exception_handler -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_err_stub 0 -isr_no_err_stub 0 -isr_err_stub 0 -isr_err_stub 0 -isr_err_stub 0 -isr_err_stub 0 -isr_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_no_err_stub 0 -isr_err_stub 0 -isr_no_err_stub 0 diff --git a/src/kernel/tables/compile_flags.txt b/src/kernel/tables/compile_flags.txt new file mode 100644 index 0000000..2af49c7 --- /dev/null +++ b/src/kernel/tables/compile_flags.txt @@ -0,0 +1 @@ +-I../../include/ diff --git a/src/kernel/gdt.c b/src/kernel/tables/gdt.c index 406b40c..9c65152 100644 --- a/src/kernel/gdt.c +++ b/src/kernel/tables/gdt.c @@ -4,9 +4,9 @@ GDT_t table = 0x0; extern GDTR_t gdtr; void get_gdtr() { - uint32_t base = 0x0000; + uint32_t base = (uint32_t)table; - table[0] = make_descriptor(0, 0, 0); + table[0] = make_descriptor(base, 0, 0); table[1] = make_descriptor(base, 0x3FFFF, make_code(0, 0, 1)); table[2] = make_descriptor(base, 0x3FFFF, make_data(0, 0, 1)); diff --git a/src/kernel/tables/idt.c b/src/kernel/tables/idt.c new file mode 100644 index 0000000..01a6776 --- /dev/null +++ b/src/kernel/tables/idt.c @@ -0,0 +1,27 @@ +#include "idt.h" +#include "gdt.h" +#include "isr.h" +#include <stdint.h> + +__attribute__((aligned(0x10))) static Gate_Descriptor_t idt[256]; +extern GDTR_t idtr; +extern void *isr_stub_table; + +void get_idtr() { + idtr.offset = (uintptr_t)&idt[0]; + idtr.size = sizeof(Gate_Descriptor_t) * 256 - 1; + for (uint8_t vec = 0; vec < 32; vec++) { + make_gate(((void **)(isr_stub_table))[vec], 0x8E, vec); + } + make_gate(wrap_keyboard_handler, 0x8E, 0x21); +} + +void make_gate(void *isr, uint8_t attrs, uint8_t vec) { + Gate_Descriptor_t *descriptor = &idt[vec]; + + descriptor->offset_low = (uint32_t)isr & 0xFFFF; + descriptor->attrs = (0b1000 << 4) | attrs; + descriptor->offset_high = (uint32_t)isr >> 16; + descriptor->segment_selector = 0x08; + descriptor->reserved = 0; +} diff --git a/src/kernel/tables/stub.s b/src/kernel/tables/stub.s new file mode 100644 index 0000000..11e457a --- /dev/null +++ b/src/kernel/tables/stub.s @@ -0,0 +1,53 @@ + +%macro isr_err_stub 1 +isr_stub_%+%1: + call exception_handler + iret +%endmacro +%macro isr_no_err_stub 1 +isr_stub_%+%1: + call exception_handler + iret +%endmacro + +extern exception_handler +isr_no_err_stub 0 +isr_no_err_stub 1 +isr_no_err_stub 2 +isr_no_err_stub 3 +isr_no_err_stub 4 +isr_no_err_stub 5 +isr_no_err_stub 6 +isr_no_err_stub 7 +isr_err_stub 8 +isr_no_err_stub 9 +isr_err_stub 10 +isr_err_stub 11 +isr_err_stub 12 +isr_err_stub 13 +isr_err_stub 14 +isr_no_err_stub 15 +isr_no_err_stub 16 +isr_err_stub 17 +isr_no_err_stub 18 +isr_no_err_stub 19 +isr_no_err_stub 20 +isr_no_err_stub 21 +isr_no_err_stub 22 +isr_no_err_stub 23 +isr_no_err_stub 24 +isr_no_err_stub 25 +isr_no_err_stub 26 +isr_no_err_stub 27 +isr_no_err_stub 28 +isr_no_err_stub 29 +isr_err_stub 30 +isr_no_err_stub 31 + +global isr_stub_table +isr_stub_table: +%assign i 0 +%rep 32 + dd isr_stub_%+i +%assign i i+1 +%endrep |
