diff --git a/Makefile b/Makefile index 5c10641..f87bae7 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # or maybe add it to a bash script instead? im not sure CC = i686-elf-gcc -CFLAGS = -m32 -ffreestanding -Wall -Wextra -Werror -Wpedantic --sysroot=$(PWD)/sysroot -isystem=/usr/include -Iinclude -MD -D__TESTING__ +CFLAGS = -m32 -ffreestanding -Wall -Wextra -Werror -Wpedantic --sysroot=$(PWD)/sysroot -isystem=/usr/include -Iinclude -MD -D__TESTING__ AS = nasm ASFLAGS = -f elf @@ -44,8 +44,9 @@ os.iso: kernel.elf grub-mkrescue -o $@ iso run: os.iso - bochs -f util/bochsrc.txt -q - + kitty --hold sh -c "gdb kernel.elf -x util/gdbcmds" & + qemu-system-i386 -s -cdrom os.iso + #TODO: when i inevitably do add libc, this is going to fail because they have the same name as the libk objects #TODO: so we'll need to do a batch rename on one of the two object files, libc.a: CFLAGS:=$(CFLAGS) -D__is_libc # Target rule to define __is_libc diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..d2f5cc2 --- /dev/null +++ b/TODO.md @@ -0,0 +1,7 @@ +## What do I need to do? + +Exception handling is a must for next part, we need to be able to dianogse issues better + + - Want the address of the fault + - Proper handling of the issue + - Maybe dump registers? diff --git a/kernel/arch/gdt/gdt_entry.c b/kernel/arch/gdt/gdt_entry.c index 615ac85..2e858a8 100644 --- a/kernel/arch/gdt/gdt_entry.c +++ b/kernel/arch/gdt/gdt_entry.c @@ -70,6 +70,8 @@ void gdt_init(void) reloadSegments(); #ifdef __TESTING__ kinfo("Initialized the GDT"); +#endif +#ifdef __TESTING__ dump_gdt(); #endif } diff --git a/kernel/arch/idt/idt.c b/kernel/arch/idt/idt.c index f0fd2c7..9000381 100644 --- a/kernel/arch/idt/idt.c +++ b/kernel/arch/idt/idt.c @@ -27,18 +27,10 @@ void exception_handler(unsigned int i) } if (i == PIC_KEYB) { -#ifdef __TESTING__ - //kinfo("Sending EOI instruction to KEYB"); -#endif unsigned char in = inb(0x60); - - char to_print = decode_key_enum(decode_scancode(in)); - if (to_print != '\0') - printf("%c", to_print); - - /** - * TODO: this is a cute temporary fix but lets do a real keyboard driver please? - */ +#ifdef __TESTING__ + printf("scancode: %x\n", in); +#endif PIC_sendEOI(1); } diff --git a/kernel/arch/io/keyb.c b/kernel/arch/io/keyb.c index 9145ff0..b0deb4a 100644 --- a/kernel/arch/io/keyb.c +++ b/kernel/arch/io/keyb.c @@ -1,126 +1,95 @@ #include #include +#include + +#ifdef __TESTING__ +#include +#include +#endif #include +#include bool is_shift_down = false; +queue kb_cmd_queue; + +// current plan is to create a a multi d array +// +// +// 16 entries each for each scan code... so +// 0x01..0x0F (15)/ this is the top row, so esc - 1..0, etc +// 0x10..0x1F (16) ... +// 0x20..0x2F ... +// these arrays will keep a 0/1 flag to see if these keys are pressed +// as a stort of state machine +// this will also let us tell multiple keys pressed +// +// another more simple version, which i could start with +// +// is do a Single character as currently pressed +// and a bitflag we can mask for leftshift, leftctrl, right shift, right ctrl, alt, etc being pressed down +// +// +// + +struct keyboard_state keyb_state; + +void init_kb(void) +{ +#ifdef __TESTING__ + puts("Initializing keyboard driver!"); +#endif + init_queue(&kb_cmd_queue); + + keyb_state.leds = 0; + + queue_kb_command(KEYB_CMD_ENABLE_SCANNING); + queue_kb_command(KEYB_CMD_SET_DEFAULT_PARAMS); + + //queue_kb_command(KEYB_CMD_SET_TYPEMATIC); + //queue_kb_command(0x1F); + + + send_kb_commands(); + + +#ifdef __TESTING__ + puts("Initialized keyboard driver!"); +#endif +} + +void queue_kb_command(uint8_t command) + {enqueue(&kb_cmd_queue, command);} + +void send_kb_commands(void) +{ + int i; + uint8_t resp, cmd; + while (!queue_is_empty(&kb_cmd_queue)) { + cmd = queue_peek(&kb_cmd_queue); + for (i = 0; i < KEYB_CMD_RETRIES; i++) { + outb(KEYB_PORT, cmd); + io_wait(); + resp = inb(KEYB_PORT); + io_wait(); + + switch(resp) { + case KEYB_RESP_ACK: + break; + case KEYB_RESP_RESEND: + continue; + default: + break; + } + + } + dequeue(&kb_cmd_queue); + } +} + kb_key_press_t decode_scancode(uint8_t scancode) {return (kb_key_press_t) scancode;} -// TODO: check the shift scan code as a boolean, if yes ... blah blah -char decode_key_enum(kb_key_press_t keycode) -{ - switch(keycode) { - case KEY_Q: - return (is_shift_down) ? 'Q' : 'q'; - case KEY_W: - return (is_shift_down) ? 'W' : 'w'; - case KEY_E: - return (is_shift_down) ? 'E' : 'e'; - case KEY_R: - return (is_shift_down) ? 'R' : 'r'; - case KEY_T: - return (is_shift_down) ? 'T' : 't'; - case KEY_Y: - return (is_shift_down) ? 'Y' : 'y'; - case KEY_U: - return (is_shift_down) ? 'U' : 'u'; - case KEY_I: - return (is_shift_down) ? 'I' : 'i'; - case KEY_O: - return (is_shift_down) ? 'O' : 'o'; - case KEY_P: - return (is_shift_down) ? 'P' : 'p'; - case KEY_A: - return (is_shift_down) ? 'A' : 'a'; - case KEY_S: - return (is_shift_down) ? 'S' : 's'; - case KEY_D: - return (is_shift_down) ? 'D' : 'd'; - case KEY_F: - return (is_shift_down) ? 'F' : 'f'; - case KEY_G: - return (is_shift_down) ? 'G' : 'g'; - case KEY_H: - return (is_shift_down) ? 'H' : 'h'; - case KEY_J: - return (is_shift_down) ? 'J' : 'j'; - case KEY_K: - return (is_shift_down) ? 'K' : 'k'; - case KEY_L: - return (is_shift_down) ? 'L' : 'l'; - case KEY_Z: - return (is_shift_down) ? 'Z' : 'z'; - case KEY_X: - return (is_shift_down) ? 'X' : 'x'; - case KEY_C: - return (is_shift_down) ? 'C' : 'c'; - case KEY_V: - return (is_shift_down) ? 'V' : 'v'; - case KEY_B: - return (is_shift_down) ? 'B' : 'b'; - case KEY_N: - return (is_shift_down) ? 'N' : 'n'; - case KEY_M: - return (is_shift_down) ? 'M' : 'm'; - case KEY_1: - return (is_shift_down) ? '!' : '1'; - case KEY_2: - return (is_shift_down) ? '@' : '2'; - case KEY_3: - return (is_shift_down) ? '#' : '3'; - case KEY_4: - return (is_shift_down) ? '$' : '4'; - case KEY_5: - return (is_shift_down) ? '%' : '5'; - case KEY_6: - return (is_shift_down) ? '^' : '6'; - case KEY_7: - return (is_shift_down) ? '&' : '7'; - case KEY_8: - return (is_shift_down) ? '*' : '8'; - case KEY_9: - return (is_shift_down) ? '(' : '9'; - case KEY_0: - return (is_shift_down) ? ')' : '0'; - case KEY_MINUS: - return (is_shift_down) ? '_' : '-'; - case KEY_EQUALS: - return (is_shift_down) ? '=' : '+'; - case KEY_LEFT_BRACKET: - return (is_shift_down) ? '{' : '['; - case KEY_RIGHT_BRACKET: - return (is_shift_down) ? '}' : ']'; - case KEY_BACKSLASH: - return (is_shift_down) ? '|' : '\\'; - case KEY_SEMICOLON: - return (is_shift_down) ? ':' : ';'; - case KEY_SINGLE_QUOTE: - return (is_shift_down) ? '\"' : '\''; - case KEY_COMMA: - return (is_shift_down) ? '<' : ','; - case KEY_PERIOD: - return (is_shift_down) ? '>' : '.'; - case KEY_FORWARDSLASH: - return (is_shift_down) ? '?' : '/'; - case KEY_BACK_TICK: - return (is_shift_down) ? '~' : '`'; - case KEY_ENTER: - return '\n'; - case KEY_SPACE: - return ' '; - case KEY_LEFT_SHIFT: - case KEY_RIGHT_SHIFT: - is_shift_down = true; - return '\0'; - case KEY_LEFT_SHIFT_R: - case KEY_RIGHT_SHIFT_R: - is_shift_down = false; - return '\0'; // TODO: should i send a character on a no op key? - default: - return '\0'; - } -} diff --git a/kernel/include/kernel/x86/keyb.h b/kernel/include/kernel/x86/keyb.h index 7330bbf..836563c 100644 --- a/kernel/include/kernel/x86/keyb.h +++ b/kernel/include/kernel/x86/keyb.h @@ -3,9 +3,37 @@ #ifndef ARCH_KEYB_H #define ARCH_KEYB_H -#define KEYB_DATA_PORT (0x60) -#define KEYB_STATUS_PORT (0x64) -#define KEYB_COMMAND_PORT (0x64) +#define KEYB_PORT (0x60) + +#define KEYB_CMD_RETRIES 3 + +#define KEYB_CMD_SET_LEDS (0xED) +#define KEYB_CMD_ECHO (0xEE) +#define KEYB_CMD_DO_SCAN_CODE (0xF0) +#define KEYB_CMD_IDENTIFY_KEYB (0xF2) +#define KEYB_CMD_SET_TYPEMATIC (0xF3) +#define KEYB_CMD_ENABLE_SCANNING (0xF4) +#define KEYB_CMD_DISABLE_SCANNING (0xF5) +#define KEYB_CMD_SET_DEFAULT_PARAMS (0xF6) +#define KEYB_CMD_TYPEMATIC_AUTOREPEAT_3 (0xF7) +#define KEYB_CMD_ALL_MAKE_RELEASE_3 (0xF8) +#define KEYB_CMD_MAKE_ONLY_3 (0xF9) +#define KEYB_CMD_TYPE_AUTOREPEAT_MAKE_RELEASE_3 (0xFA) +#define KEYB_CMD_KEY_TYPEMATIC_AUTOREPEAT_3 (0xFB) +#define KEYB_CMD_KEY_MAKE_RELEASE_3 (0xFC) +#define KEYB_CMD_KEY_MAKE_3 (0xFD) +#define KEYB_RESEND_LAST_BYTE (0xFE) +#define KEYB_RESET_SELF_TEST (0xFF) + + +#define KEYB_LED_SCRL_LCK (1 << 0) +#define KEYB_LED_NUM_LCK (1 << 1) +#define KEYB_LED_CAP_LCK (1 << 2) + +#define KEYB_GET_SCAN_SET (0x00) +#define KEYB_SET_SCAN_1 (0x01) +#define KEYB_SET_SCAN_2 (0x02) +#define KEYB_SET_SCAN_3 (0x03) #define KEYB_RESP_ERR (0x00) @@ -72,7 +100,20 @@ typedef enum { KEY_F12_R, } kb_key_press_t; +struct keypress { + kb_key_press_t key_code; + uint8_t +}; +struct keyboard_state { + uint8_t leds; +}; + + +void init_kb(void); + +void send_kb_commands(void); +void queue_kb_command(uint8_t command); kb_key_press_t decode_scancode(uint8_t scancode); diff --git a/kernel/kmain.c b/kernel/kmain.c index 84586d6..45adc3e 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -7,6 +7,9 @@ #include #include #include +#include + + void kmain(void) { @@ -21,18 +24,8 @@ void kmain(void) terminal_initialize(); serial_initialize(); #endif - - -/** - * The computer is now hanging on INTERRUPT 32, - * this is good because that means the PIC is working, its the timer interrupt, except... the PIT is masked off... - * we need to now implement the ISR routines in exception_handler, - * first i want to implement all of the code for the basic exceptions.. - * then i want to setup the PIC triggers - * - * now for keyboard stuff, i believe i need to start looking into setting up a ps/2 driver before the interrupts will even start arriving.. - * - */ + + init_kb(); printf("Entering loop...\n"); while (1) { diff --git a/libc/queue/queue.c b/libc/queue/queue.c index 1553aba..2064fe0 100644 --- a/libc/queue/queue.c +++ b/libc/queue/queue.c @@ -14,7 +14,12 @@ void init_queue(queue *q) } bool queue_is_empty(queue *q) - {return (q->front == q->rear - 1);} ; // TODO: if this returns true, shouldn't we just be re-init-ing because we have the space to take up that used array +{ + bool empty = q->front == q->rear - 1; + if (empty) + init_queue(q); + return empty; +} bool queue_is_full(queue *q) {return (q->rear == MAX_QUEUE_SIZE);} // TODO: this is an error for SURE @@ -40,7 +45,7 @@ void dequeue(queue* q) q->front++; } -uint8_t peek(queue* q) +uint8_t queue_peek(queue* q) { if (queue_is_empty(q)) { #ifdef __TESTING__ diff --git a/util/bochsrc.txt b/util/bochsrc.txt deleted file mode 100644 index 0039aed..0000000 --- a/util/bochsrc.txt +++ /dev/null @@ -1,11 +0,0 @@ -megs: 32 -display_library: sdl -romimage: file=/usr/share/bochs/BIOS-bochs-latest -vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest -ata0-master: type=cdrom, path=os.iso, status=inserted -boot: cdrom -log: bochslog.txt -clock: sync=realtime, time0=local -cpu: count=1, ips=1000000 -com1: enabled=1, mode=file, dev=com1.out -keyboard: type=mf, serial_delay=150 diff --git a/util/gdbcmds b/util/gdbcmds new file mode 100644 index 0000000..83636e0 --- /dev/null +++ b/util/gdbcmds @@ -0,0 +1,2 @@ +target remote :1234 +c diff --git a/util/run-qemu.sh b/util/run-qemu.sh new file mode 100755 index 0000000..8705a7d --- /dev/null +++ b/util/run-qemu.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +qemu-system-i386 -s -cdrom os.iso & gdb kernel.elf -x=util/gdbcmds