首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ARM:禁用MMU和更新PC

ARM:禁用MMU和更新PC
EN

Stack Overflow用户
提问于 2015-06-15 10:49:28
回答 1查看 2.2K关注 0票数 2

简而言之,为了调试的目的,我想关闭Linux上下文中的所有MMU (和缓存)操作,只为了运行一些测试。要非常清楚的是,我不打算在那之后我的系统还能正常工作。

关于我的设置:我目前正在摆弄一个飞思卡尔Vybrid (VF610),它集成了一个A5和它的低功耗模式。由于我正在试验一些可疑的本地内存损坏,而芯片处于“低功耗停止”模式,而我的DDR3处于自刷新状态,因此我试图一点一点地改变操作,现在执行所有挂起/恢复步骤,而不实际执行WFI。因为在此指令之前,我运行地址转换,在没有地址转换(本质上是重置)的情况下,我想通过“手动”关闭MMU来“模拟”。

(我目前没有JTAG或对我的芯片的任何其他调试访问权限。我通过MMC/TFTP/NFS加载它,并使用LED调试它。)

到目前为止我尝试过的是:

代码语言:javascript
运行
复制
    /* disable the Icache, Dcache and branch prediction */
    mrc     p15, 0, r6, c1, c0, 0
    ldr r7, =0x1804
    bic r6, r6, r7
    mcr     p15, 0, r6, c1, c0, 0
    isb

    /* disable the MMU and TEX */
    bic r7, r6, r7
    isb
    mcr p15, 0, r6, c1, c0, 0   @ turn on MMU, I-cache, etc
    mrc p15, 0, r6, c0, c0, 0   @ read id reg
    isb
    dsb
    dmb

以及其他同样效果的变体。

我观察到:

在MMU块之前,我可以点亮一个LED (3个组装指令,没有分支,没什么花哨,也不需要访问我的DDR,它已经在自我刷新-- GPIO端口的虚拟地址在此之前存储在寄存器中)。

在MMU块之后,无论我尝试物理地址还是虚拟地址,我都不能再使用了。

我认为这个问题可能与我的个人电脑有关,它保留了一个过时的虚拟地址。查看内核的其他部分是如何完成的,但反过来(即,在启用翻译的同时):

代码语言:javascript
运行
复制
    ldr r3, =cpu_resume_after_mmu

    instr_sync
    mcr p15, 0, r0, c1, c0, 0   @ turn on MMU, I-cache, etc
    mrc p15, 0, r0, c0, c0, 0   @ read id reg
    instr_sync

    mov r0, r0
    mov r0, r0
    ret r3          @ jump to virtual address
ENDPROC(cpu_resume_mmu)
    .popsection
cpu_resume_after_mmu:

(来自arch/arm/内核/睡眠.S,cpu_resume_mmu)

我不知道这2条指令延迟与什么相关,以及它在哪里被记录下来。我在这个问题上什么也没有发现。我尝试过类似的东西,但没有成功:

代码语言:javascript
运行
复制
    adr lr, BSYM(phys_block)

    /* disable the Icache, Dcache and branch prediction */
    mrc     p15, 0, r6, c1, c0, 0
    ldr r7, =0x1804
    bic r6, r6, r7
    mcr     p15, 0, r6, c1, c0, 0
    isb

    /* disable the MMU and TEX */
    bic r7, r6, r7
    isb
    mcr p15, 0, r6, c1, c0, 0   @ turn on MMU, I-cache, etc
    mrc p15, 0, r6, c0, c0, 0   @ read id reg
    isb
    dsb
    msb

    mov r0, r0
    mov r0, r0
    ret lr

phys_block:
    blue_light
    loop

感谢任何有线索或指点的人!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-16 13:15:39

由于杰森和德韦尔奇都通过评论(每个人)提出了我所需要的答案,为了清楚起见,我将在这里回答我自己的问题:

诀窍是简单地添加一个身份映射从/到执行转换的页面,允许我们跳到它与一个“物理”(实际上是虚拟的) PC,然后禁用MMU。

下面是最后的代码(有点具体,但有注释):

代码语言:javascript
运行
复制
    /* Duplicate mapping to here */

    mrc p15, 0, r4, c2, c0, 0 // Get TTRB0
    ldr r10, =0x00003fff
    bic r4, r10 // Extract page table physical base address
    orr r4, #0xc0000000 // Nastily "translate" it to the virtual one

    /*
     * Here r8 holds vf_suspend's physical address. I had no way of
     * doing this more "locally", since both physical and virtual
     * space for my code are runtime-allocated.
     */

    add lr, r8, #(phys_block-vf_suspend) // -> phys_block physical address 

    lsr r9, lr, #20 // SECTION_SHIFT     -> Page index
    add r7, r4, r9, lsl #2 // PMD_ORDER  -> Entry address
    ldr r10, =0x00000c0e // Flags
    orr r9, r10, r9, lsl #20 // SECTION_SHIFT   -> Entry value
    str r9, [r7] // Write entry

    ret lr  // Jump / transition to virtual addressing

phys_block:
    /* disable the MMU and TEX */
    isb
    mrc     p15, 0, r6, c1, c0, 0
    ldr r7, =0x10000001
    bic r6, r6, r7
    mcr p15, 0, r6, c1, c0, 0   @ turn on MMU, I-cache, etc
    mrc p15, 0, r6, c0, c0, 0   @ read id reg
    isb
    dsb
    dmb

    /* disable the Icache, Dcache and branch prediction */
    mrc     p15, 0, r6, c1, c0, 0
    ldr r7, =0x1804
    bic r6, r6, r7
    mcr     p15, 0, r6, c1, c0, 0
    isb

    // Done !
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30843270

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档