所以,基本上,我想在 ARMv7 内核上启用内存管理单元。实际过程非常简单。我只需要将转换表的地址加载到 TTBR0
中并使用控制寄存器启用 MMU。
/* enable mmu */
mcr p15, 0, r0, c2, c0, 0
mrc p15, 0, r12, c1, c0, 0
orr r12, r12, #0x1
mcr p15, 0, r12, c1, c0, 0
现在,一旦启用 MMU,问题就会出现,因为在 ARMv7 上(与 ARM 架构的其他一些版本不同),CPU 立即开始从虚拟地址中获取。因此,如果引导加载程序在
0x10000000
上运行然后启用 MMU,除非它首先进入身份映射,否则在 0x10000004
处的下一次提取将导致预取中止。现在,我知道可以在 MMU 的初始启用期间使用身份映射来做到这一点。但是,在切换转换表(将新值加载到 TTBR0
中)时也会出现同样的问题。因此,本质上,我正在寻找一种或多或少直接的方法将新值加载到
TTBR0
(或只是打开 MMU),然后 立即跳转到新地址 ,这将在新 map 中有效.这在早期架构中是可能的,因为在启用 MMU 或更改状态的指令之后至少有 4 条指令是从旧地址获取的。理想情况下,我希望能够在不依赖令人难以置信的丑陋黑客的情况下做到这一点,每次要切换页表或打开 MMU 时都必须创建身份映射。为了澄清我在谈论旧架构时的意思,这里是 ARM 信息中心页面的链接,解释了如何在 ARM720T 上打开 MMU:7.16.1. Enabling the MMU
最佳答案
简短的回答是,无法完全按照您在 ARMv7-A 中的要求进行操作。
ARM720T 示例是一个极其特定于微体系结构的黑客,永远无法保证在不同处理器之间可移植。
对于 ARMv7-A 没有不使用标识映射来打开/关闭 MMU 的可移植方式,但对于更新转换表:
您可以做的(在 ARM720T 中不可用)是使用 TTBR1/TTBR0 的组合来保存您的描述符。 TTBCR 中的 N 字段配置覆盖 TTBR1 表的 TTBR0 表的大小。这样,只要您的 TTB 切换代码位于通过与您正在更新的 TTBR 不同的 TTBR 描述的区域中,就不会有映射冲突。
另一种选择是重写 TTBR0 描述的转换表而不是切换。
关于memory - 启用 ARMv7 VMSA 内存管理单元?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13669498/