Page 1 of 4

Keyboard Handler

Posted: Sun May 08, 2005 4:50 am
by Zioo
Hello..
I'm trying to write a keyboard handler but, I can't get it working. When i press a key nothing happens :(

I use this code..

Code: Select all

From my keyboard.c file
--------------------------------

extern void keyb_ISR();

asm (
   ".globl _keyb_ISR        \n"
   "_keyb_ISR:              \n"
   "   pusha               \n" /* Save all registers               */
   "   pushw %ds           \n" /* Set up the data segment          */
   "   pushw %es           \n"
   "   pushw %ss           \n" /* Note that ss is always valid     */
   "   pushw %ss           \n"
   "   popw %ds            \n"
   "   popw %es            \n"
   "                       \n"
   "   call _keyboard_ISR   \n"
   "                       \n"
   "   popw %es            \n"
   "   popw %ds            \n" /* Restore registers                */
   "   popa                \n"
   "   iret                \n" /* Exit interrupt                   */
);

void keyboard_ISR(void)
{   
kprintf("Key Pressed!",0,0,BLUE_TXT);
}

void enable_kisr()
{
 unsigned scancode;  
 scancode = inportb(0x60); 
 AddInt(0x21, keyb_ISR, 0);
 outportb(0x21, (inportb(0x21) & 0xFD));      // Enable IRQ 1
}
And in my kernel.c file call I the enable_kisr(); function...
???

Re:Keyboard Handler

Posted: Sun May 08, 2005 5:53 am
by Pype.Clicker
- i don't see the point of reading the scancode in "enable isr"
- you seems not to have an "EOI" signal sent, so if you manage to have your handler called, it will be called at most once.

Re:Keyboard Handler

Posted: Sun May 08, 2005 7:12 am
by Brendan
Hi,
Pype.Clicker wrote: - i don't see the point of reading the scancode in "enable isr"
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".

My OS's (the current one and several previous versions) have a boot menu in real mode followed by a reasonably lengthy delay before the keyboard ISR is installed. In this situation it isn't uncommon for the user to press the enter key (the "Boot OS Now!" menu option) to begin the boot process, but then release the enter key before the keyboard ISR is ready, leaving the "enter key released" stuck in the keyboard controller's buffer.
Pype.Clicker wrote:- you seems not to have an "EOI" signal sent, so if you manage to have your handler called, it will be called at most once.
Both the EOI and a "inportb(0x60)" are missing - either will prevent more than one IRQ from being received (but neither explain the lack of a first IRQ).

To find the problem with the first IRQ I'd do 2 tests. The first test would be using the code (as it exists now) with the addition of an "INT 0x21" at the end of "enable_kisr()". This would check the IDT entry, ISR stub and the "kprintf()" code.

The second test (if the first works fine) would be to add the EOI code and change "enable_kisr()" to:

Code: Select all

void enable_kisr()
{
    unsigned scancode; 
    scancode = inportb(0x60);
    AddInt(0x20, keyb_ISR, 0);
    outportb(0x21, (inportb(0x21) & 0xFE));      // Enable IRQ 0!
}
This would set it up so that IRQ0 (the PIT timer, which should still be generating an IRQ every 18.2 Hz and can't become "jammed") triggers the ISR instead, and will test the PIC configuration and CLI/STI problems.

At least one of these tests will fail - which one?


Cheers,

Brendan

Re:Keyboard Handler

Posted: Sun May 08, 2005 7:15 am
by Zioo
I've change my code and it's now look like this
But it does still not work.. Maybe i'm missing something important, but I don't know what...

Code: Select all

;; Assembler part of the IRQ1 handler
[extern _keyboard_ISR]
[global _irq1]
_irq1:
     pusha
     push ds
     push es
     push fs
     push gs
     mov eax,0x10   ; Data segment
     mov ds,eax
     cld
     call _keyboard_ISR
     pop gs
     pop fs
     pop es
     pop ds
     popa
     iret

/*Called from the assembly function*/
void keyboard_ISR(void)
{   
int co = inportb(0x60);
outportb(0x20, 0x20);  // Send EOI
clrscr();
k_print_nr(co);
}

/*Enable keyboard at IRQ1; Called on startup*/
void enable_kisr()
{
     AddInt(21, irq1, 0);
     outportb(0x21, (inportb(0x21) & 0xFD));      // Enable IRQ 1
}

Re:Keyboard Handler

Posted: Sun May 08, 2005 7:26 am
by Brendan
Hi,

Are you sure? - "AddInt(21, irq1, 0);" isn't the same as "AddInt(0x21, irq1, 0);" (the former seems wrong to me, while the latter is what was originally posted).

Despite this, see the tests mentioned in my previous post...


Cheers,

Brendan

Re:Keyboard Handler

Posted: Sun May 08, 2005 7:43 am
by Zioo
allright when i add 'asm("int $0x21");' at the end of enable_kisr(); get i this error "General Protection Fault"

Re:Keyboard Handler

Posted: Sun May 08, 2005 8:20 am
by Brendan
Hi,
Zioo wrote: allright when i add 'asm("int $0x21");' at the end of enable_kisr(); get i this error "General Protection Fault"
Well in that case I've got some bad news, and some bad news.

Firstly, for some reason the keyboard IRQ isn't getting to your keyboard ISR (otherwise you would've got a GPF before). Secondly there's something wrong with your code (it shouldn't generate a GPF with 'asm("int $0x21");' or if it receives a keyboard IRQ.

Of course I'm assuming you've changed the "AddInt(21, irq1, 0);" back to "AddInt(0x21, irq1, 0);". If you haven't it'd explain the GPF because you'd be installing an interrupt handler for interrupt 0x15 rather than interrupt 0x21 (there probably wouldn't be any interrupt handler for interrupt 0x21).


