所以,基本上,我想在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)然后,立即跳转到新地址< / strong>,这将在新地图中有效。这在早期架构中是可能的,因为从旧地址获取了启用MMU或更改状态的指令之后的至少4条指令。理想情况下,我希望能够做到这一点,而不依赖于令人难以置信的丑陋黑客,每次你想要切换页面表或打开MMU时都必须创建一个身份映射。
为了澄清我在讨论旧架构时的意思,这里是ARM信息中心页面的链接,解释了如何在ARM720T上打开MMU:7.16.1. Enabling the MMU
答案 0 :(得分:3)
简短的回答是,没有办法完全按照你在ARMv7-A中提出的要求。 ARM720T示例是一个极其微架构特定的黑客,并且永远无法保证在不同处理器之间可移植。
对于ARMv7-A没有可移植的方法不使用身份映射来打开/关闭MMU,但是更新转换表是这样的: 您可以做什么(在ARM720T中不可用)是使用TTBR1 / TTBR0的组合来保存您的描述符。 TTBCR中的N字段配置覆盖TTBR1的TTBR0表的大小。这样,只要您的TTB切换代码位于通过与您正在更新的TTBR不同的TTBR描述的区域中,就不存在地图冲突。
另一种选择是重写TTBR0描述的转换表而不是切换。