Page 1 of 1

input from keyboard

Posted: Fri Aug 29, 2014 12:32 am
by Tanzadeh
I write a very small kernel.and how can I get input from keyboard.

this is my kernel source code

main.c

Code: Select all

#include "M_include/stdio.h"
void main(void){
clear_screen();
k_print("Welcome to persianOS", 0x07);
}
stdio.h

Code: Select all

int k_print(const char *str, int color){
char *video = (char*) 0xB8000;
unsigned int i = 0;
unsigned int i2 = 0;
while(str[i2] != '\0'){
video[i] = str[i2];
video[i + 1] = color;
++i2;
i = i + 2;
}
}
int clear_screen(){
char *video = (char*) 0xB8000;
unsigned int i = 0;
unsigned int i2 = 0;
while(i2 <(80*25*2)){
video[i2] = ' ';
video[i2+1] = 0x02;
i2= i2 + 2;
}
}

Re: input from keyboard

Posted: Fri Aug 29, 2014 1:20 am
by Lionel
-sigh-

Okay, I need to tell you something; you don't have a kernel. You have the bare minimum to write to the screen. That isn't a kernel.

To get input from the keyboard, you need to receive IRQ1 from your interrupt handlers (and subsequently have a GDT and IDT present). Each time the interrupt is fired, you need to get the scan code and convert it into its ASCII representation. Then, you need to terminate the interrupt cleanly.

Do you understand what I'm saying? Probably not, if you did you wouldn't be asking such a question.

