【解答】关于内核中没开MMU之前的虚拟地址物理地址转换问题
2014-10-03 17:02
411 查看
1. 内核没开MMU之前有虚拟地址吗?没有MMU哪来的虚拟地址?
答:有,因为加载时地址和运行时地址不同导致的没打开MMU之前也会有虚实地址问题。
2. 加载时地址和运行时地址什么区别,为什么有这种区别?
答:加载时地址:把可执行文件放到物理内存的内存地址,例如把镜像放到0x80000000地址处,则加载时地址=0x80000000
运行时地址:镜像生成后的虚拟地址,由编译器和连接脚本决定。
内核镜像放到内存中时,放置的地址是任意的,所以要考虑到这种情况,在没打开mmu之前使用内存中的数据都要计算偏移
以下代码是ARMv8linux内核的head.S节选,可以很好的说明没开MMU之前的虚实地址转换问题:
ENTRY(lookup_processor_type)
adr x1, __lookup_processor_type_data //x1= 当前PC的值 + 与标号__lookup_processor_type_data之间的偏移量,即x1存储的是相对于当前PC的 __lookup_processor_type_data地址值,这里的pc是物理地址。在开了mmu之后,所有的pc都是虚拟地址。
ldp x2, x3, [x1] //把下面__lookup_processor_type_data标号中“.”存到x2,cpu_table存到x3,x2,x3里存储的都是虚拟地址
sub x1, x1, x2 // get offset between VA and PA,这里有歧义,x1是物理地址,x2是虚拟地址,所以这里是PA-VA,不是VA-PA
add x3, x3, x1 // convert VA to PA,这里x3是VA,加上PA-VA得出x3的PA
1:
ldp w5, w6, [x3] // load cpu_id_val and cpu_id_mask
cbz w5, 2f // end of list?
and w6, w6, w0
cmp w5, w6
b.eq 3f
add x3, x3, #CPU_INFO_SZ
b 1b
2:
mov x3, #0 // unknown processor
3:
mov x0, x3
ret
ENDPROC(lookup_processor_type)
.align 4
.type __lookup_processor_type_data, %object
__lookup_processor_type_data:
.quad . //"."代表当前虚拟地址,上面adr那条指令计算的x1是当前这条指令的物理地址,ldp那条指令中的x2是虚拟地址,所以sub计算出来的是PA-VA
.quad cpu_table
答:有,因为加载时地址和运行时地址不同导致的没打开MMU之前也会有虚实地址问题。
2. 加载时地址和运行时地址什么区别,为什么有这种区别?
答:加载时地址:把可执行文件放到物理内存的内存地址,例如把镜像放到0x80000000地址处,则加载时地址=0x80000000
运行时地址:镜像生成后的虚拟地址,由编译器和连接脚本决定。
内核镜像放到内存中时,放置的地址是任意的,所以要考虑到这种情况,在没打开mmu之前使用内存中的数据都要计算偏移
以下代码是ARMv8linux内核的head.S节选,可以很好的说明没开MMU之前的虚实地址转换问题:
ENTRY(lookup_processor_type)
adr x1, __lookup_processor_type_data //x1= 当前PC的值 + 与标号__lookup_processor_type_data之间的偏移量,即x1存储的是相对于当前PC的 __lookup_processor_type_data地址值,这里的pc是物理地址。在开了mmu之后,所有的pc都是虚拟地址。
ldp x2, x3, [x1] //把下面__lookup_processor_type_data标号中“.”存到x2,cpu_table存到x3,x2,x3里存储的都是虚拟地址
sub x1, x1, x2 // get offset between VA and PA,这里有歧义,x1是物理地址,x2是虚拟地址,所以这里是PA-VA,不是VA-PA
add x3, x3, x1 // convert VA to PA,这里x3是VA,加上PA-VA得出x3的PA
1:
ldp w5, w6, [x3] // load cpu_id_val and cpu_id_mask
cbz w5, 2f // end of list?
and w6, w6, w0
cmp w5, w6
b.eq 3f
add x3, x3, #CPU_INFO_SZ
b 1b
2:
mov x3, #0 // unknown processor
3:
mov x0, x3
ret
ENDPROC(lookup_processor_type)
.align 4
.type __lookup_processor_type_data, %object
__lookup_processor_type_data:
.quad . //"."代表当前虚拟地址,上面adr那条指令计算的x1是当前这条指令的物理地址,ldp那条指令中的x2是虚拟地址,所以sub计算出来的是PA-VA
.quad cpu_table
相关文章推荐
- 【解答】关于内核中没开MMU之前的虚拟地址物理地址转换问题
- 【解答】关于内核中没开MMU之前的虚拟地址物理地址转换问题
- 【解答】关于内核中没开MMU之前的虚拟地址物理地址转换问题
- 关于在Windows Server2003上面配置虚拟目录物理路径为局域网内其他机器地址的若干问题
- Linux 内核虚拟地址到物理地址转换讨论
- ARM Android内核虚拟地址到物理地址的转换实例 (ARM Android kernel virtual address to physical address)
- 关于JOS 未对全部内存分页映射之前 物理地址映射问题的思考
- Linux 内核空间虚拟地址和物理地址相互转换
- MMU内存管理单元(1)-虚拟地址到物理地址转换
- 关于JOS 未对所有内存分页映射之前 物理地址映射问题的思考
- Linux 内核 虚拟地址 物理地址 转换
- 外设IO地址空间中的地址怎么转换到内核态的虚拟地址空间(一个ioremap函数真的解释清楚了么)
- 将虚拟地址转换成物理地址
- 关于数据如何从物理虚拟地址转到文件虚拟地址
- 用户虚拟地址转换成物理地址
- 关于线性地址到物理地址的转换缓冲
- 虚拟地址转换成物理地址
- (转)WINCE物理和虚拟地址的问题
- 关于 bootloader 里的物理地址到虚拟地址的影射
- 物理地址和虚拟地址1 (MMU)