zoukankan      html  css  js  c++  java
  • 【解答】关于内核中没开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

  • 相关阅读:
    hdu 4970 树状数组 “改段求段”
    hdu 2242 无向图/求用桥一分为二后使俩个bcc点权值和之差最小并输出 /缩点+2次新图dfs
    hdu3715 2-sat+二分
    hdu 3639 有向图缩点+建反向图+搜索
    hdu 3072 有向图缩点成最小树形图计算最小权
    hdu 3061 hdu 3996 最大权闭合图 最后一斩
    hdu 3879 hdu 3917 构造最大权闭合图 俩经典题
    hdu 4738 无向图缩点断桥 // 细节坑题
    hdu3452 无向树去掉最小的边集使任何叶子与根不连通 / 最小割
    hdu 3657 最小割的活用 / 奇偶方格取数类经典题 /最小割
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5183822.html
Copyright © 2011-2022 走看看