On 32bit machines, due to the limitations of 32bit address space, the maximum addressing range is 2 ^ 32-1, that is, 4G linear address space, 2G/2g, 1g/3G allocation method, divide the 4G address space into two parts
The so-called 3g/1G is 3G application space 1g kernel space, 2g/2G is 2G application address space 2G kernel address space.
Here we only consider 3g/1g, that is, only 1g of kernel space. The Linux kernel further divides the 1 GB kernel address space,
1. the first section of space starting from page_offset is the linear Ram ing space of physical Ram. The size of this section is fixed to 896 Mb on the x86 machine, and for 2g/2G arm machines, this linear ing space may exceed 1 GB. The physical addresses that can be directly mapped to this linear space are DMA zone and normal zone, and the physical memory outside this range is divided into high memory zone.
2. the kernel maintains a secure zone between page_offset and vmalloc_start to capture out-of-bounds memory.
3. The vmalloc_start space to vmalloc_end is a non-contiguous memory zone, which is used by vmalloc and vfree. The non-contiguous memory zone can provide the logical address continuous for the kernel but the physical address is not necessarily consecutive in the memory zone. The non-continuous memory zone can be mapped to the normal zone or the physical memory of the high memory zone. When the kernel thread needs a large block of memory but does not need the corresponding physical memory to be continuous, you can use vmalloc for allocation. Because vmalloc only allocates a segment of address space without actually allocating physical memory, the size of the allocated space can be larger than the physical memory size.
When the physical memory of the system is large, some physical memory cannot be linearly mapped. These unmapped physical memory are called high memory, and the corresponding low-end physical memory that can be mapped is called low memory.
Page boxes in high-end memory without linear addresses cannot be accessed by the kernel. A part of linear address space is dedicated to the ing of high-end physical memory. Of course, this ing is temporary. Otherwise, only some high-end physical memory can be mapped.
The kernel can map high-end physical memory using three different mechanisms: Permanent kernel ing, fixed ing (temporary kernel ing is a special form of fixed ing), and non-continuous memory allocation.
Non-continuous memory allocation
Non-contiguous memory areas can be mapped to high-end memory or low-end memory. It makes sense to use a continuous linear address to access non-consecutive page frames, because this pattern avoids external fragments, the existence of external fragments will make the system not have a large enough continuous page box.
Linux uses discontinuous memory allocation in several aspects:
1. Allocate a data structure for the active SWAp Zone
2. Allocate space for Modules
3. You can also allocate a buffer to some I/O drivers that do not require continuous physical page boxes.
Permanent kernel ingPersistent kernel Map
Allows the kernel to establish a long-term ing between a high-end page box and the kernel address space. They use a dedicated page table in the main and page tables, and the address is stored in pkmap_page_table. The size of the page table is 512 or 1024, depending on whether the PAE is activated. When the PAE is not activated, the page table items occupy 4 bytes, so that a page table can store 1024 page table items, if PAE is activated, the page table entry occupies 8 bytes. This page table can only store 512 items. Therefore, the kernel can only access up to 2 m or 4 m of high-end memory at a time.
Fixed kernel ing
The linear address of fixed kernel ing is similar to 0xffffc000. fixed kernel ing linear address to physical address conversion is not like Kernel linear ing space directly minus 0xc0000000, but can be established in any way. that is to say, the linear address of the fixed ing can correspond to any physical address.
The linear address of each fixed ing corresponds to an integer index value, which is defined
enum fixed_addresses {#ifdef CONFIG_X86_32 FIX_HOLE, FIX_VDSO,#else VSYSCALL_LAST_PAGE, VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE + ((VSYSCALL_END-VSYSCALL_START) >> PAGE_SHIFT) - 1, VSYSCALL_HPET,#endif#ifdef CONFIG_X86_32 FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,#endif __end_of_fixed_addresses};
Fix_to_virt function compute the linear address of a constant corresponding to a given Index
static inline unsigned long fix_to_virt(const unsigned int idx){ if (idx >= FIX_KMAP_END) __this_fixmap_does_not_exist(); return __fix_to_virt(idx);}
To associate a fixed address with a physical ing linear address, the kernel uses set_fixmap (idx, Phys) and set_fixmap_nocache
Temporary kernel ing
Temporary kernel ing is a special form of fixed address kernel ing that can be used inside interrupt handlers and deletable functions because they do not block the current process.
Any page box in the high-end memory can be mapped to the kernel address space through a window.
Each CPU has its own set of windows. For specific definitions of each window, see km_type. Each symbol in the data structure, which identifies a window and corresponds to a fixed kernel address.
Fix_to_virt obtains the Kernel linear address from this symbol (index. Remember that each symbol has a specific meaning. Only one kernel component can be used, so it ensures that the temporary kernel ing can be non-blocking.