__calc_phys_offset
/*
* Calculate the start of physical memory.
*/
__calc_phys_offset:
adr x0, 1f
ldp x1, x2, [x0]
sub x28, x0, x1 // x28 = PHYS_OFFSET - PAGE_OFFSET
add x24, x2, x28 // x24 = PHYS_OFFSET
ret
ENDPROC(__calc_phys_offset)
.align 3
1: .quad .
.quad PAGE_OFFSET
1.adr x0,1f // ldr加载当前pc值加上当前物理地址到1标签处的偏移,假设当前PC为0x10000000(物理地址),此处代码的虚拟地址为0xc000a000,1f标签处的虚拟地址为0xc000a000a,那么此时adr指令执行后,x0的值为 0x10000000 + 0xa = 0x1000000a,即此时1f标签处的物理地址
2.ldp为位置无关的指令,执行 ldp x1,x2,[x0],将加载1标签处的值,x1 = . 即1标签处的虚拟地址,System.map中的地址,x2 = PAGE_OFFSET
x0 为标签1处的物理地址
x1 为标签1处的虚拟地址
因为线性映射中:va = pa - pa_offset + PAGE_OFFSET
所以有 x28 = x0 - x1 = pa -va = pa_offset - PAGE_OFFSET = pa_offset - x2
所以PA_OFFSET = x28 + x2,将此值赋给x24,
即x24为PHYS_OFFSET