Linux memory management | 2. Virtual address space layout

img
My circle: Senior engineer gathering place
I am Brother Dong, a senior embedded software development engineer. I am engaged in embedded Linux driver development and system development. I have worked for a Fortune 500 company!
Creative philosophy: focus on sharing high-quality embedded articles so that everyone can gain something from reading!
img
img

In the previous chapter, we learned about the origin and core ideas of memory management. Let's first introduce the management of virtual memory space in order.Linux

 

Similarly, we knowLinuxThe kernel abstracts the virtual memory space mainly to allow each process to enjoy the space exclusively. So how is the virtual memory space laid out?

Premise: For different digitsCPU, the addressing capabilities are different, and the abstracted virtual memory space sizes are also different. We use common Take the32 bitCPU as an example.

 

1. Virtual memory space layout

For 32 bits of CPU, the addressing range is 0~2^32, that is, 0x00000000-0xFFFFFFFF, that is, the virtual memory space abstracted up to 4G.

This4GB memory space is divided intouser space and kernel spaceLinux a> is the kernel space, as follows:, a total of is user space, , a total of , of which 0x0000000-0xBFFFFFFF3G0xC00000000-0xFFFFFFFF1G

image-20230924173124939

Regardless of kernel space or user space, it is still divided on the basis of virtual memory space, and its direct access is still virtual address, not physical address!

After we write the code, the generated executable program becomes a system process after running. From a "virtual" point of view, each process has exclusive use of this< a i=1>virtual address space,4G

 

2. User space layout

As mentioned above, user space is distributed in 0x0000000-0xBFFFFFFF in virtual memory with size 3G.

Each user process is divided into 5 different memory areas according to the principle that address spaces with consistent access attributes are stored together Access attributes consistently refer to: readable, writable, executable):

  • code segment:Text Segment, which is our binary program, the code segment needs to be prevented from being illegally modified during runtime,< a i=3>So this section is read-only.
  • Data segment:Data Segment, mainly stores initialized variables, mainly including: static variables and global variables, This section is read and write.
  • BSS section:BSS Segment, mainly stores uninitialized global variables. In the memory, all bss sections are set to zero. ,This section is read and write.
  • Heap segment:Heap Segment, mainly stores the memory segment dynamically allocated during the running of the process. The size is not fixed and can be dynamically expanded and reduced. Usually Use malloc and free to allocate and release, and the heap growth direction is upward.
  • File mapping and anonymous mapping segments:Memory Mapping Segment, mainly store files used by the process or dependent dynamic libraries, growing upward from low addresses.
  • Stack segment:Stack Segment, mainly stores local variables temporarily created by the process, function call context information, etc., and the stack grows downward.

image-20231005160139650

For an executable program, you can use the size command to view the size of the compiled executable file, which includes code segments, data segments and other data information, as follows:

donge@Donge:$ size Donge-Demo
   text    data     bss     dec     hex filename
  12538    1916   43632   58086    e2e6 Donge-Demo
  • text:Code segment size
  • data:Data segment size
  • bss:bssstage size
  • dec: Executable file size in decimal format
  • hex: Executable file size in hexadecimal

 

After running the program, you can use the cat /proc/PID/maps command or the pmap PID command to view the allocation of the process in the virtual memory space, where the PID is the PID number of the process, as follows:

