Page 1 of 1

I get a warning from my keyboard handler when I compile it

Posted: Wed Dec 16, 2015 4:05 pm
by kladfslkj
I used some code from Bran's Kernel Development Tutorial to get the keyboard to work. I had started with A LOT of warnings and errors, but I quickly solved all but one of them. I cannot understand why I am getting this error.

Code: Select all

kdb.c: In function 'keyboard_handler':
kdb.c:105:36: warning: unused parameter 'r' [-Wunused-parameter]
 void keyboard_handler(struct regs *r)
                                    ^
Now this seems to work on every OS that uses this code (Just about every C based hobby OS I have ever seen) except mine. And, I cannot figure out why.

Here's kdb.c (I know it should be kbd.c, it's not important right now) :

Code: Select all

#include "Include/irq.h" // Gives IRQ Functions
#include "Include/vga.h" // Gives VGA Functions
#include "Include/io.h" // Provides inb and outb

/* 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 = inb(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 */
        terminal_putchar(kbdus[scancode]);
        terminal_column++;
        update_cursor(0, terminal_column);
    }
}

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

Re: I get a warning from my keyboard handler when I compile

Posted: Wed Dec 16, 2015 4:14 pm
by kzinti
crank123 wrote:I cannot understand why I am getting this error.

Code: Select all

kdb.c: In function 'keyboard_handler':
kdb.c:105:36: warning: unused parameter 'r' [-Wunused-parameter]
void keyboard_handler(struct regs *r)
                                    ^
You joking right? There is even an arrow pointing to it.

Could it be because you aren't using parameter 'r' in your keyboard_handler function? Just a crazy guess.

Re: I get a warning from my keyboard handler when I compile

Posted: Wed Dec 16, 2015 4:21 pm
by kladfslkj
kiznit wrote: Could it be because you aren't using parameter 'r' in your keyboard_handler function?
But, I HAVE to use it. It won't work otherwise. Look at any other operating system that uses this code. They have it exactly like I do and they do not experience any problems. If I try to alter the code so I do not have to use this there is a whole other list of problems.

Re: I get a warning from my keyboard handler when I compile

Posted: Wed Dec 16, 2015 4:23 pm
by kladfslkj
Here's irq.c:

Code: Select all

#include "Include/boot.h"
#include "Include/io.h"
#include "Include/idt.h"
#include <stddef.h>
#include <stdint.h>


struct regs
{
    unsigned int gs, fs, es, ds;
    unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;
    unsigned int int_no, err_code;
    unsigned int eip, cs, eflags, useresp, ss;    
};

/* 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;
}

// 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)
{
    outb(0x20, 0x11);
    outb(0xA0, 0x11);
    outb(0x21, 0x20);
    outb(0xA1, 0x28);
    outb(0x21, 0x04);
    outb(0xA1, 0x02);
    outb(0x21, 0x01);
    outb(0xA1, 0x01);
    outb(0x21, 0x0);
    outb(0xA1, 0x0);
}

/* 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);
}

/* 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);
    }

    /* 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)
    {
        outb(0xA0, 0x20);
    }

    /* In either case, we need to send an EOI to the master
     * interrupt controller too */
    outb(0x20, 0x20);
}

Re: I get a warning from my keyboard handler when I compile

Posted: Wed Dec 16, 2015 4:41 pm
by Octocontrabass
crank123 wrote:
kiznit wrote: Could it be because you aren't using parameter 'r' in your keyboard_handler function?
But, I HAVE to use it.
Point out exactly where you use the "r" variable in the "keyboard_handler" function.

Re: I get a warning from my keyboard handler when I compile

Posted: Wed Dec 16, 2015 4:45 pm
by kladfslkj
When I install the handler.

Code: Select all

void irq_install_handler(int irq, void (*handler)(struct regs *r));
The function is supposed to represent the "void (*handler)(struct regs *r)".

Re: I get a warning from my keyboard handler when I compile

Posted: Wed Dec 16, 2015 4:54 pm
by intx13
crank123 wrote:When I install the handler.

Code: Select all

void irq_install_handler(int irq, void (*handler)(struct regs *r));
The function is supposed to represent the "void (*handler)(struct regs *r)".
This code defines a prototype for a function called "irq_install_handler" which takes two arguments. The first is an integer, the second is a pointer to a function that takes one argument (a "struct regs *" pointer). This has nothing to do with the warning you're seeing, which says that although the "keyboard_handler" takes an argument "r", the body of that function doesn't use it.

This is a perfect example of why you should not blindly copy code from a tutorial and expect it to work.

Re: I get a warning from my keyboard handler when I compile

Posted: Thu Dec 17, 2015 12:50 am
by MollenOS
kladfslkj wrote:
kiznit wrote: Could it be because you aren't using parameter 'r' in your keyboard_handler function?
But, I HAVE to use it. It won't work otherwise. Look at any other operating system that uses this code. They have it exactly like I do and they do not experience any problems. If I try to alter the code so I do not have to use this there is a whole other list of problems.
No, you absolutely do not HAVE to use it. You can easily silence the warning by doing

Code: Select all

(void)r;
But first things first, what you are doing is so wrong, by the fact you don't even seem to actually try to understand what the code does and how it's used. Many people that use that code atleast read the WIKI page on both the PS/2 Controller & how the PS/2 Keyboard works. Why don't you start out by reading them? After that I'd read up on how Irq's are used, eventually the PIC. The next thing would to be to improve your Irq handlers, you should definitely not just copy-paste the onces from the tutorial without trying to understand them. Use them for inspiration, write your own.

Now, you say that the "driver" you just showed us didn't work. Is interrupts enabled? Have you tried initializing the ps/2 controller? or enabling the ps/2 port? Have you tested your irq handlers?