开启 MMU 的逻辑和物理地址?
Posted
技术标签:
【中文标题】开启 MMU 的逻辑和物理地址?【英文标题】:Logical and physical address with MMU on? 【发布时间】:2017-08-21 14:17:36 【问题描述】:我对 MMU 如何处理内核物理和逻辑地址有一些疑问。我会试着用一个例子来解释我的问题。 让我们假设我们在 ARM 架构上。
系统在 MMU 关闭的情况下启动,因此在 CPU 内部传递的所有地址都是物理地址。在我们启用 MMU 之前,我们创建一个页表,其中我们说我们所有的物理地址都映射到虚拟地址 physical address + 0xC0000000
。在此之后,我们打开 MMU。这一切都很清楚。但现在问题开始了:
由于我们处于流水线架构中,假设后面的指令是从地址 0x8000 加载的。现在据我所知,我们应该有一个页面错误,因为 MMU 在页表中的任何地方都找不到这个地址,所以它调用了一个页面错误来处理这种情况。但是如果我们设置了中断向量,在它里面会有一个分支到另一个物理地址,所以 MMU 找不到这个地址,我们不可避免地陷入了一个无限循环。我错过了什么?
【问题讨论】:
【参考方案1】:您错过了应该映射所有使用的虚拟地址,即使它们实际上匹配相同的物理内存区域。让我们详细说明。
假设有 startup
代码(用于主要初始化和启用 MMU)和其他 main
代码(仅适用于启用 MMU)具有以下布局。
这样的布局是链接器的工作,你的工作是用正确的脚本来提供它。此示例中的 CPU 入口点应该是 0x4000
。这几乎是一个特定于硬件的地址。
CPU 从禁用 MMU 和“PC=0x4000”开始,直到启用 MMU 时说0x4800
。
所以在启用 MMU 之前,必须有 0x4000-0x7FFFF
(启动)和 0xC0008000-0xC000BFFF
(所有其他代码)的映射。
现在 MMU 已启用。 PC 有 0x4804(假设 32b CPU)。 0x4804
现在是一个虚拟地址,它映射到0x4804
物理地址。 CPU 继续使用0x4804
、0x4808
、0x480C
等。
在某些时候你应该跳转到main
。对于 ARM,类似于
ldr r0, =0xC0008000
bx r0
注意,使用main
条目的虚拟地址。所以在将PC=0xC0008000
分支后解析为物理内存中的0x8000
。
0x4000-0x7FFFF
映射之后可以删除。
【讨论】:
以上是关于开启 MMU 的逻辑和物理地址?的主要内容,如果未能解决你的问题,请参考以下文章