Linux memory linear address space is 4 GB, divided into two parts: user space (usually 3 GB) and kernel space (usually 1 GB ). Here we mainly focus on the kernel address space.
The kernel manages all the physical memory through the global directory of the kernel page. Because the first 3G space before the linear address is used by the user, the first 768 Items in the global directory of the kernel page (just 3G) all except Items 0 and 1 are 0, and the last 256 Items (1 GB) are used to manage all the physical memory. The global directory on the kernel page is statically defined as the swapper_pg_dir array during compilation, which is stored at the physical memory address 0x101000.
Visible from the image,
(1) The Kernel linear address space starts from page_offset (usually 3 GB). to load the kernel into memory, 8 m linear addresses starting from page_offset are used to map the physical memory address of the kernel;
(2) next is the mem_map array. the starting line address of mem_map is related to the architecture. For example, for the UMA structure, because the 16 m physical address space corresponding to the 16 m linear address space starting from page_size is the DMA area, the mem_map array usually begins with the linear address of page_size + 16 m;
(3) The linear address space from page_size to vmalloc_start-vmalloc_offset is directly mapped to the physical memory space (one-to-one ing, physical address = Linear address-page_offset ), the size of this region is related to the actual physical memory size of the machine. Here, vmalloc_offset is 8 Mb on x86, which is mainly used to prevent out-of-bounds errors;
(4) On systems with relatively small memory, the remaining linear address space (also minus the blank area, that is, vmalloc_offset) is vmalloc () the function is used to map discontinuous physical address spaces to consecutive linear address spaces. On systems with large memory, vmalloc () use the linear address space from vmalloc_start to vmalloc_end (that is, pkmap_base minus the blank page size page_size of 2 pages)
(5) At this time, the remaining linear address space (also minus two blank spaces (vmalloc_offset) can be divided into two parts:
The first part is from pkmap_base to fixaddr_start, which is used to map high-end memory by the kmap () function;
The second part, from fixaddr_start to fixaddr_top, is a fixed-size linear address space (reference: fixed virtual addresses are needed for subsystems that need to know the virtual address at compile time such as the APIC). In the X86 architecture, fixaddr_top is statically defined as 0xffffe000, at this point, the fixed size space ends at 4 K before the last 4 K of the linear address space. The fixed size space is calculated during compilation and stored in the _ fixaddr_size variable.
The zone_normal zone size is limited because of the existence of vmalloc () use zone, kmap () use zone, and fixed large cell. Because these functions are required by the kernel during running, therefore, the online address space must have at least vmalloc_reserve space. The size of vmalloc_reserve is related to the architecture. on x86, vmalloc_reserve is defined as 128 m, which is why we can see that zone_normal is usually 16 m to M.
1. kmalloc () is the most common memory allocation method in the kernel. It finally calls the _ get_free_pages () function allocation of the partner system. Based on the flags parameter passed to this function, determines the purpose of the function allocation. If the flag is gfp_kernel, it can only be used in the process context. If the flag is gfp_atomic, it can be used to interrupt the context or hold the lock in the code segment.
The linear address returned by kmalloc is directly mapped, And the allocation request is satisfied with consecutive physical pages, and the maximum number of requests is built in (2 ** 5 = 32 pages ).
2. kmap () is mainly used in the kernel ing of the high-end storage page box. It is generally used as follows:
Use alloc_pages () to obtain the struct Page Structure in the high-end memory area, and then call kmap (struct * Page) in the address space after the kernel address space page_offset + 896m (pkmap_base to fixaddr_star) create a permanent ing (if the page structure corresponds to a page with low-end physical memory, this function returns only the virtual address of the page)
Kmap () may also cause sleep, so it cannot be used in code that interrupts or holds the lock.
However, kmap can only allocate one physical page, so it should be used as little as possible.
3. vmalloc preferentially uses high-end physical memory, but the performance will be discounted.
Physical pages allocated by vmalloc will not be exchanged;
The virtual address returned by vmalloc is larger than (page_offset + sizeof (Phys memory) + gap), which is a linear address between VMALLOC_START----VMALLOC_END;
Vmalloc uses a vmlist linked list, which is different from vm_area_struct used to manage user processes. The latter will swapped;
4. Reasons for using kmap:
For high-end physical memory (after MB), there is no one-to-one correspondence with the kernel address space (that is, the relationship between virtual address = physical address + page_offset), so get_free_pages () cannot be used () instead, you must use the interface of the partner system algorithm such as alloc_pages () to obtain the struct * Page Structure and map it to the kernel address space.
Linux memory linear address space is 4 GB, divided into two parts: user space (usually 3 GB) and kernel space (usually 1 GB ). Here we mainly focus on the kernel address space.
The kernel manages all the physical memory through the global directory of the kernel page. Because the first 3G space before the linear address is used by the user, the first 768 Items in the global directory of the kernel page (just 3G) all except Items 0 and 1 are 0, and the last 256 Items (1 GB) are used to manage all the physical memory. The global directory on the kernel page is statically defined as the swapper_pg_dir array during compilation, which is stored at the physical memory address 0x101000.
Visible from the image,
(1) The Kernel linear address space starts from page_offset (usually 3 GB). to load the kernel into memory, 8 m linear addresses starting from page_offset are used to map the physical memory address of the kernel;
(2) next is the mem_map array. the starting line address of mem_map is related to the architecture. For example, for the UMA structure, because the 16 m physical address space corresponding to the 16 m linear address space starting from page_size is the DMA area, the mem_map array usually begins with the linear address of page_size + 16 m;
(3) The linear address space from page_size to vmalloc_start-vmalloc_offset is directly mapped to the physical memory space (one-to-one ing, physical address = Linear address-page_offset ), the size of this region is related to the actual physical memory size of the machine. Here, vmalloc_offset is 8 Mb on x86, which is mainly used to prevent out-of-bounds errors;
(4) On systems with relatively small memory, the remaining linear address space (also minus the blank area, that is, vmalloc_offset) is vmalloc () the function is used to map discontinuous physical address spaces to consecutive linear address spaces. On systems with large memory, vmalloc () use the linear address space from vmalloc_start to vmalloc_end (that is, pkmap_base minus the blank page size page_size of 2 pages)
(5) At this time, the remaining linear address space (also minus two blank spaces (vmalloc_offset) can be divided into two parts:
The first part is from pkmap_base to fixaddr_start, which is used to map high-end memory by the kmap () function;
The second part, from fixaddr_start to fixaddr_top, is a fixed-size linear address space (reference: fixed virtual addresses are needed for subsystems that need to know the virtual address at compile time such as the APIC). In the X86 architecture, fixaddr_top is statically defined as 0xffffe000, at this point, the fixed size space ends at 4 K before the last 4 K of the linear address space. The fixed size space is calculated during compilation and stored in the _ fixaddr_size variable.
The zone_normal zone size is limited because of the existence of vmalloc () use zone, kmap () use zone, and fixed large cell. Because these functions are required by the kernel during running, therefore, the online address space must have at least vmalloc_reserve space. The size of vmalloc_reserve is related to the architecture. on x86, vmalloc_reserve is defined as 128 m, which is why we can see that zone_normal is usually 16 m to M.
1. kmalloc () is the most common memory allocation method in the kernel. It finally calls the _ get_free_pages () function allocation of the partner system. Based on the flags parameter passed to this function, determines the purpose of the function allocation. If the flag is gfp_kernel, it can only be used in the process context. If the flag is gfp_atomic, it can be used to interrupt the context or hold the lock in the code segment.
The linear address returned by kmalloc is directly mapped, And the allocation request is satisfied with consecutive physical pages, and the maximum number of requests is built in (2 ** 5 = 32 pages ).
2. kmap () is mainly used in the kernel ing of the high-end storage page box. It is generally used as follows:
Use alloc_pages () to obtain the struct Page Structure in the high-end memory area, and then call kmap (struct * Page) in the address space after the kernel address space page_offset + 896m (pkmap_base to fixaddr_star) create a permanent ing (if the page structure corresponds to a page with low-end physical memory, this function returns only the virtual address of the page)
Kmap () may also cause sleep, so it cannot be used in code that interrupts or holds the lock.
However, kmap can only allocate one physical page, so it should be used as little as possible.
3. vmalloc preferentially uses high-end physical memory, but the performance will be discounted.
Physical pages allocated by vmalloc will not be exchanged;
The virtual address returned by vmalloc is larger than (page_offset + sizeof (Phys memory) + gap), which is a linear address between VMALLOC_START----VMALLOC_END;
Vmalloc uses a vmlist linked list, which is different from vm_area_struct used to manage user processes. The latter will swapped;
4. Reasons for using kmap:
For high-end physical memory (after MB), there is no one-to-one correspondence with the kernel address space (that is, the relationship between virtual address = physical address + page_offset), so get_free_pages () cannot be used () instead, you must use the interface of the partner system algorithm such as alloc_pages () to obtain the struct * Page Structure and map it to the kernel address space.