Relearning the operating system-15 | Interrupts and interrupt vectors: Why can languages such as Java/js capture keyboard input?

table of Contents

Question 1: What is our goal?

Question 2: How to abstract buttons?

Question 3: How to deal with keystrokes? Use operating system processing or let each program implement it by itself?

Question 4: What model does the program use to respond to keystrokes?

Question 5: When processing user keystrokes, do I need to interrupt the program being executed?

Question 6: How does the operating system know which key the user has pressed?

Question 7: How does the motherboard know that the keyboard is pressed?

Arrangement of Ideas: Interrupted Design

Type of interrupt

Question 1: Why can languages ​​such as Java/Js capture keyboard input?

Question 2: It is understandable that the operating system can handle the keyboard keys, so we can also use the keyboard when we turn on the computer, but the operating system has not been loaded into the memory at that time. How to explain this?

 


Exploration process: how to design the entire link that responds to the keyboard?
When you get a problem, you need to calm down to think and explore solutions. You can check information, watch videos, or consult experts, but before that, you must first think and sort out. Some questions can be answered directly, and some questions need to continue to dig deeper to find the theoretical support behind them.

Question 1: What is our goal?

Our goal is to implement key-press response programs in Java/JS. This implementation is a bit like a Switch-Case statement—different programs are executed according to different keys, such as pressing the Enter key to wrap, and pressing the left and right keys to move the cursor.

Question 2: How to abstract buttons?

Generally, there are no more than 100 keys on the keyboard. So we can consider using a byte of data to describe what key the user presses. The button has two operations, one is to press and the other is to release. These are two different operations. For an 8-bit byte, consider using the most significant 1 to describe the pressed or released state, and then the following 7 bits (0~127) describe which key was pressed. In this way, as long as we determine the order of user keystrokes/releases, there will be no ambiguity for our system.

Question 3: How to deal with keystrokes? Use operating system processing or let each program implement it by itself?

Processing keys is a general program, and you can consider part of the processing first by the operating system, such as:

When the user presses the Enter key, the operating system first performs a unified package, and then converts the code of the key to the string Enter to facilitate the use of various programs.

It is better for the operating system to perform the calculation first to process the operation of the combination key. Because the bottom layer only knows the key and release, the combination key must be judged by the time factor.

You can think of the following situation as a Ctrl + C key combination. This behavior can be handled uniformly by the operating system, as shown below:

按下 Ctrl
按下 C
释放 Ctrl
释放 C

Question 4: What model does the program use to respond to keystrokes?

When an application written in Java or JS wants to respond to key presses, the message model should be considered. Because if the program keeps scanning the keys, it will bring a great burden to the entire system. For example, if the program writes a while loop to scan for keystrokes, it will cost a lot. If the program registers a function that responds to keystrokes on the operating system, this function is executed only when the keystrokes are actually triggered, so that overhead can be reduced.

Question 5: When processing user keystrokes, do I need to interrupt the program being executed?

In terms of user experience, keypressing should be a high-priority operation. For example, when the user presses Ctrl+C or Esc, it may be because the user wants to interrupt the currently executing program. Even if the user only wants to input, we should concentrate resources to the user as much as possible, because we don't want the user to feel the delay.

If you need to consider that the program will be interrupted at any time to respond to other higher priority situations, then this behavior should be supported from the bottom of the program execution, and it is best to support it from the hardware level, which is the fastest. This leads to the protagonist of this lesson-interruption. For details on how to deal with it, see our analysis on the interrupt part below.

Question 6: How does the operating system know which key the user has pressed?

There is a similar question to question 5. Does the operating system continuously trigger the reading of keyboard keys, or does it trigger a program belonging to the operating system every time a keyboard key comes?

Obviously, the latter is more efficient.

So who can interrupt the operating system program anytime and anywhere? Who has this authority? Is it an administrator account? Of course not, the machine itself should have such a high level of authority.

Let's think about this model. Every time the user presses a key, a CPU's ability is triggered. This ability will interrupt the program being executed to process the button. Should there be a program for processing buttons inside the CPU? This will definitely not work, because we hope that the CPU is used for calculations. If the CPU has its own program, it will complicate the problem. This is called coupling in software design. The job of the CPU is to concentrate on executing instructions efficiently.

Therefore, every time a key is pressed, there must be a mechanism to notify the CPU. We can consider using the bus to notify the CPU, that is, the motherboard is notifying the CPU.

So how does the CPU notify the operating system after receiving the notification? The CPU can only interrupt the program being executed and then switch to another program that needs to be executed. To put it bluntly, it is to change the PC pointer. The CPU has only one way to switch the executed program. Here I would like to ask you to think, is there only one way: CPU interrupts the currently executing program and then executes another program to change the PC pointer?

Next, let's think further, how does the CPU know how much the PC pointer should be set to? Does the CPU know the location of the program in which the operating system responds to keystrokes?

The answer is of course not knowing.

Therefore, we can only control the CPU to jump to a fixed position. For example, as soon as the CPU receives information from the motherboard (a key is triggered), the CPU immediately interrupts the currently executing program and sets the PC pointer to 0. That is, the PC pointer will read the next instruction from memory address 0 in the next step. Of course, this is just one of our thoughts, and further consideration is needed. What the operating system has to do is to write an instruction in the memory address 0, for example, let the PC pointer jump to the position where it processes the key program.

Having said that, let’s summarize, what the CPU has to do is to change the PC pointer (equivalent to interrupt the program being executed) as soon as it sees the interrupt, and how much the PC changes to can be judged according to different types, such as pressing a button. 0. The operating system will write instructions to these specific locations, and when an interrupt occurs, it will take over the control of the program, that is, let the PC pointer point to the program that the operating system handles the keystrokes.

Question 7: How does the motherboard know that the keyboard is pressed?

