Kernel Mode and User Mode

1.  The architecture of Unix/Linux

  As shown in the figure above, from a macro perspective, the architecture of the Linux operating system is divided into user mode and kernel mode (or user space and kernel). The kernel is essentially a kind of software - it controls the hardware resources of the computer and provides the environment in which the upper-level applications run . User mode is the activity space of the upper-layer application. The execution of the application must rely on the resources provided by the kernel , including CPU resources, storage resources, and I/O resources. In order for the upper-layer application to access these resources, the kernel must provide the upper-layer application with an access interface: the system call.

  System calls are the smallest functional unit of the operating system . These system calls can be extended and tailored according to different application scenarios. Now various versions of Unix implementations provide different numbers of system calls. For example, different versions of Linux provide 240-260 System calls, FreeBSD provides about 320 (reference: UNIX environment advanced programming). We can think of a system call as an operation that cannot be simplified (similar to atomic operations, but different concepts), some people compare it to a "stroke" of a Chinese character, and a "Chinese character" represents an upper-level application , I think this analogy is very appropriate. Therefore, sometimes if you want to implement a complete Chinese character (allocate memory space to a variable), you must call a lot of system calls. From the perspective of the implementer (programmer), this will inevitably increase the burden on the programmer. A good programming method is to pay attention to the upper-level business logic operations and avoid the complex implementation details of the underlying layer as much as possible. Library functions are an effective way to free programmers from complicated details. It implements the encapsulation of system calls, and presents a simple business logic interface to users, which is convenient for users to call. From this perspective, library functions are like "radicals" that make up Chinese characters. Such a composition method greatly enhances the flexibility of program design. For simple operations, we can directly call system calls to access resources, such as "people", and for complex operations, we use library functions to implement them, such as " Benevolence". Obviously, such library functions can also have different implementation versions according to different standards, such as ISO C standard library, POSIX standard library and so on.

  Shell is a special application, commonly known as the command line, which is essentially a command interpreter. It connects system calls and various applications, usually acting as a kind of "glue" to connect various small function programs. Enhance the functionality of each program by enabling different programs to work together with a clear interface. At the same time, Shell is programmable. It can execute text that conforms to Shell syntax. Such text is called Shell script. Usually, a few lines of Shell script can achieve a very large function. The reason is that these Shell statements are usually correct. System calls do a layer of encapsulation. In order to facilitate the interaction between the user and the system, generally, a shell corresponds to a terminal, the terminal is a hardware device, and a graphical window is presented to the user. We can input or output text through this window. This text is passed directly to the shell for analysis, interpretation, and execution.

  To sum up, user-mode applications can access kernel-mode resources in three ways:

1) System call

2) Library functions

3) Shell script

  The picture below is a subdivision of the above picture, from which you can go further and get a "panoramic" impression of what the kernel is doing. Mainly as follows: downward control of hardware resources, inward management of operating system resources: including process scheduling and management, memory management, file system management, device driver management and network resource management, upward to provide applications. Interface for system calls. On the whole, the entire operating system is divided into two layers: user mode and kernel mode. This layered architecture greatly improves the scalability and flexibility of resource management, and facilitates users to call resources and centralize them. management, bringing a certain degree of security.

2. Switching between user mode and kernel mode

  Because the resources of the operating system are limited, if there are too many operations to access resources, it will inevitably consume too many resources, and if these operations are not distinguished, it is likely to cause resource access conflicts. Therefore, in order to reduce the access and use conflicts of limited resources, one of the design philosophies of Unix/Linux is to assign different execution levels to different operations, which is the concept of so-called privileges . Simply put, it is the ability to do as much as possible, and some particularly critical operations related to the system must be completed by the most privileged program. The CPU of Intel's X86 architecture provides four privilege levels from 0 to 3. The smaller the number, the higher the privilege level. The Linux operating system mainly uses two privilege levels, 0 and 3, which correspond to the kernel state and the user state respectively. The operations that a process running in user mode can perform and the resources it can access are greatly restricted, while a process running in kernel mode can perform any operation and have no restrictions on the use of resources. Many programs run in user mode at the beginning, but in the process of execution, some operations need to be executed under the permission of the kernel, which involves a process of switching from user mode to kernel mode . For example, the memory allocation function malloc() in the C function library uses the sbrk() system call to allocate memory. When malloc calls sbrk(), it involves a switch from user mode to kernel mode. Similar functions also There's printf(), which calls the wirte() system call to output strings, and so on.

  Under what circumstances will the switch from user mode to kernel mode occur? Generally, there are the following three situations:

1) Of course, it is the system call: the reason is the above analysis.

2) Abnormal events: When the CPU is executing a program running in user mode, some unexpected abnormal events suddenly occur, and at this time, abnormal events related to the process from the current user mode execution to the kernel mode execution will be triggered, typically such as page missing exception.

3) Interruption of peripheral devices: When the peripheral device completes the user's request operation, it will send an interrupt signal like the CPU. At this time, the CPU will suspend the execution of the next instruction to be executed, and turn to execute the processing program corresponding to the interrupt signal. , if the previously executed instruction was in user mode, the transition from user mode to kernel mode occurs naturally.

  注意:系统调用的本质其实也是中断,相对于外围设备的硬中断,这种中断称为软中断,这是操作系统为用户特别开放的一种中断,如Linux int 80h中断。所以,从触发方式和效果上来看,这三种切换方式是完全一样的,都相当于是执行了一个中断响应的过程。但是从触发的对象来看,系统调用是进程主动请求切换的,而异常和硬中断则是被动的。

三、总结

  本文仅是从宏观的角度去理解Linux用户态和内核态的设计,并没有去深究它们的具体实现方式。从实现上来看,必须要考虑到的一点我想就是性能问题,因为用户态和内核态之间的切换也会消耗大量资源。关于实现的细节,目前学艺不精不敢乱说,等日后补上。但知道了这一点,我相信对很多问题也就很容易理解了,比如说基于缓冲区的IO和无缓冲的IO,用户进程和内核进程之间的切换,IO复用中的读写内核事件表,等等,这些知识之后会一一补上。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324604878&siteId=291194637