启用 ARMv7 VMSA 内存管理单元?

Posted

技术标签:

【中文标题】启用 ARMv7 VMSA 内存管理单元?【英文标题】:Enabling the ARMv7 VMSA memory management unit? 【发布时间】:2012-12-02 12:59:25 【问题描述】:

所以,基本上,我想在 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)然后,立即跳转到新地址,这将在新地图中有效。这在早期架构上是可能的,因为在启用 MMU 或更改状态的指令之后至少有 4 条指令是从旧地址获取的。理想情况下,我希望能够做到这一点,而无需依赖极其丑陋的 hack,每次您想要切换页表或打开 MMU 时都必须创建一个身份映射。

为了澄清我在谈论旧架构时的意思,这里有一个指向 ARM 信息中心页面的链接,该页面解释了如何在 ARM720T 上打开 MMU:7.16.1. Enabling the MMU

【问题讨论】:

我不知道您为什么将身份映射描述为丑陋的 hack,它是启用 MMU 的体系结构指定的方法,并且相当容易实现。 @VariableLengthCoder 好吧,最初启用 MMU 并没有那么糟糕。但是在映射之间切换很烦人,因为它需要在每个映射中都有一个具有相同 VA 的页面。 【参考方案1】:

简短的回答是,没有办法完全按照您在 ARMv7-A 中的要求进行操作。 ARM720T 示例是一个极其微架构特定的 hack,永远无法保证在不同处理器之间可移植。

对于 ARMv7-A 没有可移植的方式不使用身份映射来打开/关闭 MMU,但对于更新转换表: 您可以做的(在 ARM720T 中不可用)是使用 TTBR1/TTBR0 的组合来保存您的描述符。 TTBCR 中的 N 字段配置覆盖 TTBR1 的 TTBR0 表的大小。这样一来,只要您的 TTB 切换代码位于通过与您正在更新的不同的 TTBR 描述的区域中,就不会出现地图冲突。

另一种选择是重写 TTBR0 描述的转换表,而不是切换。

【讨论】:

以上是关于启用 ARMv7 VMSA 内存管理单元?的主要内容,如果未能解决你的问题,请参考以下文章

MMU

使用自动内存管理

操作系统 内存管理单元MMU TLB

操作系统 内存管理单元MMU TLB

操作系统 内存管理单元MMU TLB

内存管理单元MMU学习