OSDev.org https://forum.osdev.org/ |
|
Keyboard https://forum.osdev.org/viewtopic.php?f=1&t=31935 |
Page 1 of 1 |
Author: | MichaelPetch [ Fri May 19, 2017 7:11 pm ] |
Post subject: | Re: Keyboard |
At first glance, in your code you have: Code: if (scan_code < 128); on_key(scan_code); I don't think you intended to put a semicolon ; on the end of the if statement. There may be other issues as well but thought I'd point this out. You say you are using GCC but the extern "C" usage suggests you are using g++ ? I have a concern about this: Code: void keyb_handler() { asm("pusha"); keyb_process_keys(); outb(PIC1_PORT, 0x20); asm("popa; leave; iret"); } This code assumes that there will be a stack frame generated, and even worse that stack frame will likely by default alter EBP before reaching PUSHA meaning that it is possible registers have been clobbered before saving them. If you are using GCC 7.1 or above the interrupt attribute on functions is no longer ignored for x86 targets. It is now documented in GCC this way: Quote: Interrupt .Use this attribute to indicate that the specified function is an interrupt handler or an exception handler (depending on parameters passed to the function, explained further). The compiler generates function entry and exit sequences suitable for use in an interrupt handler when this attribute is present. The IRET instruction, instead of the RET instruction, is used to return from interrupt handlers. All registers, except for the EFLAGS register which is restored by the IRET instruction, are preserved by the compiler. Since GCC doesn’t preserve MPX, SSE, MMX nor x87 states, the GCC option -mgeneral-regs-only should be used to compile interrupt and exception handlers Your other options are to create a stub (keyb_handler)in a separate assembly file that calls the keyb_process_keys in the C code. You can also do this with a basic ASM block outside of a function: Code: extern "C" void keyb_handler(void); extern "C" void keyb_process_keys(void); extern "C" void default_intr_handler(void); __asm__(".global default_intr_handler\n" "default_intr_handler:\n\t" "iret"); /* Define a keyboard handler stub that makes a call to a C function */ __asm__(".global keyb_handler\n" "keyb_handler:\n\t" "cld\n\t" /* Set direction flag forward for C functions */ "pusha\n\t" /* Save all the registers */ "call keyb_process_keys\n\t" "popa\n\t" /* Restore all the registers */ "iret"); Alter keyb_process_keys to be: Code: void keyb_process_keys() { if (inb(0x64) & 0x01) { unsigned char scan_code; unsigned char state; scan_code = inb(0x60); if (scan_code < 128) on_key(scan_code); } outb(PIC1_PORT, 0x20); } The other assumption is that you have properly generated a GDT (and loaded it) prior to calling kmain. You don't show us the rest of your code so it is hard to judge if there is a problem outside the concerns above. There may be other bugs in your bootloader and there is an indication in this code that you are not using a mulitboot loader (or something like it) and have coded your own bootloader to bootstrap you into the C code. |
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |