Hi all. I've been following the tutorials and wiki on this site for a little while (it's a truly *FANTASTIC* resource, by the way!). I've put a kernel structure together and got as far as getting keyboard interrupts working and being sent to the ISR (yeay! ), and I've set up a few other experimental kernel routines on hotkeys to make them easy to test. It also prints out the scancode of each key and whether it was a press or release to the screen.
Then I set about mapping the scancodes to key names -- so it can also tell me a textual name of each key. I mapped every key for the four keyboards I have here and made separate keymaps for US and UK keyboards. It seems to work really well.
But then I did a bit of web searching to see if the special keys on some keyboards (e.g., Sleep, Wake up, Play/Pause, Mute, Vol up/down, Internet, etc.) had standard codes, and I came across *this* page: http://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html. If I've understood this right, there are three scancode sets, and sets 1 and 3 are sometimes buggy.
To my horror, my keymaps seem to be set 1. But they also seem to be the same as the "X (Set 2)" column in that table, and I don't know what that is. Now I'm just really confused. Can anyone tell me, for best compatibility should I switch the keyboard to another set and redo the maps? Is there a set which is always supported by keyboards or do I need to write code to handle all of them?
Is it also a good idea to set up an enum of virtual key constants so I can refer to them in the rest of the OS instead of hardware-locked scancodes? I reckon that's what I should do next, but I'd like to hear advice from the more experienced first.
(Honestly, I never realized keyboards were so complicated!)
Keyboard scancode sets?
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
I had a quick look at http://www.win.tue.nl/~aeb/linux/kbd/scancodes-6.html (you have probably seen that on too) and I noticed that many of the keys with the same function are mapped to different scancodes.
Which suggests that in the end, you'll need maps for each keyboard layout to have every keyboard work as expected.
Which suggests that in the end, you'll need maps for each keyboard layout to have every keyboard work as expected.
Hi. Thanks yeah, although I'm not too worried about the multimedia / extra keys at the moment, because although they don't have standard codes, none of them conflict with the standard 105 keys. (If they have the certification for the Windows key, the Microsoft spec places restrictions on which keycodes they can use for extra keys.) This means I can, theoretically, implement them as a set of extra maps later, with lots of nulls in place for all the standard keys. (Lots of nulls == simple == good!)
But what's really confusing me is what's the difference between Scancode Set 1, Scancode Set 2, and Scancode "X (Set 2)" ....
Originally, set 1 was used on the XT. Now that page I linked to says, (and I quote) : Sets 2 and 3 are designed to be translated by the 8042. And the Microsoft specs require keyboards to output set 2 scancodes. I'm just really confused as to why. Why was a different set of scancodes introduced, just so that a chip could turn them back into set 1?
There's plenty of stuff on the Internet about how the scancodes are translated, without explanation as to what this achieves. I can't possibly be the first person to wonder this, since it totally changes every key. And set 1 seems to be some kind of default (?), even though it doesn't work properly, apparently. So I still don't know what mode to use
But what's really confusing me is what's the difference between Scancode Set 1, Scancode Set 2, and Scancode "X (Set 2)" ....
Originally, set 1 was used on the XT. Now that page I linked to says, (and I quote) : Sets 2 and 3 are designed to be translated by the 8042. And the Microsoft specs require keyboards to output set 2 scancodes. I'm just really confused as to why. Why was a different set of scancodes introduced, just so that a chip could turn them back into set 1?
There's plenty of stuff on the Internet about how the scancodes are translated, without explanation as to what this achieves. I can't possibly be the first person to wonder this, since it totally changes every key. And set 1 seems to be some kind of default (?), even though it doesn't work properly, apparently. So I still don't know what mode to use
Set 1 works pretty well. There may be a few tiny issues with very non-standard key combinations (Alt-PrtSc). It is the scanset that the BIOS and DOS use. So it is almost completely standardized. It cannot be too buggy, or the BIOS and DOS would not work (which would be heresy).
Scanset 2 is supposed to be "better" than Scanset 1. After several years of implementing Scanset 1, engineers thought that the scanset could have been designed better to begin with, so that it could be translated/interpreted more easily by a keyboard driver. So they took a whack at making a better one. But it still had to support the BIOS/DOS. So it had to always boot in "Scanset1 compatibility mode", so to speak. This is what "X (set 2)" is on your list. And yes, the whole point is that it is identical to Scanset 1. All modern computers boot in this mode -- scanset 2 with the internal translation to scanset 1 turned on.
So, during a boot, you might try switching the scanset from "translated scanset 2" (= scanset 1) into real scanset 2, in order to use this "better" scanset. Except there is a problem. AFAIK, most (all?) laptops will not let you turn off the translation. Which is why I personally recommend just sticking with the translated scanset 2 (= scanset 1) that you get for free during the boot process as default. It's really not that hard to decode into a keydown/keyup.
Scanset 2 is supposed to be "better" than Scanset 1. After several years of implementing Scanset 1, engineers thought that the scanset could have been designed better to begin with, so that it could be translated/interpreted more easily by a keyboard driver. So they took a whack at making a better one. But it still had to support the BIOS/DOS. So it had to always boot in "Scanset1 compatibility mode", so to speak. This is what "X (set 2)" is on your list. And yes, the whole point is that it is identical to Scanset 1. All modern computers boot in this mode -- scanset 2 with the internal translation to scanset 1 turned on.
So, during a boot, you might try switching the scanset from "translated scanset 2" (= scanset 1) into real scanset 2, in order to use this "better" scanset. Except there is a problem. AFAIK, most (all?) laptops will not let you turn off the translation. Which is why I personally recommend just sticking with the translated scanset 2 (= scanset 1) that you get for free during the boot process as default. It's really not that hard to decode into a keydown/keyup.
Brilliant! Thank you very much! I've got a basic plan now for how this driver is going to work:
1. PS/2 Keyboard driver can use the "set 2 translated to set 1" scancodes.
2. It translates the scancodes into a set of hardware-independent virtual key constants.
3. Sends these virtual key constants plus some flags info (shift, ctrl, alt, super, num lock, caps lock, scroll lock, pressed/repeat/released) to the *generic* part of the keyboard manager, so it's no longer tied to just PS/2.
4. Generic keyboard manager calls the keyboard layout manager (which I've already got written and working for US and UK keyboards) to translate the virtual key codes + flags into printable characters and/or get the key name.
5. Generic keyboard manager presumably sticks these into a buffer then, so they can be accessed by a getchar() thing, and then I'll have keyboard input!
OS dev is much better when you have a plan
1. PS/2 Keyboard driver can use the "set 2 translated to set 1" scancodes.
2. It translates the scancodes into a set of hardware-independent virtual key constants.
3. Sends these virtual key constants plus some flags info (shift, ctrl, alt, super, num lock, caps lock, scroll lock, pressed/repeat/released) to the *generic* part of the keyboard manager, so it's no longer tied to just PS/2.
4. Generic keyboard manager calls the keyboard layout manager (which I've already got written and working for US and UK keyboards) to translate the virtual key codes + flags into printable characters and/or get the key name.
5. Generic keyboard manager presumably sticks these into a buffer then, so they can be accessed by a getchar() thing, and then I'll have keyboard input!
OS dev is much better when you have a plan
Re: Keyboard scancode sets?
It is not so complicated.
http://www.henkessoft.de/OS_Dev/OS_Dev1 ... ocId185043
http://www.henkessoft.de/OS_Dev/Downloads/13%20C.zip
http://www.henkessoft.de/OS_Dev/OS_Dev1 ... ocId185043
http://www.henkessoft.de/OS_Dev/Downloads/13%20C.zip
http://www.henkessoft.de/OS_Dev/OS_Dev3.htm (OSDEV)
http://www.c-plusplus.de/forum/viewforu ... is-62.html
irc.euirc.net #PrettyOS
http://www.c-plusplus.de/forum/viewforu ... is-62.html
irc.euirc.net #PrettyOS
Re: Keyboard scancode sets?
Hi,
For the table you're looking at:
For old computers (e.g. IBM XT), the keyboard sent scancode set 1 and there was no translation. The current scheme (scancode set 2 with translation) was invented for backward compatibility - so that old software still saw the same codes from the PS/2 controller.
If you plug a keyboard into the mouse port it works perfectly (the only problem here is that the PS/2 controller doesn't support translation for the second PS/2 port). If you plug a mouse into the first PS/2 port then it'll work perfectly too (but you must disable the scancode translation). It's also possible to detect if the device is a keyboard or a mouse. If you combine all of this, you'll see it's possible to have 2 PS/2 keyboards at the same time, or 2 PS/2 mouses at the same time, or a keyboard and mouse in the "wrong" PS/2 ports, and for the OS to automatically detect what is plugged in where and work perfectly in any case (regardless of which PS/2 devices are plugged into which PS/2 ports, if any). Of course it probably doesn't work reliably for USB devices that are being used to emulate PS/2 devices (because the BIOS/SMM emulation code is typically crappy) but you'd (eventually) want to use USB drivers instead and disable the PS/2 emulation; and the BIOS doesn't like some combinations (because it assumes that the device in the first PS/2 port is a keyboard). You'd also need to have some code to detect the PS/2 controller type - some old PS/2 controllers (mostly in 80486 and older computers) only support one PS/2 port, which complicates device detection code a little (you get strange results when you try to detect what device is connected to the second PS/2 port when the second PS/2 port doesn't exist); and some emulators might have problems if you try to disable translation (I know Bochs used to - not sure if it's changed).
Cheers,
Brendan
Normally, the keyboard itself is set to "scancode set 2" and the PS/2 controller converts from "scancode set 2" to "scancode set 1".midir wrote:If I've understood this right, there are three scancode sets, and sets 1 and 3 are sometimes buggy.
To my horror, my keymaps seem to be set 1. But they also seem to be the same as the "X (Set 2)" column in that table, and I don't know what that is. Now I'm just really confused. Can anyone tell me, for best compatibility should I switch the keyboard to another set and redo the maps? Is there a set which is always supported by keyboards or do I need to write code to handle all of them?
For the table you're looking at:
- "Set 1" means the keyboard sends scancode set 1, and translation in the PS/2 controller is disabled, so you see scancode set 1
- "X(Set 1)" means the keyboard sends scancode set 1, and translation in the PS/2 controller is enabled, so you see a strange mess.
- "Set 2" means the keyboard sends scancode set 2, and translation in the PS/2 controller is disabled, so you see scancode set 2
- "X(Set 2)" means the keyboard sends scancode set 2, and translation in the PS/2 controller is enabled, so you see scancode set 1 (note: default behavior)
- "Set 3" means the keyboard sends scancode set 3, and translation in the PS/2 controller is disabled, so you see scancode set 3
- "X(Set 3)" means the keyboard sends scancode set 3, and translation in the PS/2 controller is enabled, so you see a strange mess.
For old computers (e.g. IBM XT), the keyboard sent scancode set 1 and there was no translation. The current scheme (scancode set 2 with translation) was invented for backward compatibility - so that old software still saw the same codes from the PS/2 controller.
If you plug a keyboard into the mouse port it works perfectly (the only problem here is that the PS/2 controller doesn't support translation for the second PS/2 port). If you plug a mouse into the first PS/2 port then it'll work perfectly too (but you must disable the scancode translation). It's also possible to detect if the device is a keyboard or a mouse. If you combine all of this, you'll see it's possible to have 2 PS/2 keyboards at the same time, or 2 PS/2 mouses at the same time, or a keyboard and mouse in the "wrong" PS/2 ports, and for the OS to automatically detect what is plugged in where and work perfectly in any case (regardless of which PS/2 devices are plugged into which PS/2 ports, if any). Of course it probably doesn't work reliably for USB devices that are being used to emulate PS/2 devices (because the BIOS/SMM emulation code is typically crappy) but you'd (eventually) want to use USB drivers instead and disable the PS/2 emulation; and the BIOS doesn't like some combinations (because it assumes that the device in the first PS/2 port is a keyboard). You'd also need to have some code to detect the PS/2 controller type - some old PS/2 controllers (mostly in 80486 and older computers) only support one PS/2 port, which complicates device detection code a little (you get strange results when you try to detect what device is connected to the second PS/2 port when the second PS/2 port doesn't exist); and some emulators might have problems if you try to disable translation (I know Bochs used to - not sure if it's changed).
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: Keyboard scancode sets?
We should have a new rule of thumb: if ehenkes is replying to a thread, check the original thread's date! Zombie revival alert!Brendan wrote:Hi
JAL