Keyboard not working.

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
Lionel
Member
Member
Posts: 117
Joined: Fri Jul 16, 2010 2:16 pm
Libera.chat IRC: ryanel
Location: California

Keyboard not working.

Post by Lionel »

Hello!,
I'm sorry about another possibly noobish question.
Anyway, I was following Bran's tutorial. And I was on the last part (keyboard) and when I added it to the list of things to compile and link, everything was ok. But when I run it, I get this:Image
keyboard_handler(); never gets called, so no output is printed.
Could someone help me please?
kb.c

Code: Select all

#include "common.h"

/* KBDUS means US Keyboard Layout. This is a scancode table
*  used to layout a standard US keyboard. I have left some
*  comments in to give you an idea of what key is what, even
*  though I set it's array index to 0. You can change that to
*  whatever you want using a macro, if you wish! */
unsigned char kbdus[128] =
{
    0,  27, '1', '2', '3', '4', '5', '6', '7', '8',	/* 9 */
  '9', '0', '-', '=', '\b',	/* Backspace */
  '\t',			/* Tab */
  'q', 'w', 'e', 'r',	/* 19 */
  't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',		/* Enter key */
    0,			/* 29   - Control */
  'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',	/* 39 */
 '\'', '`',   0,		/* Left shift */
 '\\', 'z', 'x', 'c', 'v', 'b', 'n',			/* 49 */
  'm', ',', '.', '/',   0,					/* Right shift */
  '*',
    0,	/* Alt */
  ' ',	/* Space bar */
    0,	/* Caps lock */
    0,	/* 59 - F1 key ... > */
    0,   0,   0,   0,   0,   0,   0,   0,
    0,	/* < ... F10 */
    0,	/* 69 - Num lock*/
    0,	/* Scroll Lock */
    0,	/* Home key */
    0,	/* Up Arrow */
    0,	/* Page Up */
  '-',
    0,	/* Left Arrow */
    0,
    0,	/* Right Arrow */
  '+',
    0,	/* 79 - End key*/
    0,	/* Down Arrow */
    0,	/* Page Down */
    0,	/* Insert Key */
    0,	/* Delete Key */
    0,   0,   0,
    0,	/* F11 Key */
    0,	/* F12 Key */
    0,	/* All other keys are undefined */
};

/* Handles the keyboard interrupt */
void keyboard_handler(struct regs *r)
{
    unsigned char scancode;

    /* Read from the keyboard's data buffer */
    scancode = kinportb(0x60);

    /* If the top bit of the byte we read from the keyboard is
    *  set, that means that a key has just been released */
    if (scancode & 0x80)
    {
        /* You can use this one to see if the user released the
        *  shift, alt, or control keys... */
    }
    else
    {
        /* Here, a key was just pressed. Please note that if you
        *  hold a key down, you will get repeated key press
        *  interrupts. */

        /* Just to show you how this works, we simply translate
        *  the keyboard scancode into an ASCII value, and then
        *  display it to the screen. You can get creative and
        *  use some flags to see if a shift is pressed and use a
        *  different layout, or you can add another 128 entries
        *  to the above layout to correspond to 'shift' being
        *  held. If shift is held using the larger lookup table,
        *  you would add 128 to the scancode when you look for it */
        putch(kbdus[scancode]);
    }
}

/* Installs the keyboard handler into IRQ1 */
void keyboard_install()
{
    irq_install_handler(1, keyboard_handler);
}
irq.c

Code: Select all

#include "common.h"

/* These are own ISRs that point to our special IRQ handler
*  instead of the regular 'fault_handler' function */
extern void irq0();
extern void irq1();
extern void irq2();
extern void irq3();
extern void irq4();
extern void irq5();
extern void irq6();
extern void irq7();
extern void irq8();
extern void irq9();
extern void irq10();
extern void irq11();
extern void irq12();
extern void irq13();
extern void irq14();
extern void irq15();

/* This array is actually an array of function pointers. We use
*  this to handle custom IRQ handlers for a given IRQ */
void *irq_routines[16] =
{
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0
};

/* This installs a custom IRQ handler for the given IRQ */
void irq_install_handler(int irq, void (*handler)(struct regs *r))
{
    irq_routines[irq] = handler;
    puts("Handler Installed!\n");
}

/* This clears the handler for a given IRQ */
void irq_uninstall_handler(int irq)
{
    irq_routines[irq] = 0;
}

/* Normally, IRQs 0 to 7 are mapped to entries 8 to 15. This
*  is a problem in protected mode, because IDT entry 8 is a
*  Double Fault! Without remapping, every time IRQ0 fires,
*  you get a Double Fault Exception, which is NOT actually
*  what's happening. We send commands to the Programmable
*  Interrupt Controller (PICs - also called the 8259's) in
*  order to make IRQ0 to 15 be remapped to IDT entries 32 to
*  47 */
void irq_remap(void)
{
    koutportb(0x20, 0x11);
    koutportb(0xA0, 0x11);
    koutportb(0x21, 0x20);
    koutportb(0xA1, 0x28);
    koutportb(0x21, 0x04);
    koutportb(0xA1, 0x02);
    koutportb(0x21, 0x01);
    koutportb(0xA1, 0x01);
    koutportb(0x21, 0x0);
    koutportb(0xA1, 0x0);
    putsid(2,"IRQ Installer", "IRQ remapped successfully!");
}

