There are two types of virtual addresses that the Linux kernel uses:
- What you already mentioned in the line "The core of memory (virtual) directly corresponds to physical memory (only an offset from 0xC000_0000 will give us a physical address). This displays the adjacent physical addresses.
- Using vmalloc.
The first is done using MACRO:
include/asm-x86/page_32.h #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
_pa (x) performs virtual and physical translation. Please note that this translation occurs at compile time. Translation of the spreadsheet page does not occur. The last sentence is very important.
On the other hand, using the second method, you can allocate memory that is contiguous in virtual memory, but may not be so in physical memory. Now, in this case, the first access to the virtual address requires a full translation of the page table. The question is, who does this?
In the case of CISC machines (for example, x86), the MMU (hardware) does this in case of missing TLB (first access to the virtual address) and updates the page table. For virtual kernel addresses (obtained through vmalloc), they are saved as TLB entries. They are called global records, and when the process context switches, they are mostly ignored and not reddened like the rest of the process address records. However, when you do vfree to free the associated virtual memory, these entries are deleted.
In the case of a RISC machine (for example, MIPS), the translation of the page is processed by the software. After skipping TLB, the hardware throws an exception. The descriptor trap runs in kernel mode to translate and update TLBs using special instructions. After returning from the trap handler, the same line of code is executed and TLB crashes.
Refer to: http://pages.cs.wisc.edu/~remzi/OSFEP/vm-tlbs.pdf
The bottom line is that not all kernel addresses are mapped as you described. For your case, physical addresses are generated at compile time. So why add a TLB entry. For addresses from vmalloc there are TLB entries. When a context switch occurs between processes, the entire TLB does not need to be cleared, and the global entries made by the vmalloc core can be saved. When you use vfree, the corresponding global entries are cleared.