What you need to do is read the wiki, which has all the answers to basically any question buried deep inside. I will not find them for you; as a responsible and determined person you must search the wiki for these answers yourself. I however, was in the same situation once (though I didn't dare ask for help in this manner, i went straight to searching), so I will give you some pointers and directions to being successful in osdev.

First off, are you already an accomplished programmer (with over ... lets say 4 years experience)? If not, become one.
Secondly, are you prepared to do research? If not, don't even try.
If you are determined to be an OS Developer, not just interested in this like it was a fad; but genuinely interested, heed my advice:

Make sure you know everything, I really mean know everything at Required_Knowledge by heart.
Secondly, read Beginner_Mistakes, just as a precaution.
Third, read How_To_Ask_Questions and rephrase your question accurately. This will definitely make us care more and want to help you.
Fourth, read What_order_should_I_make_things_in for you to figure out what you need to do. All the answers are on the wiki.
Fifth, read the wiki itself. Click on every article you can. Each contains so much knowledge of people more competent then you or I.
And finally, sixth: The article on how to get keyboard input is on the left side of the homepage, under Booting and Setup.

Take care,
Lionel

P.S. If you don't understand a term, such as Interrupt, just google it and the word OSDev, and you'll find the definition most likely. Also, you can search the wiki or even ask here if your too confused.

Re: input from keyboard

Posted: Fri Aug 29, 2014 1:23 am
by Brendan
Hi,
Tanzadeh wrote:I write a very small kernel.and how can I get input from keyboard.
Getting input from the keyboard is easy. You just have to:
  • Use the PCI bus scanning code (that you don't have yet) to find USB controllers
  • Use your memory management (that you don't have yet) and your scheduler code (that you don't have yet) and file IO (that you don't have yet) to start the USB controller drivers
  • Let the USB controller driver initialise itself, including using the OS's IRQ handling code (that you don't have yet) to setup its IRQ
  • Use the USB controller drivers (that you don't have yet) to disable "PS/2 emulation"
  • Use the USB controller drivers (that you don't have yet) to enumerate USB devices and find any USB keyboards
  • Use your memory management (that you don't have yet) and your scheduler code (that you don't have yet) and file IO (that you don't have yet) to start the USB keyboard drivers
  • After you've disabled "PS/2 emulation" and know that you're able to talk to the real PS/2 controller (and not some dodgy fake thing):
    • Check ACPI tables to see if a real PS/2 controller actually exists
    • Use your memory management (that you don't have yet) and your scheduler code (that you don't have yet) and file IO (that you don't have yet) to start the PS/2 controller driver
    • Let the PS/2 controller driver initialise itself, including using the OS's IRQ handling code (that you don't have yet) to setup its IRQ
    • Use the PS/2 controller drivers (that you don't have yet) to find any PS/2 keyboards
    • Use your memory management (that you don't have yet) and your scheduler code (that you don't have yet) and file IO (that you don't have yet) to start the PS/2 keyboard driver
For the keyboard drivers themselves:
  • Use the OS's file IO (that you don't have yet) to read the keyboard driver's "configuration file" and determine the keyboard layout
  • Use the OS's file IO (that you don't have yet) to read the translation tables for that keyboard layout
  • Use the interface/API that you've designed and documented (that you don't have yet) to communicate with the (USB or PS/2) controller to receive bytes from the device and send bytes to the device
  • Use the kernel's IPC (that you don't have yet) to send "key-presses" to whatever (the GUI?)
Of course you might need to add a few things to your current kernel before you begin working on the keyboard driver/s themselves.. :lol:


Cheers,

Brendan

Re: input from keyboard

Posted: Fri Aug 29, 2014 2:34 am
by mallard
The first 7 of those steps are a bit pointless unless you actually have USB HID support. You don't want to disable PS/2 emulation unless you can actually use the keyboard "natively" (i.e. dealing with buggy emulation is better than having no keyboard). I don't think most BIOSs enable emulation unless there's actually a USB HID device connected (although some may enable it if there is only a USB mouse), in which case, there probably isn't a PS/2 keyboard.

Checking ACPI for the existence of a PS/2 keyboard is probably the right thing to do once you have ACPI support, but when you're starting out, either assuming it's there and checking that the responses from the IO ports make sense during initialisation is fine. There are very few x86 "PC" systems that don't at least have an emulated PS/2 controller, I've yet to see a PC that supports BIOS boot without one (unless it's pre ~1998, in which case it might have an AT-style keyboard controller instead, which is basically a "single channel" PS/2 controller with no mouse support).

Even once you have a filesystem API, having a default configuration and layout built-in to the keyboard driver is pretty useful (e.g. if you want to support an "emergency recovery mode" if the normal filesystem isn't available) and a good way to start out.

Personally, with my OS at a very early stage in development, my (current) driver assumes that the keyboard controller is there and pre-initialised (since I boot from GRUB, which uses the keyboard...). Of course, eventually, I'll have something resembling what Brendan suggests, that's certainly not a list of "absolute pre-requisites".

While I've seen some people implement keyboard input at an early stage of development, I didn't bother until I already had quite a lot of the kernel already developed (scheduler, device/driver management, basic read-only in-RAM filesystem, kernel modules (the keyboard driver is one) and some semblance of "userspace"). Basically, it's not really needed until you actually have a use for it (in my case, the userspace "command-shell" application.

Re: input from keyboard

Posted: Fri Aug 29, 2014 3:43 am
by Owen
mallard wrote:The first 7 of those steps are a bit pointless unless you actually have USB HID support. You don't want to disable PS/2 emulation unless you can actually use the keyboard "natively" (i.e. dealing with buggy emulation is better than having no keyboard). I don't think most BIOSs enable emulation unless there's actually a USB HID device connected (although some may enable it if there is only a USB mouse), in which case, there probably isn't a PS/2 keyboard.
The PS/2 emulation is so hopelessly broken on pretty much every motherboard that it's actually pretty essential that you disable it. Its' basically only good enough for DOS and WIndows 95.
mallard wrote:Checking ACPI for the existence of a PS/2 keyboard is probably the right thing to do once you have ACPI support, but when you're starting out, either assuming it's there and checking that the responses from the IO ports make sense during initialisation is fine. There are very few x86 "PC" systems that don't at least have an emulated PS/2 controller, I've yet to see a PC that supports BIOS boot without one (unless it's pre ~1998, in which case it might have an AT-style keyboard controller instead, which is basically a "single channel" PS/2 controller with no mouse support).
Every Mac (which, yes, do support BIOS boot). Worse, you'll crash the system when you try to probe it. Ask ACPI.

I think a lot of the focus on VGA text mode and the keyboard is fundamentally misplaced. Really, until you're in a state to deal with real graphics mode and real drivers, you're far better off using the serial port (plus, then you have a serial port logging system built in for debugging your kernel, which is very useful)

Re: input from keyboard

Posted: Fri Aug 29, 2014 4:48 am
by mallard
Owen wrote: The PS/2 emulation is so hopelessly broken on pretty much every motherboard that it's actually pretty essential that you disable it. Its' basically only good enough for DOS and WIndows 95.
If you disable it, you've got no keyboard/mouse support at all (on USB-based systems), unless you have USB HID support. Please explain how no input is preferable to buggy input. I'm not sure what "modern" OSs do to the PS/2 controller than DOS/Windows 9x didn't. Keyboards haven't changed much since then...
Owen wrote: Every Mac (which, yes, do support BIOS boot). Worse, you'll crash the system when you try to probe it. Ask ACPI.
Or don't try to boot your OS on hardware you know won't work... Why bother trying to run your OS on a Mac if you know you won't be able to use it?

Of course, disabling emulation and probing ACPI is absolutely the best way to do things, once you've got to a stage in development when that's practical, but until then, it's just fine to make assumptions about the hardware/emulator you're testing on.
Owen wrote: I think a lot of the focus on VGA text mode and the keyboard is fundamentally misplaced. Really, until you're in a state to deal with real graphics mode and real drivers, you're far better off using the serial port (plus, then you have a serial port logging system built in for debugging your kernel, which is very useful)
Personally, my OS has a text-mode console and outputs masses of debugging information to the serial port. Debugging information is not part of the "user-interface" and shouldn't be displayed on the "screen" (the thing the "user" interacts with; whether that's text, graphical, serial console, telnet session, etc.). VGA text mode is pretty easy to use and has no real downsides. With a properly-designed infrastructure, you can move off of it as soon as you've got something else. I much prefer the "make it work, then make it good" development strategy to the "don't do anything until you're sure it's going to be perfect" attitude.

Re: input from keyboard

Posted: Fri Aug 29, 2014 5:26 am
by Brendan
Hi,
mallard wrote:Checking ACPI for the existence of a PS/2 keyboard is probably the right thing to do once you have ACPI support, but when you're starting out, either assuming it's there and checking that the responses from the IO ports make sense during initialisation is fine. There are very few x86 "PC" systems that don't at least have an emulated PS/2 controller, I've yet to see a PC that supports BIOS boot without one (unless it's pre ~1998, in which case it might have an AT-style keyboard controller instead, which is basically a "single channel" PS/2 controller with no mouse support).
Checking ACPI for the existence of a PS/2 controller (not a PS/2 keyboard) means checking the value of a flag in a simple table in memory. You don't need full ACPI support (no need for an AML interpreter or anything else complicated).
mallard wrote:While I've seen some people implement keyboard input at an early stage of development, I didn't bother until I already had quite a lot of the kernel already developed (scheduler, device/driver management, basic read-only in-RAM filesystem, kernel modules (the keyboard driver is one) and some semblance of "userspace"). Basically, it's not really needed until you actually have a use for it (in my case, the userspace "command-shell" application.
That is mostly what I'm suggesting in my previous post - it would be foolish to attempt to implement a useful keyboard driver before the things it depends on exist. I just wanted to give Tanzadeh (the OP) a better idea of what sorts of things might be needed beforehand.

Also note that today's shortcuts tend to become tomorrow's "the standard way things are done". If your intent is to develop a robust and well designed system your first steps should be chosen with care. If you begin your journey with a small step into a sewerage pipe it's likely that your final destination will be "drowning in poo" despite subsequent attempts to change course along the way. This is partly because the more code you add onto a bad design the harder it is to change that bad design; and partly because old habits die hard.


Cheers,

Brendan

Re: input from keyboard

Posted: Fri Aug 29, 2014 6:01 am
by mallard
Brendan wrote: the more code you add onto a bad design the harder it is to change that bad design
Exactly, so if you write the minimum possible amount of code to make things work to begin with, you have less to change when you come to make it "better".

Re: input from keyboard

Posted: Fri Aug 29, 2014 6:18 am
by Brendan
Hi,
mallard wrote:
Brendan wrote: the more code you add onto a bad design the harder it is to change that bad design
Exactly, so if you write the minimum possible amount of code to make things work to begin with, you have less to change when you come to make it "better".
Not quite. If you write minimal code that only works sometimes (e.g. on specific hardware) and decide that it's "good enough for now", then later you've got plenty of other things that need work and decide it's still "good enough for now", and after several years there's even more other things that need work and you decide it's still "good enough for now". This continues for several decades, and everyone that tries your OS (include you) know that the OS is a piece of crap and that it's never going to be fixed because there's always other things that need work.

In contrast; if it doesn't work at all you've got much more motivation to actually do something about it. For this reason "doesn't work at all" is significantly better than "good enough for now". Basically; if it's worth doing something, do it properly the first time.


Cheers,

Brendan

Re: input from keyboard

Posted: Fri Aug 29, 2014 6:44 am
by mallard
Brendan wrote: Not quite. If you write minimal code that only works sometimes (e.g. on specific hardware) and decide that it's "good enough for now", then later you've got plenty of other things that need work and decide it's still "good enough for now", and after several years there's even more other things that need work and you decide it's still "good enough for now". This continues for several decades, and everyone that tries your OS (include you) know that the OS is a piece of crap and that it's never going to be fixed because there's always other things that need work.
Firstly, there are very few OS's that have survived "for several decades". None that are common (Mac OS X is probably the oldest, deriving from 1989's NeXTStep, both Windows (NT) and Linux have their origins in the early 1990s). Software develops at such a rate that even things we consider "perfect" now are likely to be less so in several decades.

It's always a balance. There are some things that are "good enough for now", but are definitely not "production ready", while others are "good enough for now" and will be for a good few years/decades (i.e. until something comes along to replace USB or PCI(E) or ACPI or 64-bit addressing isn't enough or some other development that we can't predict). There is really no such thing as code that's "good enough forever". As long as your limitations are properly considered and documented (even if that's just with "//TODO"s) then you're half-way there.

There's also a big difference between what you design and what you implement. Going back to keyboard drivers, mine is designed to support loadable keyboard mappings, unicode characters, etc. but that's not actually implemented yet. Bits of the support code are there (e.g. a "multibyte" flag in the "flags" field, having the keyboard mapping referenced by pointers, etc.), but the actual functionality isn't. It's entirely possible to have a "good" design that only has the bare minimum that makes it work "for now" implemented.
Brendan wrote: In contrast; if it doesn't work at all you've got much more motivation to actually do something about it. For this reason "doesn't work at all" is significantly better than "good enough for now". Basically; if it's worth doing something, do it properly the first time.
Well, if we could always "do it properly the first time" there would be no need for debugging tools! There are, of course, different approaches. I prefer the "agile" type approach of implementing only what's needed, following the "KISS principle", while still keeping the higher-level design open and forward-looking. You seem to prefer the more "engineered" approach, where everything is planned in advance. The approach one takes is more a matter of preference than anything else.

Re: input from keyboard

Posted: Fri Aug 29, 2014 10:13 am
by SpyderTL
Tanzadeh wrote:I write a very small kernel.and how can I get input from keyboard.
Check out the PS2_Keyboard page for details on reading keypress events from the PS/2 keyboard controller.

Basically, you will need to read from IO Port 0x64 and see if bit zero is set.

If it is, you can read one byte from IO Port 0x60 to get the scan code. This code can be used to figure out what key was pressed (or released).

Hope that helps. Let us know if you run into any problems.