/* We first remap the interrupt controllers, and then we install
*  the appropriate ISRs to the correct entries in the IDT. This
*  is just like installing the exception handlers */
void irq_install()
{
    irq_remap();
    idt_set_gate(32, (unsigned)irq0, 0x08, 0x8E);
    idt_set_gate(33, (unsigned)irq1, 0x08, 0x8E);
    idt_set_gate(34, (unsigned)irq2, 0x08, 0x8E);
    idt_set_gate(35, (unsigned)irq3, 0x08, 0x8E);
    idt_set_gate(36, (unsigned)irq4, 0x08, 0x8E);
    idt_set_gate(37, (unsigned)irq5, 0x08, 0x8E);
    idt_set_gate(38, (unsigned)irq6, 0x08, 0x8E);
    idt_set_gate(39, (unsigned)irq7, 0x08, 0x8E);
    idt_set_gate(40, (unsigned)irq8, 0x08, 0x8E);
    idt_set_gate(41, (unsigned)irq9, 0x08, 0x8E);
    idt_set_gate(42, (unsigned)irq10, 0x08, 0x8E);
    idt_set_gate(43, (unsigned)irq11, 0x08, 0x8E);
    idt_set_gate(44, (unsigned)irq12, 0x08, 0x8E);
    idt_set_gate(45, (unsigned)irq13, 0x08, 0x8E);
    idt_set_gate(46, (unsigned)irq14, 0x08, 0x8E);
    idt_set_gate(47, (unsigned)irq15, 0x08, 0x8E);
    putsid(2,"IRQ Installer", "IRQ has been installed successfully!");
}

/* Each of the IRQ ISRs point to this function, rather than
*  the 'fault_handler' in 'isrs.c'. The IRQ Controllers need
*  to be told when you are done servicing them, so you need
*  to send them an "End of Interrupt" command (0x20). There
*  are two 8259 chips: The first exists at 0x20, the second
*  exists at 0xA0. If the second controller (an IRQ from 8 to
*  15) gets an interrupt, you need to acknowledge the
*  interrupt at BOTH controllers, otherwise, you only send
*  an EOI command to the first controller. If you don't send
*  an EOI, you won't raise any more IRQs */
void irq_handler(struct regs *r)
{
    /* This is a blank function pointer */
    void (*handler)(struct regs *r);

    /* Find out if we have a custom handler to run for this
    *  IRQ, and then finally, run it */
    handler = irq_routines[r->int_no - 32];
    if (handler)
    {
        handler(r);
        putsid(2,"IRQ", "IRQ handled!");
    }

    /* If the IDT entry that was invoked was greater than 40
    *  (meaning IRQ8 - 15), then we need to send an EOI to
    *  the slave controller */
    if (r->int_no >= 40)
    {
        koutportb(0xA0, 0x20);
    }

    /* In either case, we need to send an EOI to the master
    *  interrupt controller too */
    koutportb(0x20, 0x20);
}
I even copied the code exactly from the tutorial(making edits like making outportb koutportb)
I thank you in advance for any help received.
~Lionel
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: Keyboard not working.

Post by thepowersgang »

Have you enabled interrupts? Is the IDT entry correct? What does bochs say about the keyboard controller state?
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
Lionel
Member
Member
Posts: 117
Joined: Fri Jul 16, 2010 2:16 pm
Libera.chat IRC: ryanel
Location: California

Re: Keyboard not working.

Post by Lionel »

I enabled interrupts with __asm__ __volatile__ ("sti");
The IDT has been installed successfully and the entry is correct.
And I use qemu (Shown in screenshot), so I don't know about it's state.
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: Keyboard not working.

Post by thepowersgang »

That was actually a hint to use bochs as well (I use Qemu mostly nowadays, but for low level bugs, Bochs comes out again)

I remember that I used to hit a bug in Qemu (or, at least my keyboard code did) where I never got an interrupt, try reading from the keyboard data port after enabling the keyboard driver, that may fix things (as it ACKs any interrupts delivered before the handler is assigned)
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
Lionel
Member
Member
Posts: 117
Joined: Fri Jul 16, 2010 2:16 pm
Libera.chat IRC: ryanel
Location: California

Re: Keyboard not working.

Post by Lionel »

I always find bochs hard to use. But I'll try it again.
User avatar
Lionel
Member
Member
Posts: 117
Joined: Fri Jul 16, 2010 2:16 pm
Libera.chat IRC: ryanel
Location: California

Re: Keyboard not working.

Post by Lionel »

Sorry for the double-post. but bochs does it too.
User avatar
Karlosoft
Member
Member
Posts: 277
Joined: Thu Feb 14, 2008 10:46 am
Location: Italy
Contact:

Re: Keyboard not working.

Post by Karlosoft »

My keyboard driver still doesn't work on bochs but I solved lots of problem on real hardware asking a restart of the keyboard with commands.
Luns
Member
Member
Posts: 56
Joined: Sun May 01, 2011 12:15 am

Re: Keyboard not working.

Post by Luns »

In your PIC remap function, it looks a message is supposed to be printed to the screen. Is that the case? Because I don't see the output in your screenshot.

Do you know if your irq_handler function ever gets called?
User avatar
Lionel
Member
Member
Posts: 117
Joined: Fri Jul 16, 2010 2:16 pm
Libera.chat IRC: ryanel
Location: California

Re: Keyboard not working.

Post by Lionel »

No, the irq handler is never called.
User avatar
Nessphoro
Member
Member
Posts: 308
Joined: Sat Apr 30, 2011 12:50 am

Re: Keyboard not working.

Post by Nessphoro »

Hmm printf "key pressed" in the keyboard_handler
User avatar
Lionel
Member
Member
Posts: 117
Joined: Fri Jul 16, 2010 2:16 pm
Libera.chat IRC: ryanel
Location: California

Re: Keyboard not working.

Post by Lionel »

Nevermind about this, I got it working , I don't know that happened but restarting the kernel from scratch helped!
Post Reply