关mmu运行linux内核,【解答】关于内核中没开MMU之前的虚拟地址物理地址转换问题...

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值