Memory from the hardware point of view

Paper tape

Memory memory

Dynamic partitioning

Segmentation mechanism

Paging mechanism

Look at memory from the kernel

Why distinguish between kernel space and user space

What are user state and kernel state

How to enter kernel space from user space

The process context and interrupt context

First, from the hardware to see the memory

Summary: For multitasking operating systems, each process has a separate process address space. These process address spaces are isolated from each other within the virtual address space, but may map the same physical page in the physical address space. Their mapping relationship mainly relies on the MMU of the processor to provide page table mapping and management functions

The process address space is divided into kernel space and user space. They can all be mapped to actual physical addresses through the page table mechanism provided by the processor.

Second, look at the memory from the kernel

Memory management is a very complex system, if described by layers, memory space can be divided into three levels, namely user space, kernel space, and hardware layer. where the operating system and drivers run in kernel space, while applications run in user space.

User space: 0x0000 0000 0000 0000 ~ 0x0000 FFFF FFFF FFFF

Kernel space: 0xFFFF 0000 0000 0000 ~ 0xFFFF FFFF FFFF FFFF

The virtual address space of the base bit is located at 0x0000 0000 0000 0000 ~ 0x0000 FFFF FFFF FFFF FFFF If the highest bit of the virtual address is equal to 0, this virtual address space is used and the TTBR0_BLx is used to hold the base address of the page table.

The virtual address space for the high bits is located at 0xFFFF 0000 0000 0000 ~ 0xFFFF FFFF FFFF FFFF FFFF TTBR1_ELx FFFF FFFF

For example, in the AArch64 architecture, because the address bus bit width supports up to 48 bits, the virtual address (VA) is divided into two spaces (user space, kernel space), each supporting up to 256TB.

The MMU in the AArch64 architecture supports single-stage page table conversion and also supports two-phase page table conversion in virtualization extensions.

Single-stage page table conversion: Translation of virtual addresses (VA) into physical addresses (PAs)

Two-stage page table translation: 1) Translate the virtual address into an intermediate physical address (IPA) 2) Translate the IPA into the final PA

In a 32-bit Linux system, the total virtual address space that can be used is 4GB. The space is divided into 0-3GB for user space and 3-4GB for kernel space. It is usually divided by 3:1, but of course it can also be divided by 2:2.

1. Why distinguish between kernel space and user space

Of all the instructions in the CPU, some instructions are more dangerous and easy to cause the system to crash, such as cleaning memory, setting the clock, etc. For those dangerous instructions, only allow the operating system kernel to have its own permission to operate, and ordinary applications can only use those instructions that will not cause disaster.

Intel’s CPU, for example, divides the privilege hierarchy into four levels, Ring0-Ring3. In fact, the Linux system only uses two runlevels, Ring0 and Ring3. When running the Ring3 level, it is called running in user state, and when running at the Ring0 level, it is called running in kernel state.

2. What is user state and kernel state

When a process initiates a system call and the process executes in kernel code, the process is said to be in the kernel state. At this point the processor is at the highest privilege (Ring0 level). When a process is in kernel state, the kernel code executed uses the kernel stack of the current process, and each process has its own kernel stack.

When a process executes in user space, the process is said to be in user state. At this point the processor is at the lowest privilege level (Ring3 level). When a process is in user state, the executed program code uses the user stack of the current process’s user space, and each process has its own user stack.

Note: When the executing user program is suddenly interrupted by the interrupting program, at this time the user program can also be symbolically referred to as in the kernel state of the process. Because the interrupt handler will use the kernel stack of the current process.

Kernel state: the process runs in the kernel address space, at this time the CPU can execute any instructions, the running code is not restricted, can access any valid address, can also be port access.

User state: The process runs in the user address space, and the code being executed at this time is subject to many checks by the CPU, and they can only access the virtual address of the page table entries of other address spaces that specify the virtual address of the page that can be accessed in the user state, and can only directly access the accessible ports specified in the I/O license bitmap in the task status segment (TSS).

Note: For the previous DOS operating system, there is no concept of kernel space, user space, kernel state, user state, and the code is generally considered to be running in the kernel state, so the operating system is easy to crash. For Linux, by distinguishing between kernel space and user-space design, the operating system code and application code are isolated, making the operating system more robust, more stable and usable, and more secure.

3. How to enter kernel space from user space

The three scenarios triggered by user space entering kernel space are system calls (soft interrupts), exceptions, and hardware interrupts.

When a process is created, it will generate two stacks, namely the user stack and the kernel stack. The user stack is in the user address space, and the kernel stack is in the kernel address space.

When a process executes in user space, the user stack is used, and the address of the user stack is stored in the CPU stack pointer register.

When a process executes in kernel space, the kernel stack is used, and the address of the kernel stack is stored in the CPU stack pointer register.

1) System call case

When a process needs to read a resource on disk, it will issue a system call to the operating system, such as (Open(), Read(), Write(), Close() open interface, etc. At this point, some CPU context switching actions occur.

Saves the original user-state instruction bits in the current CPU register

In order to execute kernel-state code, the CPU registers need to be updated to the new location of the kernel-state instructions

Jump to kernel-state to run kernel tasks, such as reading resources from the invocation of disk IO into the kernel-state kernel cache

After disk IO is over, copy the data from the kernel cache area of kernel space to the user cache area of user space

When the system call ends, the CPU registers are restored to their original user-state instruction bits

Finally switch to user space and continue running the process

In general, in kernel space, the code controls the use of hardware layer resources, and the code in user space can only call the hardware resources in the system through the system call interface that the kernel is open to the public.

4. Process context and interrupt context

The processor is always in one of three states

Kernel state, running in the process context, the kernel represents the process running in kernel space

Kernel state, running in interrupt context, kernel on behalf of hardware running in kernel space

User state, which runs in user space

User-space applications, through system calls, enter kernel space. At this time, the user-space process must pass many variables and parameter values to the kernel, and some register values and variables of the user process must be saved when the kernel is running. The so-called “process context” can be seen as these parameters passed by the user process to the kernel, as well as the set of variables and register values to be saved by the kernel and the environment at that time.

The hardware triggers a signal, causing the kernel to call an interrupt handler and enter kernel space. In this process, some variables and parameters of the hardware are also passed to the kernel, and the kernel uses these parameters for interrupt handling. The so-called “interrupt context” can also be seen as these parameters passed by the hardware and some other environments that the kernel needs to save (mainly the process environment that is currently interrupted for execution).

3. Sources of reference