After digging layer by layer, "How to design the entire link that responds to the keyboard?" The current operating system has been able to take over the buttons. Next, we need to think about how the motherboard knows that there are buttons and informs the CPU.

You can think of a keyboard key as pressing a certain switch, and we need a chip to convert the key information into the value of a specific key. For example, when the user presses the A key, which row and column A key is on, it can be regarded as an electrical signal. Then we need the chip to convert this electrical signal into a specific number (a Byte). After the conversion is completed, the motherboard can receive this number (key code), then write the number into one of its own registers, and notify the CPU.

In order to facilitate the CPU calculation, after the CPU receives the notification from the motherboard, the key code will be stored in a register, which facilitates the execution of the key-press program.

Arrangement of Ideas: Interrupted Design

The overall design is divided into 3 layers, the first layer is the hardware design, the second layer is the operating system design, and the third layer is the programming language design.

The collection of key codes is the ability of the keyboard chip and the motherboard. After the motherboard knows that there is a new button, it informs the CPU that the CPU will interrupt the currently executing program and jump the PC pointer to a fixed position, which we call an interrupt.

Considering that there will be various events in the system, we need to determine the location of the PC pointer jump according to the interrupt type. The location of the PC pointer jump may be different depending on the interrupt type. For example, key programs, printer ready programs, system exceptions, etc. all need to be interrupted. For example, system calls also need to interrupt the program being executed and switch to the kernel mode to execute the kernel program.

Therefore, we need to classify the different types of interrupts. This type is called the interrupt identifier . For example, for a button, we can consider using the number 16. The number 16 is the identification code of the interrupt type of the button. When different types of interrupts occur, the CPU needs to know which address the PC pointer should jump to. This address is called the Interupt Vector .

You can consider such an implementation: when the interrupt number 16 occurs, the PC pointer of the 32-bit machine jumps directly to the memory location of memory address 16*4. If the design has a maximum of 255 interrupts, the number is from 0 to 255, just 1K memory address is needed to store the interrupt vector-this 1K space is called the interrupt vector table.

32 bits are exactly 4 bytes, which means that 255 4 bytes can store the entire vector table.

Therefore, after the CPU receives the interrupt, the CPU operates the PC pointer according to the interrupt type to find the interrupt vector. The operating system must modify the interrupt vector and insert an instruction before that. For example, the operating system writes a Jump instruction here to jump the PC pointer to the program that handles the corresponding interrupt type.

After the operating system takes over, taking the key-press program as an example, the operating system will perform some processing, including the following things:

Put the button in a queue and save it. This is because the operating system cannot guarantee to process all the keys in a timely manner. For example, when the keys are too fast, they need to be stored first, and then processed slowly in time-sharing.

Calculate the key combination. You can use the time relationship between pressing and releasing.

After a certain calculation, the button is abstracted into a message (event structure or object).

Provide API to the application, so that the application can monitor the messages processed by the operating system.

Distribute keypress messages to programs that monitor keypresses.

So the program is at the language level, such as languages ​​with virtual machines like Java/Node.js, only need to interface with the operating system API.

Type of interrupt

According to the triggering party of the interrupt, it is divided into synchronous interrupt and asynchronous interrupt ;

According to whether the interrupt is forced to trigger, it is divided into maskable interrupt and non-maskable interrupt .

Interrupts can be directly triggered by CPU instructions. Such actively triggered interrupts are called synchronous interrupts . There are several cases of synchronous interruption.

  1. The system call needs to switch from the user mode to the kernel mode. In this case, the program needs to trigger an interrupt, called a trap. After the interrupt is triggered, the system call needs to be continued.
  2. There is also a synchronization interruption is wrong (Fault), usually because of some error is detected, it is necessary to trigger an interrupt, the interrupt after the response will be re-run place that triggered the error, such as missing pages interrupt pagefault .
  3. Program exceptions, this situation is similar to Trap, used to implement exceptions thrown by the program.

Another part of the interrupt is not directly triggered by the CPU, because it needs to respond to external notifications, such as interrupts triggered by devices such as keyboards and mice. This kind of interrupt is called asynchronous interrupt.

The CPU usually supports setting an interrupt mask bit (a register). After setting it to 1, the CPU will no longer respond to interrupts temporarily . For keyboard and mouse input, such as traps, errors, exceptions, etc., will be temporarily shielded. But for some particularly important interrupts, such as power-down interrupts caused by CPU failures, they will still be triggered normally. The interrupts that can be masked are called maskable interrupts, and most interrupts are maskable interrupts.

This can also explain why some programs cannot be terminated by ctrl + c.

Question 1: Why can languages ​​such as Java/Js capture keyboard input?

In order to capture keyboard input, the hardware layer needs to abstract the keys into interrupts and interrupt the CPU execution. The CPU finds the corresponding interrupt vector according to the interrupt type. The operating system presets the interrupt vector, so the operating system takes over the program after an interrupt occurs. The operating system implements a basic algorithm for analyzing keystrokes, abstracts keystrokes into keyboard events, provides a queue to store multiple keys, and also provides an API to monitor keystrokes. Therefore, applications, such as the Java/Node.js virtual machine, can use keyboard events by calling the operating system's API.

Question 2: It is understandable that the operating system can handle the keyboard keys, so we can also use the keyboard when we turn on the computer, but the operating system has not been loaded into the memory at that time. How to explain this?

There is often a simplified version of the operating system on a ROM of the motherboard, called BIOS (Basic Input/Ouput System). Before the OS takes over the computer, the BIOS manages the machine and assists in loading the OS into the memory. The early OS also used the capabilities of the BIOS. After modern OS took over, it would replace the BIOS interrupt vector.

 

 

Guess you like

Origin blog.csdn.net/MyySophia/article/details/114044259