所以,基本上,我想在 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 立即开始从虚拟地址获取。因此,如果引导加载程序在 at 运行0x10000000
然后启用 MMU,除非它首先进入标识映射,否则下一次提取 at0x10000004
将导致预取中止。现在,我知道可以在 MMU 的初始启用期间使用身份映射来执行此操作。但是,在切换翻译表(将新值加载到 中)时也会出现同样的问题TTBR0
。
所以,本质上,我正在寻找一种或多或少直接的方式来加载一个新值TTBR0
(或者只是打开 MMU),然后立即跳转到一个新地址,这将在新地图中有效。这在早期架构上是可能的,因为在启用 MMU 或更改状态的指令之后至少有 4 条指令是从旧地址获取的。理想情况下,我希望能够做到这一点,而无需依赖极其丑陋的 hack,每次您想要切换页表或打开 MMU 时都必须创建一个身份映射。
为了澄清我在谈论旧架构时的意思,这里有一个指向 ARM 信息中心页面的链接,该页面解释了如何在 ARM720T 上打开 MMU:7.16.1。启用 MMU