The system calls
The kernel provides interactive interfaces for user processes, which can provide restricted access to hardware devices, apply for operating system resources, create processes and communicate with processes. Each system call in Linux corresponds to a system call number that identifies a particular system call.
- System call not only provides the request interface for the application program, but also ensures the security and stability of the system. User-space programs cannot directly access kernel code, which resides in a protected memory address that user processes cannot access.
- The system call adds a layer between the user process and the hardware device, shielding the complex operation of the hardware, thus making the application layer easier to use.
Application Programming Interface API
In fact, applications generally use the application programming interface implemented in user space to indirectly call system calls. Apis can realize an interface through one or several system calls, and can shield the differences of different operating systems to provide the same interface for applications, such as the common C library. In addition, POSIX annotations give the relationship between apis and system calls, and different operating systems can provide POSIX-compatible libraries that allow applications to implement a unified interface.
Hardware management
The core task of the operating system kernel includes managing the extended hardware of the computer, such as hard disk, keyboard, mouse, and other extended hardware. The kernel must be able to communicate with them, but there is a key concern about the communication process, and that is speed. The CPU is very fast, but the speed of making a request to the hardware and receiving a response is very slow. How to get them to work together effectively is the core problem of hardware management, because this problem can seriously affect the overall performance.
There are two implementations: polling mechanism and interrupt mechanism. Polling allows the kernel to periodically query the hardware to see if it needs processing, and to process it if it does, which can make the kernel do a lot of unproductive work. The interrupt mechanism, on the other hand, lets the hardware take the initiative to send signals to the kernel when an event occurs, and then the kernel steps in to handle it. Kernels also typically use interrupt mechanisms to manage hardware.
About the interrupt
The interrupt mechanism allows the hardware to send a notification to the CPU. The interrupt is essentially a special electrical signal that the processor receives and immediately informs the kernel. For example, when the mouse is clicked, the mouse controller will send an interrupt notification. Once the processor detects the interrupt signal, it interrupts its current work and processes the interrupt. Then it informs the operating system that the mouse has generated an interrupt, and the kernel knows that the mouse has been pressed, and the kernel is responsible for processing the event.
Interrupts are different on different devices. A unique number is used to identify the interrupts, that is, the interrupt values of the mouse, keyboard, and hard disk are different. The operating system handles different interrupts. Interrupt value is also called interrupt request line (IRQ), each IRQ corresponds to a value, such as 0 bit clock interrupt on PC, 1 bit keyboard interrupt. Of course, it is also possible to allocate interrupt values dynamically.
Interrupts Interrupt the operating system by hardware, providing a mechanism for the hardware to communicate with the operating system.
Interrupt handler
In response to each particular interrupt, the kernel executes a specified function, the interrupt handler. Each hardware has a corresponding interrupt handler, which is part of the device driver. In Linux, an interrupt handler is a C function that is declared of a certain type and then called by the kernel in a standard way. Interrupt handlers are called by the kernel to respond to interrupts. They run in an interrupt context, and code executed in that context cannot block.
Interrupt signal can happen at any time, so interrupt handler can be run at any time, it must ensure that it is executed quickly, in order to quickly resume the execution of interrupt code. Ideally, interrupts can be responded to quickly and interrupt handlers can be executed quickly. But the interrupt program to deal with often have a lot of work, for example, for the network, the interrupt handler to copy the network card packet into the memory, but also after processing it to the appropriate protocol stack, and finally inform the hardware has processed the interrupt signal.
The upper and lower parts of the interruption
We want fast interrupt responses, but at the same time we want to do more work in interrupt handlers. To solve this problem, interrupt handling is divided into upper and lower halves. The upper half is used to perform time-constrained work, such as answering hardware. The lower half deals with work that can be deferred. In fact, the upper and lower half is an asynchronous processing idea, so as to ensure the response speed, but also to complete a large workload of processing.
As for the NIC, the cache size is fixed. Once the NIC receives data, the kernel must copy it to the memory immediately. Otherwise, the NIC’s cache may be full and packets may be lost. In view of this situation, for the network card interrupt signal processing should quickly copy the network card packet to the memory, this is the work of the first half, after the fast execution immediately end interrupt processing, the processor back to the interrupt before the program. The time-consuming packet processing operations are placed in the lower part, which can be processed later without strong timeliness.
Each device has its own driver, which registers interrupt handlers through the request_irq() function.
Interrupt context
An interrupt context is the context in which the kernel executes an interrupt handler, in which it cannot sleep, and in which it cannot call certain functions. An interrupt handler interrupts other code that is executing, so it must execute quickly and concisely. The interrupt handler has its own stack.
Linux Interrupt Procedure
The hardware generates an interrupt signal, which sends an electrical signal across the bus to the interrupt controller, which sends the interrupt signal to the processor. The processor immediately stops what it is doing, shuts down the interrupt system and jumps to a predefined location to start executing code, which is an interrupt handler entry set by the kernel. For each interrupt line, the processor jumps to a corresponding unique entry location. The kernel executes the do_IRQ() function in response to received interrupts.
System timer
A large number of kernel functions are time-driven, such as functions that execute periodically, which require timers to support. System timer is a kind of programmable hardware chip, it interrupts with a fixed frequency, that is, timer interrupt, its corresponding interrupt handler is responsible for updating the system time, but also responsible for the execution of periodic tasks. Timers and clock interrupt handlers are the backbone of the Linux kernel management mechanism.
Timers are the basis for managing kernel elapsed time. When using timers, you set a timeout and specify the function to execute when the timeout occurs. This function will be automatically executed when the timer is up, and it only runs once.
Kernel time
The kernel needs the help of hardware to calculate and manage time. The hardware provides the kernel with a system timer to count the elapsed time, which is handled by the kernel’s specific interrupt handler when a clock interrupt occurs. The timer automatically triggers time interrupts at a certain frequency, which is called the beat rate. The interval between two consecutive time interrupts is the beat. The kernel calculates the wall time and system uptime by the known beat. The wall time is the actual time, and the system uptime is the time since the system started. The kernel also provides user space with a set of system calls to get the actual time and date.
Real time clock
A real-time clock (RTC) is a device designed to persistently store system time. It relies on a tiny battery on the motherboard to keep the system time, so it can keep the system time even when the system is shut down. The real-time clock and CMOS are integrated. The real-time clock and BIOS save Settings are powered by the same battery. When the system starts, the kernel reads the real-time clock to initialize the wall time, which corresponds to the variable xtime.
Time-based kernel management
The kernel relies on clock interrupts for much of its work, such as:
- Update system running time.
- Actual time update work.
- In the SMP structure, equalizing the work of the run queue in the scheduler.
- Determine whether the current process has used up its time slice and schedule work.
- Run the dynamic timer.
- Processor time statistics.
About the beat rate
The beat rate of the system timer is provided to the static preprocessing definition in HZ, which is defined by the kernel in asm/param.h file. The default timer frequency on x86 systems is 100, so clock interrupt comments are set to 100 hz. Clock interrupts are performed 100 times per second, once every 10ms. Different architectures may have different beat rates.
The higher beat rate provides time-driven time resolution and improves the accuracy of time-driven events. For Linux, it provides higher precision for system calls such as poll() and select(), and improves the accuracy of process preemption. However, a high cadence rate imposes a burden on the system because clock interrupt handlers are executed more frequently, increasing power consumption.
jiffies
Jiffies is a global variable that records the total number of ticks that have been generated since the system was started. It starts at 0, and each time the clock interrupts it increases the changed value by the beat rate, or N Hertz, per second. The work of the clock interrupt handler generally includes:
- Obtain xTIME_lock to protect jiffIES_64 and wall time xtime.
- Answer system clock.
- Update the real-time clock with wall time.
- Accumulative jiffies_64.
- Update the system time and user time consumed by the current process.
- Example Run the expired timer.
- Calculate the load average.
Focus on artificial Intelligence, reading and feeling, talk about mathematics, computer Science, distributed, machine learning, deep learning, natural language processing, Algorithms and Data Structures, Java depth, Tomcat kernel, etc.