Hao Jian: Linux Memory Management Study Notes - Lesson 1 [Transfer]

This article is reproduced from: https://blog.csdn.net/juS3Ve/article/details/80035751

Summary

MMU and paging mechanism

Memory area (memory sub-ZONE)

LinuxBuddy Allocation Algorithm

CMA (Contiguous Memory Allocator)

 

 

0. Reading before class

Song Baohua: How does the CPU access the memory? --The most basic principle of MMU

http://mp.weixin.qq.com/s/SdsT6Is0VG84WlzcAkNCJA

 

Song Baohua: Experience Meltdown Vulnerability with Code

http://mp.weixin.qq.com/s/lJJU3LCepJgNq5AxyFFM8Q

 

The death of speculation - a picture to understand the MELTDOWN vulnerability

http://mp.weixin.qq.com/s?__biz=MzA3NTk5MDIzNw%3D%3D&mid=2647665589&idx=1&sn=3c29a6c3fe477cbd3b2efed983b1dd5e&scene=45#wechat_redirect

 

 

  1. MMU and paging mechanism

640?wx_fmt=png

MMU (Memory Management Unit) is a piece of hardware that assists the operating system in memory management, providing hardware support such as virtual address and physical address mapping, memory access permission protection, and cache control. Once the CPU turns on the MMU, the CPU can only see the virtual address (the programmer can only see the virtual address), and only the MMU can see the physical address.

The main functions of MMU are as follows:

1) Provide a mapping of virtual addresses and physical addresses

For example, the CPU accesses a 32-bit virtual address 0x12345 670, assuming that the MMU management divides the memory of each page into 4K (the PageSize usually used in 32-bit systems is 4K), the p (page number) in the above figure is 12345 , d (in-page offset address) is 670. First, use p to look up the page table (the page table itself is also in memory), find the corresponding page table entry, and the page table entry will fill in the physical address corresponding to the virtual address of this page.

Note: The base address register stores the base address of the page table. Each time the process switches, the value of the register will change, because the page table of each process is different.

 

2) Memory access permission protection

In addition to the physical address corresponding to the virtual address, each page table entry also has the RWX permission for the page address. For example, if the code segment has only R+X, and a pointer is used to write the code segment, a page fault will occur (page fault will occur in both cases: i. The virtual address does not find the corresponding physical address; ii. The virtual address has a corresponding physical address , but the permissions are wrong). EG. Write const variable page fault

640?wx_fmt=png

Another important point is that another parallel permission of this page can also be marked in the page table entry of the MMU, that is, whether this virtual address can be accessed in user mode and kernel mode or only in kernel mode. For example, under IA32, the kernel space address is generally mapped to 3GB~4GB, and the page table above 3G is set in the page table entry to be accessed only when the CPU is trapped in kernel mode. This restricts user-mode programs' access to kernel data. EG. Meldown side-channel attack, breaking through hardware limitations.

 

Notes:

i. "Virtual addresses are pointers, physical addresses are integers (32-bit or 64-bit integers, not pointers)"

You can refer to the definition of physical addresses in the kernel code: include/linux/types.h

640?wx_fmt=png

       ii. Since the access speed of the page table is very slow, the TLB (Translation Looksize Buffer), the core component of the MMU, is introduced. TLB is the core component of the MMU. It caches a small amount of the conversion relationship between virtual addresses and physical addresses. It is the Cache of the translation table, commonly known as "" Quick Table".

When there is no buffer corresponding address translation relationship in the TLB, it is necessary to access the translation table in the memory (the translation table of most processors is a multi-level page table) to obtain the corresponding relationship between virtual addresses and physical addresses. A core component TTW (TranslationTable walk). After a successful TTW, the result should be written into the TLB.

iii. MPU: Memory protection unit, which can only manage permissions and cannot perform virtual-real mapping.

 

2. Memory area (memory is divided into ZONE)

640?wx_fmt=png

1)ZONE_DMA

640?wx_fmt=png

DMA is relative to memory and can directly access memory as CPU is relative to memory. Because some DMA engines may be defective, they may not be able to access all memory (for example, when the DMA engine on the x86 ISA bus accesses memory, the address line can only be sent to less than 16M, and its hardware cannot access memory above 16M at all. ), and therefore the ZONE_DMA. The size of ZONE_DMA is determined by hardware, for example some architectures have no problem performing DMA at any address in memory, on these architectures ZONG_DMA is empty.

The memory of ZONE_DMA is not dedicated to DMA, but when a defective DMA wants to apply for memory, it should apply from this area, for example, a driver module calls void*dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_tgfp); When the function applies for a ZONE_DMA memory area, the gfp parameter needs to be written as GFP_DMA.

 

