Page 1 of 1

Problem with keyboard driver

Posted: Tue Jul 05, 2005 12:33 am
by beyondsociety
After taking a long break from coding, I decided to see if I could get a basic keyboard driver running, but no luck so far. I can manually call the keyboard interrupt (int $33) as well as enable the interrupt within the keyboard handler.

The problem is I only get one keypress and thats it. I have tried the two tests in this previous post to check my PIC, IDT, CLI/STI functions and I had no problems getting them to work. I also have added the the EOI, but I only get one keypress.

keyboard handler

I believe this is my problem, as if I look in the bochs error log, it gives me a "internal keyboard buffer full, ignoring scancode" and then the scancode.
If the OS (or boot code) masks IRQs, then the keyboard sends a byte, and then the OS's keyboard driver takes over (unmasks the IRQ in the PIC, etc) then you can have a byte "jammed" in the keyboard controller chip's buffer. In this case any further bytes sent by the keyboard will result in a "buffer overflow" condition, and will not generate an IRQ.

The easiest way to resolve this situation is to do a dummy "inportb(0x60)" as seen here. If the OS has a very small delay between masking the IRQs and installing a keyboard IRQ handler it will be very unlikely (but still possible) for the keyboard controller chip to become "jammed".
How do I add this extra dummy "importb(0x60)" to my code

Code: Select all

void init_keyboard(void)
{
???install_handlers(0x21, keyboard_handler, 0);
???outportb(0x21, (inportb(0x21) & 0xFD));
}

void keyboard_handler(void)
{  
???unsigned scancode;
???scancode = inportb(0x60); 
???printk("Testing\n");
}

; IRQ01 (Keyboard Interrupt)
[GLOBAL irq01]
[EXTERN _keyboard_handler]
irq01:
???pusha
???push ds
???push es
???push fs
???push gs

???call _keyboard_handler

???mov al, 0x20
???out 0x20, al

???pop gs
???pop fs
???pop es
???pop ds
???popa
???iret
Thanks in advance for any help.

Re:Problem with keyboard driver

Posted: Tue Jul 05, 2005 12:44 am
by Brendan
Hi,
beyondsociety wrote:How do I add this extra dummy "importb(0x60)" to my code
Try something like this:

Code: Select all

void init_keyboard(void)
{
   inportb(0x60)
   install_handlers(0x21, keyboard_handler, 0);
   inportb(0x60)
   outportb(0x21, (inportb(0x21) & 0xFD));
   inportb(0x60)
}

Cheers,

Brendan

Re:Problem with keyboard driver

Posted: Tue Jul 05, 2005 1:03 am
by mystran
What is said, is that every time you get an IRQ1, you should go and read port 0x60. You are doing it, so that is not the problem. One inportb(0x60) per interrupt should be enough.

What I suspect is that the problem is in PIC instead. Are you either masking, or handling all other interrupts (especially the PIT). At least add either a panic-handler (if you masked them), or proper EOI sender (if you don't mask) for other interrupts as well. Ofcourse, if you have a working clock built on PIT, then this is not likely to be the issue.

Unfortunately, that's all that comes to mind this early. I remember having a similar problem at some point, but I think it was an EOI thing then.

Btw, you're stub isn't setting ds/es, so if you're not in kernel when you get the IRQ, you've going to have wrong segments for the C code.