Keyboard, we do computer this line of nature need not say more, every day with it. But familiar, know the principle behind the keyboard? Keyboards are marked with the name of each key, indicating what it means, but how does the computer know? How are key combinations implemented? How do you press a character key to turn it into ordinary ASCII code? By the end of this article, you’ll be able to understand the nature of the keyboard and know the answers to these questions.
- Public id: Rand_cs
I. Relevant introduction
Keyboard encoder
Keyboard encoder (I8048), is the chip in the keyboard, mainly used to monitor whether there is a key pressed, played, and then report to the keyboard controller the key related information. The keyboard encoder acts like the keyboard’s mouth, allowing the keyboard to speak and express the current state of the key. It also controls the switch of Num Lock and Caps Lock LED lights.
Keyboard scan code
The information mentioned above is the keyboard scan code. If a key is pressed, it will be bounced, so each key will have two states, that is, each key will correspond to two scan codes. The code when the key is pressed is called makecode, and the code when the key is bounced is called breakcode.
The on and off codes of most keys are 8 bits and 1 byte, but some control keys such as CTRL and Alt, additional keys such as Insert, keypad areas such as /, and arrow keys are 2 or more bytes. There are multiple bytes of scan code beginning with 0xe0. Only a Pause Break key begins with 0xE1.
Relationship between broken code and Pass code: Broken code = Pass code + 0x80. 0x80 binary represents 1000 0000, so the break and Pass codes can be understood as consisting of 8 bits, with the highest bit 7 indicating the key state, 1 indicating down, and 0 indicating up.
Note: The above is the case of the first set of keyboard scan codes, the current keyboard basically uses the second set of keyboard scan codes, but for compatibility, the second set of scan codes will eventually be converted to the first set of scan codes, which is also a part of the work of the keyboard controller.
Keyboard controller
The keyboard controller (I8042), which is not inside the keyboard, is integrated on the Southbridge chip. It mainly receives the scan code from the keyboard encoder (the second set), decodes (into the first set) and saves it in its register, and then sends the interrupt request through the interrupt controller.
I8042 has 4 registers, as shown below:
The input buffer and output buffer share a 0x60 port, and the state controller and control register share a 0x64 port.
Does sharing not conflict? Note the different read/write states. When the CPU reads data from 8042 using the INT instruction, 0x60 represents the output buffer. When the CPU writes data to 8042 using the out instruction, 0x60 represents the input buffer.
Note: Input/output depends on the object, for the keyboard controller is output, then for the CPU is input, use the IN instruction.
Each register is 8-bit, and a maximum of 8-bit, 1-byte scan codes can be saved, and the keyboard interrupt service program can process only 1-byte scan codes at a time. That is to say, the number of keyboard breaks is not the number of times you press and bounce, but the number of bytes of key and bounce corresponding to the pass code and break code (the first set). You can see that there are countless interruptions when we type.
Isn’t the keystroke information multiple bytes of scan code? Yes, but the hardware environment is so, can not change, can only work on the software, this is the next to say the keyboard interrupt procedure, first look at the flow of keyboard interrupt, good have a clear route.
Second, keyboard interrupt process
In fact, the above related introduction has involved part of the keyboard interrupt process, in this specific from beginning to end, first look at the flow chart:
-
Keyboard encoder monitors whether there is a key pressed or unpressed, if there is a key pressed, send the key code to the keyboard controller; If there is a key up, then send break code (basically send a second set of keyboard scan code).
-
The keyboard controller receives the scan code from the keyboard encoder, decodes it into the first scan code, saves it in its own output buffer, and then sends the keyboard interrupt signal to the CPU through the interrupt controller.
-
The following process is basically the same as the interrupt process mentioned above, which is briefly described here: the CPU responds when the interrupt is not closed, the interrupt controller sends the interrupt vector number through the data line, and the CPU locates the interrupt service program according to the vector number, checks the privilege level automatic stack during the process, and then runs the interrupt service program to deal with the interrupt.
Three, the keyboard interrupt service program
Keyboard interrupts are second in priority to clock interrupts among all maskable interrupts and need to be handled as quickly as possible. The entire keyboard server program in Linux 0.11 is written in assembly, which operates directly on the underlying instructions without a compiler to add extra stuff, so it runs faster than programs written in high-level languages, but it also makes it harder to write programs.
Linux0.11 version of the keyboard interrupt service framework source code as shown below:
The framework does the following:
Protect the site – stack
In the above article, we wrote to push ss, ESP, eflags, cs, eIP, error_code (if there is a privilege change and the interrupt has an error code) to save the scene, that is only the automatic part of the CPU, completely save the original task information is still in the interrupt handler.
As shown in the figure above, the keyboard interrupt service program in the general purpose register only saved 4, eAX, EBX, ECX, EDX, if to save trouble and not the pursuit of efficiency can be no brain operation pushad stack all the general purpose registers, but it is a Linux system, although only 0.11 version, but also to pursue precision, efficiency, A register that is needed by the pushonly interrupt program and may be destroyed.
Read scan code
Inb $0x60, AL reads the scan code from port 0x60 of the output cache of the keyboard controller. The keyboard controller will not continue to work without reading data from the output buffer, meaning that no matter how you press the keyboard, the keyboard controller will not respond to keyboard actions, will not save new scan code to send interrupt signals, etc. Of course, the subsequent keyboard interrupt program will not work without reading the scan code, which makes no sense.
Check whether the value is 0xe0 or 0xE1
If the scan code is 0xe0 or 0xE1, it indicates that the scan code of this key has multiple bytes. You need to save the scan code and wait for the next scan code to combine into a complete scan code.
Addresses and invokes the corresponding key handler
After getting the complete scan code, it is time to look for the corresponding key handler. There is a key_table in the source code, table, indicating that it is a table, or an array, which stores the actual handler address of each key according to the scan code size.
How do I find the corresponding key handler? In fact, it is the same as an array using the following table to obtain elements, but there are some big sounding nouns in the assembly: according to the source code using proportional indexing method, that is, key_table(, %eax, 4), that is, the corresponding key handler address is key_table + eax * 4. Key_table, equivalent to the first address of the array; Eax store scan code, scan code can be regarded as a numeric index number, equivalent to the array subscript; Address 32 bits, 4 bytes, so times 4.
Restore scene – out of stack
The reverse process of the stack protection site will not be described here. Note that the top of the stack when iRET is executed should be EIP.
Four, the key handler
Key scan code has pass code and break code, and has different processing. The main key handlers I divide into the following categories (the names at the beginning of each dot are the actual key handler function names in Linux0.11) :
-
Control key processing procedures such as CTRL, Alt, CAPS, Shift, NUM, the whole keyboard interrupt program maintains two 8-bit variables mode and leds. Each of these bits (unused) represents a key, with a 1 for down and a 0 for up. The mode keys include CAPS, Alt, CTRL, and Shift. Leds represent keys such as NumLock, CapsLock and ScrollLock. So the key handler that operates on the control key sets the corresponding bit of the variable.
-
Do_self, a program that handles normal keys, basically converts scan codes into ASCII codes and puts them in the keyboard buffer. The keyboard interrupter maintains a scanning-to-ASCII mapping table called key_map, which do_self uses to convert.
-
Func, processing function keys such as Fxx key procedures
-
Cursor, set the position of the cursor, it is to handle the direction key, PgUp, Backsp, etc
-
Unctrl, unshift, etc., reset the mode and leds. For example, unctrl changes the CTRL position in mode to 0.
-
None does nothing except the key handler corresponding to the break code for a particular key, and returns it directly. And the special key break code handler is the above 5, reset on the line.
From the above, we can also know several problems that may become a habit but have not paid attention to in detail:
-
To use the combination key, press the control key first. These control keys are identified (mode/leds) by the keyboard interrupt program. Press the control key first, the program sets the press state for the control key, and then processes the incoming key to check whether there is a control key to press, so as to make a different operation.
-
The combination keys are pressed in order, but there is no order requirement when they are played. As can be seen from the above key handler, only the passcode key handler is working, while the broken key handler is directly interrupted except for special keys that need to be reset. So when you use the keyboard to control input, the key is important, not the key up, so as long as the key is right, how to play is not important.
-
Holding down a key consistently triggers a keyboard interrupt. With a regular character key, the computer screen may print a character all the time. If there are some control keys, the interrupt program may keep setting the key to the pressed state. Of course, whether the keyboard interrupt program records the last key depends on the implementation, most are not recorded, triggering a keyboard interrupt to process a scan code.
That’s how the keyboard controls input, so this line should be pretty clear. Keyboard input is centered around keyboard interrupts. If that’s not clear, look back at the flow chart of keyboard interrupts. Well, this article is over here, if there is any error also please criticize and correct. If it helps, please pay more attention to support.
If you like this article, please click “like” to support it, and also welcome to pay attention to the public number Rand_cs to learn and progress together.