linux kernel中的virt_to_phys代码解读

假设VA_BITS = 48 (虚拟地址有效位), 那么kernel space的虚拟地址是:0xffff_0000_0000_0000 - 0xffff_ffff_ffff_ffff, userspace的虚拟地址是 0x0000_0000_0000_0000 - 0x0000_ffff_ffff_ffff

然后我们再看一张kernel space memory layout图 ,这张图说明了:
0xffff_8000_0000_0000 - 0xffff_8008_0000_0000 是个memory使用的,就是有映射SDRM的,也是线性一射
而0xffff_8000_0000_0000向下的kernel space virtual addr是给 kernel image使用的
linux kernel中的virt_to_phys代码解读

在kernel中PAGE_OFFSET = 0x8000_0000_0000

#define PAGE_OFFSET		(UL(0xffffffffffffffff) - \
	(UL(1) << (VA_BITS - 1)) + 1)

当virt_to_phys调用时候,先判断bit47(最高有效位),如果为1,则表示是(memory)DRAM的地址。那么直接使用X[46:0]和PHYS_OFFSET相加即可

#define __virt_to_phys(x) ({						\
	phys_addr_t __x = (phys_addr_t)(x);				\
	__x & BIT(VA_BITS - 1) ? (__x & ~PAGE_OFFSET) + PHYS_OFFSET :	\
				 (__x - kimage_voffset); })

PHYS_OFFSET是DRAM的真实物理地址

memstart_addr = round_down(memblock_start_of_DRAM(),
				   ARM64_MEMSTART_ALIGN);

当virt_to_phys调用时候,先判断bit47(最高有效位),如果为0,则表示是kernel image的地址, 那么直接使用X[46:0]和kimage_voffset相减即可

kimage_voffset来自汇编中的__mmap_switched函数

str_l	x21, __fdt_pointer, x5		// Save FDT pointer

ldr_l	x4, kimage_vaddr		// Save the offset between
sub	x4, x4, x24			// the kernel virtual and
str_l	x4, kimage_voffset, x5		// physical mappings
上一篇:virt-p2v工具的使用记录


下一篇:2021-10-24