Page 1 of 2

Keyboard driver in bran's tutorials

Posted: Sun May 17, 2015 4:38 am
by snasim2002
I have just started to follow bran's tutorials,and everything worked fine for me until the keyboard chapter. (I don't need the PIT.) The major problem with the keyboard driver is tha5 it always jumps to the function "keyboard_handler" whenever I press a key. As a result, it always does the same thing , and I can't control the keyboard by a "gets" or "getc" like function. What should I do now ?

Re: Keyboard driver in bran's tutorials

Posted: Sun May 17, 2015 5:09 am
by Nable
snasim2002 wrote:What should I do now?
You should implement some buffer for codes of pressed keys. Interrupt handler puts codes to this buffer and get functions either fetch data from it (if data is available) or wait for something to appear in it. This is a simplified point of view (there may be multiple/different keyboards and multiple applications that want keyboard input) but I hope that you've got the idea.

Re: Keyboard driver in bran's tutorials

Posted: Wed May 20, 2015 6:33 am
by snasim2002
Can u give a sample code snippet ??

Re: Keyboard driver in bran's tutorials

Posted: Wed May 20, 2015 7:40 am
by no92
snasim2002 wrote:Can u give a sample code snippet ??
Probably, nobody will. Do you know how to create a buffer, write and read to/from it? Also, have you read and understood this?

Re: Keyboard driver in bran's tutorials

Posted: Thu May 21, 2015 7:48 am
by jtokarchuk
I was in the same position as you, and I didn't get any hand holding either.

This may seem cold, or elitist, but it's not. It emulates the environment which you are trying to create.

There is nothing pre-created there to help you. You have to essentially "invent" it yourself. This is the fun of osdev. Tinkering and figuring out how things work. It took me weeks to wrap my head around how a keyboard buffer worked, and how to implement getch() and gets() (rather than simply hitting a key and printing it to screen)

Am I doomed to having a crappy os that will never work properly? Oh probably, but it's mine and I can say I created it; and that is pretty damn satisfying when you make something work.

If you want it handed to you, you may be more suited to userland development, either in someone else's osdev project or on win32/mac/*nix.

at the end of the day, it boils down to a pretty basic programming skill: problem solving.

- why is my keyboard routine printing characters?: putch() is in there. let's remove it and see what happens. Hey, it stopped!
- what can I implement that can store inputted scancodes in a circular basis? sounds like an array and some counting logic.
- how can i make the os stop and wait for a string? sounds like a while loop waiting for someone to hit enter.

That's about as close as you will get to a snippet.

Re: Keyboard driver in bran's tutorials

Posted: Sat May 23, 2015 7:14 am
by snasim2002
Thanks, jtokarchuk !!
That really worked for me !!

Re: Keyboard driver in bran's tutorials

Posted: Sat May 23, 2015 7:18 am
by snasim2002
All I did was to create an external variable available from anywhere in my code, and I added a while loop in the main(). It stopped looping when I pressed the "d" key , and jumped to another dummy function, which prints "YOU PRESSED THE D KEY !!".

Re: Keyboard driver in bran's tutorials

Posted: Sat May 23, 2015 7:20 am
by Combuster
Hmm... volatile?

Re: Keyboard driver in bran's tutorials

Posted: Sat May 23, 2015 9:23 am
by Brendan
Hi,
snasim2002 wrote:All I did was to create an external variable available from anywhere in my code, and I added a while loop in the main(). It stopped looping when I pressed the "d" key , and jumped to another dummy function, which prints "YOU PRESSED THE D KEY !!".
Eventually you will need some sort of FIFO buffer, so that if the user presses 33 different keys before software reads from the keyboard the first 32 key presses aren't lost.

