Linux kernel-process address space

This article borrows from: https://www.cnblogs.com/fengliu-/p/9243004.html
https://blog.csdn.net/wsq119/article/details/82110757
https://www.cnblogs.com/wuchanming/ p/4339770.html

Process address space distribution diagram:
Insert picture description here
Program segment (Text): The mapping of program code in memory, storing the binary code of the function body.
Initialized data (Data): The data that has been initialized to the variables at the beginning of the program.
Uninitialized data (BSS): The data that has not initialized the variables at the beginning of the program operation.
Stack: Stores local and temporary variables. When the function is called, it stores the return pointer of the function, which is used to control the call and return of the function. The memory is automatically allocated at the beginning of the program block, and the memory is automatically released at the end. The operation mode is similar to the stack in the data structure.
Heap: Storage dynamic memory allocation, which requires manual allocation and manual release by the programmer. Note that it is different from the heap in the data structure, and the allocation method is similar to a linked list.

Early memory allocation mechanism

In the early computer, to run a program, all these programs were loaded into the memory, and the program was run directly on the memory, that is to say, the memory addresses accessed in the program were the actual physical memory addresses. When a computer is running multiple programs at the same time, it must be ensured that the total amount of memory used by these programs is less than the size of the actual physical memory of the computer.
When the program runs multiple programs at the same time, how does the operating system allocate memory for these programs? The following is an example to illustrate the memory allocation method at that time: the
total memory size of a computer is 128M, and now two programs A and B are running at the same time, A needs to occupy 10M of memory, and B needs to occupy 110 of memory. When the computer allocates memory to the program, it will adopt this method: first allocate the first 10M in the memory to program A, and then divide 110M from the remaining 118M in the memory and allocate it to program B. This allocation method can ensure that both program A and program B can run, but this simple memory allocation strategy has many problems.

Segmented

In order to solve the above problems, people thought of a workaround, which is to add an intermediate layer and use an indirect address access method to access physical memory. According to this method, the memory address accessed in the program is no longer an actual physical memory address, but a virtual address, and then the operating system maps this virtual address to an appropriate physical memory address. In this way, as long as the operating system handles the mapping of virtual addresses to physical memory addresses, it can ensure that the memory addresses finally accessed by different programs are located in different areas without overlapping each other, and the effect of memory address space isolation can be achieved.
When a process is created, the operating system allocates a 4GB virtual process address space for the process. The reason why it is 4GB is because in a 32-bit operating system, a pointer is 4 bytes in length, and the addressing capability of a 4-byte pointer is from 0x00000000 to 0xFFFFFFFF, and the maximum value 0xFFFFFFFF represents a capacity of 4GB. In contrast to the virtual address space, there is also a physical address space, which corresponds to real physical memory. If 512M memory is installed on your computer, the range of this physical address space is 0x00000000~0x1FFFFFFF. When the operating system maps a virtual address to a physical address, it can only map to this range, and the operating system can only map to this range. When a process is created, each process will have its own 4GB virtual address space. It should be noted that this 4GB address space is "virtual", not real, and each process can only access data in its own virtual address space, and cannot access data in other processes. This is achieved by this method Address isolation between processes.
The reason why people want to create a virtual address space is to solve the problem of process address space isolation. But if the program wants to execute, it must run on real memory. Therefore, a mapping relationship must be established between the virtual address and the physical address. In this way, through the mapping mechanism, when a program accesses an address value in the virtual address space, it is equivalent to accessing another value in the physical address space. People think of a method of segmentation. Its idea is to do a one-to-one mapping between the virtual address space and the physical address space. For example, a space of 10M in the virtual address space is mapped to a space of 10M in the physical address space. This idea is not difficult to understand. The operating system ensures that the address space of different processes is mapped to different areas in the physical address space, so that each process finally accesses it.
The physical address spaces are separated from each other. In this way, address isolation between processes is achieved. Let’s take an example to illustrate. Suppose there are two processes A and B. The memory size of process A is 10M, its virtual address space is distributed from 0x00000000 to 0x00A00000, the memory required by process B is 100M, and its virtual address space is distributed from 0x00000000 to 0x06400000. . Then according to the segmented mapping method, process A maps the area on the physical memory from 0x00100000 to 0x00B00000, and process B maps the area on the physical memory from 0x00C00000 to 0x07000000. Therefore, process A and process B are respectively mapped to different memory ranges, and they do not overlap each other, realizing address isolation. From the perspective of the application program, the address space of process A is distributed from 0x00000000 to 0x00A00000. During development, developers only need to access the addresses in this range. The application program does not care that the process A is mapped to the area of ​​physical memory, so the running address of the program is equivalent to being determined.
Although this segmented mapping method solves the first and third problems mentioned above, it does not solve the second problem, that is, the problem of memory usage efficiency. In the segmented mapping method, each time the memory is swapped in and out is the entire program, which will cause a large number of disk access operations, resulting in low efficiency. Therefore, this mapping method is still slightly rough, and the granularity is relatively large. In fact, the operation of the program has the characteristics of locality. In a certain period of time, the program only accesses a small part of the data of the program, that is, most of the data of the program will not be used in a certain period of time. Based on this situation, people think of a method of memory segmentation and mapping with a smaller granularity. This method is paging.

