Original link: https://www.luozhiyun.com/archives/705
Please declare the source for reprinting~, this article was published on luozhiyun’s blog: https://www.luozhiyun.com/archives/705
Interrupts and exceptions can be attributed to an event processing mechanism. A signal is sent through an interrupt or an exception, and then the operating system will interrupt the current operation, and then find the corresponding handler to handle the interrupt or exception according to the signal, and then process the interrupt or exception according to the signal. Whether the result is to return to the original program and then proceed to the next execution.
Different books seem to have different definitions for exceptions and interrupts, but they are actually the same thing. I use the definition in the book “intel architectures software developer’s manual” here:
- An interrupt is an asynchronous event that is typically triggered by an I/O device.
- An exception is a synchronous event that is generated when the processor detects one or more predefined conditions while executing an instruction. The IA-32 architecture specifies three classes of exceptions: faults, traps, and aborts.
We can roughly understand an interrupt as an asynchronous event triggered by an I/O device, such as a user’s keyboard input. It is an electrical signal that is generated by a hardware device and then passed to the CPU through the interrupt controller. The CPU has two special pins, NMI and INTR, which are responsible for receiving interrupt signals.
An exception is a synchronous event, usually caused by a program error, or by an exceptional condition that the kernel must handle, such as a page fault or syscall. Exceptions can be divided into errors, traps, and terminations.
The synchronization mentioned above is because the CPU will only issue an interrupt after an instruction is executed, not during the execution of a code instruction, such as a system call; asynchronous means that interrupts can occur between instructions.
When an exception or interrupt occurs, the processor stops executing the current program or task and executes the program dedicated to handling the interrupt or exception. The processor will obtain the corresponding processing program from the Interrupt Descriptor Table (IDT). When the exception or interrupt is executed, it will continue to return to the interrupted program or task to continue execution.
In Linux, an interrupt handler is a C function, except that these functions must be declared with a specific type so that the kernel can pass information about the handler in a standard way. Interrupt handlers run in the interrupt context (interrput context), the execution code in the context is not blocking.
In the x86 system, 256 kinds of exceptions (interrupt vectors) are set in the IDT in advance. The numbers from 0 to 31 correspond to the exceptions specified by Intel, and the numbers from 32 to 255 correspond to the exceptions defined by the operating system:
Vector | Mnemonic | Description | Source |
---|---|---|---|
0 | #DE | Divide Error | DIV and IDIV instructions. |
13 | #GP | General Protection | Any memory reference and other protection checks. |
14 | #PF | Page Fault | Any memory reference. |
18 | #MC | Machine Check | Error codes (if any) and source are model dependent. |
32-255 | Maskable Interrupts | External interrupt from INTR pin or INT n instruction. |
The above table can be found in “intel architectures software developer’s manual”. I listed some common exceptions above, such as division by zero, general protection exception, page missing, machine check, etc.
Let’s look at several high-level exceptions and interrupts: system calls, context switches, signals, etc.
system call system call
For the operating system, 4 priority levels are set:
0 provides direct access to all hardware resources. Limited to the lowest level of operating system functions such as BIOS, memory management;
1 Access to hardware resources is subject to some restrictions. May be used by library routines and software that controls I/O devices;
2 Access to hardware resources is more restricted. May be used by library programs and software that control I/O devices;
3 No direct access to hardware resources. The application runs at this level;
Due to the security and stability of the system, user space cannot directly execute system calls and needs to switch to kernel mode for execution. Therefore, the application will trigger an exception through the int $n
instruction. n represents the exception number in the IDT table mentioned above. The old version of the Linux kernel uses the int $0x80
instruction. After the exception is triggered, the system will switch to the kernel state and execute the corresponding exception handler.
On Linux, each system call is assigned a system call number, and the kernel records a list of all registered system calls in the system call table and stores it in sys_call_table. Because all system calls trap into the kernel in the same way, the system call number is passed to the kernel through the eax register. Before getting into the kernel, the user space puts the number corresponding to the corresponding system call into eax.
So the system call execution flow is as follows:
-
The application code calls the system call ( read ), which is a library function that wraps the system call;
-
The library function ( read ) is responsible for preparing the parameters passed to the kernel and triggering an abort to switch to the kernel;
-
After the CPU is interrupted by the interrupt, the interrupt handler is executed, that is, the system call handler ( system_call );
-
The system call processing function calls the system call service routine ( sys_read ) to actually start processing the system call;
context switch context switch
Context switching is a higher-level form of abnormal control flow through which the operating system multitasks. That is, context switching is actually built on top of the lower exception mechanism.
The kernel controls whether the current process can be preempted through the scheduler. If it is preempted, the kernel will select a new process to run, save the context of the old process, restore the context of the new process, and then transfer control to the new process. process, this is context switching.
When a system call is executed, context switching may occur. For example, if a process is blocked due to the read system call accessing the disk, the current process can be hibernated and switched to another process; context switching may also occur in interrupts, such as periodic internal system calls. When the timer is interrupted, the kernel thinks the current process has been running long enough and switches to a new process.
Process switching only occurs in kernel mode. Before performing process switching, all register contents used by user mode processes have been saved on the kernel mode stack.
The figure above shows an example of switching between A and B processes. Process A is initially in user mode until it enters the kernel by executing the system call read. Since it takes a certain time to read data from the disk, the kernel performs the switch from process A to B. Then after the disk data is ready, the disk controller will issue an interrupt signal, indicating that the data has been transferred from the disk to the memory, then the kernel will switch from kernel B to A, and then execute the instruction in process A immediately after the system call read .
Signal
A signal is a software form of exception that allows processes and the kernel to interrupt other processes to notify the process that an event of some type has occurred in the system. Each signal type corresponds to a certain system event. Low-level hardware exceptions are handled by kernel exception handlers, which are normally invisible to user processes. But the signal can notify the user process that an exception has occurred. If the process tries to divide by 0, the kernel will send it a SIGFPE signal; if the process executes an illegal instruction, the kernel will send a SIGILL signal and so on.
Signaling consists of two steps, sending a signal and receiving a signal.
A signal that is sent but not accepted is called a pending signal. A type can only have at most one pending signal, if a process has a pending signal of type k, then the next signal sent to this process of type k will only be discarded.
A process can also block to receive some kind of signal. When a signal is blocked, it can still be sent, but not received, until the process unblocks the signal.
The kernel maintains the pending signal set in the pending bit vector and the blocked signal set in the blocked bit vector for each process.
When a process switches from kernel mode to user mode, it checks the set of unblocked pending signals in the process (pending & ~blocked), if this set is empty, then the kernel passes control to the next instruction of the process (I_next) ; If it is non-empty, then the kernel selects a signal k (usually the smallest k) in the set to force the process to receive, and then the process will trigger a certain behavior according to the signal, and after completion, it will return to the control flow to execute the next instruction (I_next) .
As shown above, signal handlers can be interrupted by other signal handlers.
Summarize
This article mainly introduces how to control program execution through exceptions and interrupts in computer systems. Abnormal control flow occurs at all levels of computer systems and is the basic mechanism for providing concurrency in computer systems. At the low-level hardware layer, exceptions are handled by sending signals to the processor through the exception controller, so as to quickly respond to I/O events; at the operating system level, the program is trapped in the kernel state through exceptions, and then System call; interrupts can also interrupt the current process execution process, thereby realizing the switching between processes, which is also the basic mechanism for providing concurrency in computer systems; through signals, processes and the kernel can also be interrupted by other processes, so as to realize the process of control between.
Reference
“In-depth understanding of the Linux kernel”
“In-depth understanding of computer principles”
https://bob.cs.sonoma.edu/IntroCompOrg-x64/bookch15.html
https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
The post Exceptions & Interrupts in Computer Systems appeared first on luozhiyun`s Blog .
This article is reproduced from: https://www.luozhiyun.com/archives/705
This site is for inclusion only, and the copyright belongs to the original author.