2)ZONE_HIGHMEM,ZONG_NORMAL

Under IA32, 0~3G is the virtual address of user space, and 3G~4G is the virtual address of kernel space. In order to simplify the kernel's access to memory, Linux directly linearly maps a segment of physical address to a virtual address above 3G as soon as it is powered on. Note that the physical memory may be larger than 1G, and it cannot be linearly mapped to the virtual address space of virtual 3G~4G. Therefore, Linux directly limits the physical memory (the limit of 32-bit x86 system is 896MB). Below this limit Only do one-to-one mapping, below this limit is called low memory, above this limit is called high memory. low memory contains ZONG_NORMAL+ZONE_DMA. Note: Although low memory is linearly mapped at startup, it does not mean that low memory has been used by the kernel. When the kernel wants to use memory, it needs to apply for it just like the application.

The physical address and virtual address of low memory is a direct linear mapping, which can use the kernel API: phys_to_virt and virt_to_phys map directly between physical and virtual addresses, while high memory cannot use these two APIs.

Kernel space generally does not use high memory, and the memory requested by kmalloc is generally in low memory. When the kernel space uses high memory, kmap is called for mapping. x86 will map highmemory to virtual addresses above 3G, while ARM will map to 3G-2M~3G. As shown in the following two figures:

640?wx_fmt=png

640?wx_fmt=png

To sum up, the reason for high memory is that it is impossible to map all physical addresses one by one in the virtual address mapping area; the reason for ZONE_DMA is the hardware defect of the DMA engine. The partitions on x86-32 are summarized as follows:

640?wx_fmt=png

Note that the division of regions has no physical meaning, but is just a logical grouping adopted by the kernel to manage pages.

 

3. Linux Buddy Allocation Algorithm

640?wx_fmt=png

The three areas of DMA, conventional and high-end memory are managed by the buddy algorithm, and the free pages are managed in units of 2 to the nth power. Therefore, the lowest memory application of Linux is in units of 2 n  . The main feature of the Buddy algorithm is that the free memory in the region can be split or merged by 2 to the nth power at any time.

For example, assuming that ZONE_NORMAL has 16 pages of memory (2 4 ), and someone applies for one page of memory, the Buddy algorithm will split the remaining 15 pages into 8+4+2+1 and put them in different linked lists. At this time, if you apply for 4 more pages, you will directly give 4 pages. If you apply for 4 more pages, you will give 4 pages from the 8 pages, leaving just 4 pages. The essence of Buddy's algorithm is that any positive integer can be split into the sum of 2 to the nth power.

 

Some cases of free memory can be seen through /proc/buddyinfo: 

640?wx_fmt=png

4. CMA (Contiguous Memory Allocator)

The Buddy algorithm will lead to fragmentation of memory, leading to CMA technology.

640?wx_fmt=png

It does not matter which physical address the virtual address of the application is mapped to, whether the physical address is continuous or not. But there is no MMU in the DMA engine, and sometimes contiguous physical memory is required. For example, if there is a DMA in a camera, you need to use DMA to move a picture taken from the camera to the memory. At this time, the DMA applies for a continuous 16M memory for moving, but even if the physical memory is free 100M (but not continuous), the DMA will Unable to apply.

 

In order to solve the problem of the camera example, Linux can reserve 16M memory for the camera as soon as it is turned on. Even if it is not used, it will be wasted. The CMA technology is to avoid memory waste, so that the 16M memory is not reserved and the application can be used. Once If the camera is to be used, the CMA will squeeze the 16M memory out to the camera.

Since the virtual address of the application is mapped to which physical address, it doesn't matter whether it is continuous or not, and it doesn't even matter if the virtual address is moved to another physical address. As long as the virtual address does not change, the application will not notice it, so when the general application applies for memory You can attach the movable tag, and Linux can put the memory application of the application with the movable tag into the CMA area. When the camera DMA applies for memory, it applies for a lot of 4K (one page) memory, and moves the physical address of the movable application to these memories. Note that moving the memory will modify the page table entry of the application, although the virtual address unchanged, but the mapping to physical addresses has changed. In this way, the previous 16M memory is squeezed out to the camera's DMA.

Note that CMA is used in conjunction with the DMA API. When the DMA API is used to apply for memory, the CMA mechanism is triggered.

You can specify which section of memory is used for CMA in dts, you can specify a default global CMA pool, or you can specify a CMA pool for a specific device. For the specific implementation method, please refer to the kernel document Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt

640?wx_fmt=png

Guess you like

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