Pagination

The basic method of paging is to divide the address space into many pages. The size of each page is determined by the CPU, and then the operating system selects the page size. At present, the CPU of the Inter series supports 4KB or 4MB page size, while the PC currently chooses to use 4KB. According to this choice, the 4GB virtual address space can be divided into 1048576 pages, and the 512M physical memory can be divided into 131072 pages. Obviously, the number of pages in the virtual space is much more than the number of pages in the physical space.
In the segmentation method, the program is always loaded into the memory each time the program is run, but the paging method is different. The idea of ​​paging is to allocate memory for which page is used when the program is running, and the unused pages are temporarily kept on the hard disk. When these pages are used, memory is allocated for these pages in the physical address space, and then a mapping between the pages in the virtual address space and the newly allocated physical memory pages is established.
The following describes the implementation of the paging mechanism by introducing the loading process of an executable file. An executable file (PE file) is actually a collection of compiled and linked data and instructions. It will also be divided into many pages. During the execution of the PE file, the unit that it loads into the memory is the page. When a PE file is executed, the operating system will first create a 4GB process virtual address space for the program. As mentioned earlier, the virtual address space is just an intermediate layer. Its function is to use a mapping mechanism to map the virtual address space to the physical address space. Therefore, creating a 4GB virtual address space is not actually creating space, but The data structure needed to create that mapping mechanism is nothing more than the data structure of the page header and page table.
After creating the data structure required by the virtual address space, the process starts to read the first page of the PE file. The first page of the PE file contains information such as the PE file header and segment table. According to the file header and segment table, the process maps all the segments in the PE file to the corresponding pages in the virtual address space (in the PE file). The length of the segment is an integer multiple of the page length). At this time, the real instructions and data of the PE file have not been loaded into the memory. The operating system only establishes the mapping relationship between the PE file and the page in the process virtual address space according to the header and other information of the PE file. When the CPU wants to access a certain virtual address used in the program, when the CPU finds that the address does not have an associated physical address, the CPU thinks the page where the virtual address is located is an empty page, and the CPU thinks it is a page fault ( Page Fault), the CPU also knows that the operating system has not allocated memory to the PE page, and the CPU will return control to the operating system. The operating system then allocates a page in the physical space for the PE page, and then maps the physical page with the virtual page in the virtual space, and then returns the control to the process, and the process restarts from the position where the page fault occurred just now. carried out. Since memory has been allocated for that page of the PE file at this time, the page fault will not occur. With the execution of the program, page faults will continue to occur, and the operating system will allocate corresponding physical pages for the process to meet the needs of the process.
The core idea of ​​the paging method is that when the executable file is executed to the xth page, a memory page y is allocated for the xth page, and then this memory page is added to the mapping table of the process virtual address space. This mapping table is equivalent In a y=f(x) function. The application can access the y page associated with the x page through this mapping table.
From the above we can know that in the process of process creation,All the contents of the program are mapped to the virtual memory space of the process. In order to allow a large program to run in a limited physical memory space, we can load the beginning part of the program into the physical memory space to run, because the operating system deals with the process. If you find that the physical address does not exist in the virtual-to-physical address conversion project, a page fault (nopage) will occur at this time, and then the operating system will load the disk that has not been loaded into the memory The data is loaded into the physical memory, and the corresponding process page table is updated . You may ask, if the physical memory is full at this time, what will the operating system do?
Let’s take a look at how the linux operating system handles it:
If a process wants to load a virtual page into the physical memory, but there is no usable one. With free physical pages, the operating system must eliminate other pages in physical memory to make room for this page.
In the Linux operating system, the description of the physical page is as follows:

struct mem_map
{
    
    
1、本页使用计数,当该页被许多进程共享时计数将大于1
2、age描叙本页的年龄,用来判断该页是否为淘汰或交换的好候选
3、map_nr描叙物理页的页帧号
}

If the page that is eliminated from physical memory comes from an image or data file and has not been written, the page does not need to be saved, it can be discarded. If a process needs the page, it can retrieve it from the image or data file in memory.
However, if the page has been modified, the operating system must retain the content of the page so that it can be accessed at a later time. This kind of page is called a "dirty page". When it is deleted from memory, it will be saved in a special file called a swap file.
Relative to the speed of the processor and physical memory, it takes a long time to access the swap file, and the operating system must spend a lot of time on the issue of writing pages to disk and retrieving memory when they are used again.
If the algorithm used to determine which page is eliminated or exchanged is not efficient enough, a situation called "jitter" may occur. In this case, the page is always written to disk and read back, and the operating system is too busy to perform real work.
Linux uses the "Least Recently Used (LRU)" paging technique to fairly choose which page can be deleted from the system. Each page in this design system has an "age", and the age changes as the page is accessed. The more visited the page is, the younger it is; the less visited the older it is. The old page is the best candidate page for exchange.

linux virtual storage organization

Each process (thread) corresponds to a process descriptor (task_struct), each process descriptor has a memory descriptor (mm_struct) that is the unique process address space, and the memory descriptor contains a virtual memory area linked list ( vm_area_struct) is used to identify the area used in the address space
Insert picture description here

Guess you like

Origin blog.csdn.net/chengcheng1024/article/details/114382951