donge@Donge:$ cat /proc/16508/maps
55976ff9e000-55976ffa0000 r--p 00000000 08:10 184922                     /home/donge/WorkSpace/Program/Donge_Programs/Donge_Demo/build/Donge-Demo
55976ffa0000-55976ffa2000 r-xp 00002000 08:10 184922                     /home/donge/WorkSpace/Program/Donge_Programs/Donge_Demo/build/Donge-Demo
55976ffa2000-55976ffa3000 r--p 00004000 08:10 184922                     /home/donge/WorkSpace/Program/Donge_Programs/Donge_Demo/build/Donge-Demo
55976ffa3000-55976ffa4000 r--p 00004000 08:10 184922                     /home/donge/WorkSpace/Program/Donge_Programs/Donge_Demo/build/Donge-Demo
55976ffa4000-55976ffa5000 rw-p 00005000 08:10 184922                     /home/donge/WorkSpace/Program/Donge_Programs/Donge_Demo/build/Donge-Demo
55976ffa5000-55976ffaf000 rw-p 00000000 00:00 0
559771d91000-559771db2000 rw-p 00000000 00:00 0                          [heap]
7fec1ad84000-7fec1ad87000 rw-p 00000000 00:00 0
7fec1ad87000-7fec1adaf000 r--p 00000000 08:10 22282                      /usr/lib/x86_64-linux-gnu/libc.so.6
7fec1adaf000-7fec1af44000 r-xp 00028000 08:10 22282                      /usr/lib/x86_64-linux-gnu/libc.so.6
7fec1af44000-7fec1af9c000 r--p 001bd000 08:10 22282                      /usr/lib/x86_64-linux-gnu/libc.so.6
7fec1af9c000-7fec1afa0000 r--p 00214000 08:10 22282                      /usr/lib/x86_64-linux-gnu/libc.so.6
7fec1afa0000-7fec1afa2000 rw-p 00218000 08:10 22282                      /usr/lib/x86_64-linux-gnu/libc.so.6
7fec1afa2000-7fec1afaf000 rw-p 00000000 00:00 0
7fec1afb5000-7fec1afb7000 rw-p 00000000 00:00 0
7fec1afb7000-7fec1afb9000 r--p 00000000 08:10 22068                      /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7fec1afb9000-7fec1afe3000 r-xp 00002000 08:10 22068                      /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7fec1afe3000-7fec1afee000 r--p 0002c000 08:10 22068                      /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7fec1afef000-7fec1aff1000 r--p 00037000 08:10 22068                      /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7fec1aff1000-7fec1aff3000 rw-p 00039000 08:10 22068                      /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7ffce385d000-7ffce387e000 rw-p 00000000 00:00 0                          [stack]
7ffce394e000-7ffce3952000 r--p 00000000 00:00 0                          [vvar]
7ffce3952000-7ffce3953000 r-xp 00000000 00:00 0                          [vdso]

The above can roughly see the code segment, heap, file mapping segment, stack memory distribution, etc. of the process. The above is the layout of the user-mode virtual memory space after our executable program is loaded into the memory.

 

By the way, let me introduce my circle:A gathering place for senior engineers. I look forward to everyone joining me.

3. Kernel state space layout

Let's take a look at the virtual space layout of the kernel state. First we need to know:

  1. InLinuxsystems, user processes usually can only access virtual addresses in user space, and can only access kernel space when executing inline operations or system calls.
  2. After all processes enter the kernel state through system calls, they see the same virtual address space. They share the kernel state virtual memory space.

 

The 32-bit kernel state virtual space is distributed on0xC00000000-0xFFFFFFFF in the virtual memory, with a size of 1G, which is divided into the following areas< /span>

  • Direct mapping area (Direct Memory Region): As the name suggests, the direct mapping area directly establishes a one-to-one mapping relationship with physical memory. The kernel space address range starting from the starting address of kernel space to 896M is a direct memory mapping area. The linear address and allocated physical address of this area are continuous.

896MThe above kernel address space is also called the high-end memory area.

  • Security Protection Zone: It also becomes a memory hole with a size of 8M. Its main purpose is to avoid illegal access to non-contiguous areas. a>

  • Dynamic mapping area: that is, vmalloc Region, this area is allocated by the Vmalloc function, and its characteristics are: virtual address The space is continuous, but the physical address space is not necessarily continuous.

  • Permanent mapping area (Persistent Kernel Mapping Region): This area is mainly used to access high-end memory and is allocated through the alloc_page (_GFP_HIGHMEM) interface High-end memory page, you can use the kmap function to map the allocated high-end memory to this area.

  • Fixed mapping area (Fixing kernel Mapping Region): The virtual memory address in this area can be freely mapped to the high-end address of physical memory. The "fixed" expression is "The virtual memory space address is fixed", and the mapped physical address is variable.

Why is there the concept of fixed mapping?

For example: during the kernel startup process, some modules need to use virtual memory and map it to a specified physical address, and there is no way for these modules to wait for the complete memory management module to be initialized before performing address mapping. Therefore, the kernel has fixedly allocated some virtual addresses, and these addresses have fixed purposes. The module using this address maps these fixedly allocated virtual addresses to the specified physical address during initialization.

image-20231005155942462

4. Summary

The above is the division of the entire virtual address space, summarized as follows:

image-20231005160802093

Like + follow, never get lost

img
Welcome to follow the official account & Planet [Embedded Art], original by Brother Dong!

Guess you like

Origin blog.csdn.net/dong__ge/article/details/133782500
Recommended