gpt4 book ai didi

linux - ARM:禁用 MMU 并更新 PC

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:51:37 27 4
gpt4 key购买 nike

简而言之,我想关闭 Linux 上下文(从内核内部)中的所有 MMU(和缓存)操作,用于调试目的,只是为了运行一些测试。明确地说,我不希望我的系统在那之后仍然可以正常工作。

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

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

到目前为止我尝试了什么:

    /* 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 block 之前,我可以点亮一个 LED(3 条汇编指令,没有分支,没有什么花哨的,也没有访问我的 DDR,它已经处于自刷新状态——GPIO 端口的虚拟地址存储在一个寄存器中在那之前)。

在 MMU block 之后,无论我尝试使用物理地址还是虚拟地址,我都无法再尝试。

我认为问题可能与我的 PC 有关,它保留了一个过时的虚拟地址。查看内核其他地方的工作方式,但反过来(即启用翻译):

    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/kernel/sleep.S,cpu_resume_mmu)

我想知道这 2 条指令的延迟与什么有关,以及记录在何处。我在这个问题上一无所获。我尝试过类似的东西,但没有成功:

    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

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

最佳答案

为了解决问题的“这 2 条指令延迟是什么”部分,与/arch/arm 的大部分内容一样,它主要只是遗留下来的废话*

早在任何类型的屏障指令之前的日子里,你必须考虑这样一个事实,即在你切换 MMU 时,管道包含在切换之前已经获取和解码的指令,所以有任何像分支或如果地址空间在它执行时发生了变化,那么那里的内存访问将会出现可怕的错误。 ARMv4 Architecture Reference Manual 做出了精彩的声明“启用和禁用 MMU 的正确代码序列是实现定义的”——实际上,这主要意味着你知道你的管道有 3 个阶段长,所以插入两个 NOP 以安全地填充它.或者 took full advantage of the fact做一些可怕的事情,比如安排直接跳转到翻译后的 VA,而不通过身份映射(哎呀!)。

从有趣的旧微体系结构手册拖网中,3 NOPs are needed for StrongARM (与 3 级 ARM7 流水线的 2 相比),并且读取与结果相关的数据的 CP15 是 XScale 的推荐自同步序列,这解释了对主 ID 寄存器显然毫无意义的读取。

然而,在现代的东西(ARMv6 或更高版本)上,这些都不是必需的,因为你有架构障碍,所以你只需拨动开关然后发出一个 isb 来刷新管道,这是在为此类架构构建时,instr_sync 宏扩展到什么。

* 或者 Linux“适用于一切”方法的一个很好的例子,取决于你的观点......

关于linux - ARM:禁用 MMU 并更新 PC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30843270/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com