Ideally, this FIFO buffer will be built into some sort of communication mechanism, like pipes or messaging; so that the act of sending the key press causes it to be buffered automatically (and so that whatever is on the other end can tell the scheduler "don't give me CPU time until data arrives" to wait for data to be received, where the kernel will wake it up and the scheduler will give it CPU time again when data does arrive so that it doesn't need to waste CPU time checking all the time).

Also note that things like key presses tend to be transferred around a lot - the keyboard driver's IRQ handler might get the raw scan-code and send it (via. messaging or pipe or whatever) to the rest of the keyboard driver (to minimise the time spent inside the IRQ handler); the rest of the keyboard driver might process the daylights out of it (e.g. use lookup tables for the specific keyboard layout that it loaded from a file to convert the scancode into a some sort of "key event") and send it to some sort of upper layer (that allows different devices - e.g. keyboard, mouse, joystick, monitors, sound cards - to be assigned to one of potentially multiple users); and that upper layer might send it to a user's GUI, where the GUI checks it to see if it's "global" (e.g. "alt+tab") and either handles it itself or sends it to the application that currently has focus; where the application that has focus might be a terminal layer that converts the "key event" into something lame ("stdin") and sends it to a child process, which might be a command line shell thing that sends it to another process, which might be a telnet client that sends it over the network to a different computer.

As you can hopefully guess; "some sort of communication mechanism" has an extremely important role in all of this. It's the part that ties everything together, and it has a major effect on scheduling (all those pieces blocking and unblocking due to waiting for data to be received), and also has a strong influence on what writing software for the OS is like.


Cheers,

Brendan

Re: Keyboard driver in bran's tutorials

Posted: Fri May 29, 2015 11:30 am
by snasim2002
Here is the code I had used in my keyboard driver source :
#include "../system.h" int _TMP_; char _kdata[]; char i[]; unsigned char kbdus[] = { 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 = inportb(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 { _kdata[_TMP_] = kbdus[scancode]; _TMP_++; } } void kdata_flush() { if (_TMP_ != 0) _TMP_ = 0; if (*_kdata != 0) *_kdata = 0; } int gets () { kdata_flush(); while (_kdata[_TMP_] != '\n') { if (i[_TMP_] != _kdata[_TMP_]) i[_TMP_] = _kdata[_TMP_]; } int retv = (int) *_kdata; return retv; } /* Installs the keyboard handler into IRQ1 */void keyboard_install() { irq_install_handler(1, keyboard_handler); }
It is not working when I call gets() from main. Where is the problem ??

Re: Keyboard driver in bran's tutorials

Posted: Fri May 29, 2015 12:40 pm
by alexander
Please put your code in code tags. How does the gets function get called from main. Shouldn't gets copy the contents of _kdata to an adress you put in the arguments? I don't see the point in turning the pointer into an int.

Re: Keyboard driver in bran's tutorials

Posted: Fri May 29, 2015 12:41 pm
by jtokarchuk
Please unsquish that an use code tags. My eyes are bleeding.

Re: Keyboard driver in bran's tutorials

Posted: Sat May 30, 2015 11:25 am
by snasim2002
Sorry, Here's the code :

Code: Select all

#include "../system.h"
int _TMP_; char _kdata[]; char i[];
unsigned char kbdus[] =
{
    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 = inportb(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
    {
	_kdata[_TMP_] = kbdus[scancode]; _TMP_++;
    }
}
void kdata_flush()
{
   if (_TMP_ != 0)
	_TMP_ = 0;
   if (*_kdata != 0)
	*_kdata = 0;
}
int gets ()
{
   kdata_flush();
   while (_kdata[_TMP_] != '\n')
   {
	if (i[_TMP_] != _kdata[_TMP_])
    		i[_TMP_] = _kdata[_TMP_];
   }
   int retv = (int) _kdata;
   return retv;
}
/* Installs the keyboard handler into IRQ1 */
void keyboard_install()
{
    irq_install_handler(1, keyboard_handler);
}

Re: Keyboard driver in bran's tutorials

Posted: Sat May 30, 2015 11:42 pm
by alexander
I think char i[] should be volatile. Also you didn't tell me how you are calling the gets function in your main kernel loop

Re: Keyboard driver in bran's tutorials

Posted: Sun May 31, 2015 3:57 am
by snasim2002
I'm calling gets as:
int aa=gets();