Cheers,

Brendan

Re:Keyboard Handler

Posted: Sun May 08, 2005 9:37 am
by Zioo
Good news :) I have made som changes and now can i run 'int 0x21' and then the keyboard_ISR function run... but it does still not run every time i press a key...

Re:Keyboard Handler

Posted: Sun May 08, 2005 10:20 am
by Brendan
Hi,
Zioo wrote: Good news :) I have made som changes and now can i run 'int 0x21' and then the keyboard_ISR function run... but it does still not run every time i press a key...
Good :)

When you say it doesn't run every time, do you mean it only runs once then stops, or does it seem to skip some keypresses (but otherwise seems to work)?

If it only works once, then it'd be the EOI, the "inportb(0x60);" or locking up after the IRQ - I doubt this is the problem though.

If it's randomly skipping some keypresses, then the keyboard ISR itself is probably working properly and the problem is most likely within "clrscr();" and/or "k_print_nr(co);". I'm guessing it's a re-entrancy problem (if you're using a trap gate rather than an interrupt gate for the keyboard IRQ's IDT descriptor) - try disabling interrupts within the keyboard ISR before entering the C code and see if it fixes it...

BTW when it is working correctly you should get at least 2 IRQs for each key (when the key is pressed and when it's released).


Cheers,

Brendan

Re:Keyboard Handler

Posted: Sun May 08, 2005 10:32 am
by Zioo
YES.. Now work it perfect ;D I just missed a asm("sti");

And thanks for your good help ;)

Re:Keyboard Handler

Posted: Wed Jul 27, 2005 9:21 am
by marcio.f
Hi,

I've remapped both PIC's so that IRQ0 starts at 0x20 and IRQ8 starts at 0x28, disabled all IRQ's, loaded the IDT, and installed an entry at position 1.

Then I enabled the keyboard only (IRQ1), and when I press a key Bochs (v2.2) panics:

Code: Select all

00024535235p[BIOS ] >>PANIC<< floppy recal:f07: ctrl not ready
00024536569p[CPU0 ] >>PANIC<< HALT instruction encountered in the BIOS ROM
00024536569p[CPU0 ] >>PANIC<< WARNING: HLT instruction with IF=0!
00310580000p[WGUI ] >>PANIC<< POWER button turned off.
Any code you might want to check, just tell me and I'll post it.
I have one more question: what's the meaning of "__attribute__((__packed__))" ?
Sorry if my questions are obvious or stupid :)

Thanks in advance,
Marcio

__attribute__

Posted: Wed Jul 27, 2005 9:43 am
by Arto
marcio.f wrote: I have one more question: what's the meaning of "__attribute__((__packed__))" ?
Take a look at the GCC docs for this: http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html

Re:Keyboard Handler

Posted: Wed Jul 27, 2005 9:50 am
by marcio.f
Thanks for the link Arto :)

Re:Keyboard Handler

Posted: Fri Jul 29, 2005 5:30 am
by marcio.f
I know my question must have been asked a lot of times but I really don't know where to continue, can someone help me please?

Re:Keyboard Handler

Posted: Fri Jul 29, 2005 5:34 am
by Solar
You checked the FAQ? (Too lazy to c&p the link, just click on the mega-tokyo.com banner...)