operating-system - MMU 是在操作系统和物理内存之间进行调解还是只是一个地址转换器?

标签 operating-system virtual-memory

我试图了解当我们想为特定的虚拟内存地址分配一些值时操作系统是如何工作的。

我的第一个问题涉及 MMU 是否处理 CPU 和 RAM 之间的所有内容。这是真的?从人们可以从维基百科中读到的内容,我会这样说:

A memory management unit (MMU), sometimes called paged memory management unit (PMMU), is a computer hardware component responsible for handling accesses to memory requested by the CPU.



如果是这种情况,例如,如何告诉 MMU 我想要获得 8 个字节、64 个或 128 个字节?写作呢?

如果不是这种情况,我猜 MMU 只是将虚拟地址转换为物理地址?

当 MMU 检测到我们所说的页面错误时会发生什么?我想它必须告诉 CPU 以便 CPU 将页面本身从磁盘加载,或者 MMU 是否能够做到这一点?

谢谢

最佳答案

吞噬极乐世界,

我将尝试一一回答您的问题,但请注意,您最好掌握一本操作系统类(class)或计算机体系结构入门类(class)的教科书。

MMU 由一些硬件逻辑和状态组成,其目的实际上是产生物理地址并向存储器 Controller 提供/从存储器 Controller 接收数据。实际上,内存翻译的工作是通过协作硬件和软件 (OS) 机制(至少在现代 PC 中)来完成的。一旦获得物理地址,CPU 基本上就完成了它的工作,现在将地址发送到总线上,该总线在某个点连接到实际内存芯片。在许多系统中,此总线称为前端总线 (FSB),它依次连接到内存 Controller 。该 Controller 获取 CPU 提供的物理地址,并使用它与 DRAM 芯片交互,并最终提取内存阵列正确行和列中的位。然后将数据发送回 CPU,CPU 现在可以对其进行操作。请注意,我在此描述中不包括缓存。

所以不,MMU 不直接与 RAM 交互,我假设您使用它来表示物理 DRAM 芯片。而且你不能告诉 MMU 你想要 8 个字节,或者 24 个字节,或者其他什么,你只能提供一个地址。获得多少字节取决于您使用的机器以及它是字节寻址还是字寻址。

您的最后一个问题促使我提醒您:MMU 实际上是 CPU 的一部分——它位于同一个硅片上(尽管情况并非总是如此)。

现在,让我们以页面错误为例。假设我们的用户级应用程序想像你说的那样,设置 someAddress = 10,我会分步骤进行。让我们假设 someAddress 是 0xDEADBEEF,让我们暂时忽略缓存。

1) 应用程序向 0xsomeAddress 发出一条存储指令,在 x86 中可能看起来像

mov %eax, 0xDEADBEEF

其中 10 是 eax 寄存器中的值。

2) 0xDEADBEEF 在这种情况下是一个虚拟地址,必须进行转换。大多数情况下,虚拟到物理地址的转换将在称为转换后备缓冲区 (TLB) 的硬件结构中可用,它将非常快速地为我们提供这种转换。通常,它可以在一个时钟周期内完成。如果转换在 TLB 中,称为 TLB 命中,则可以立即继续执行(即,对应于 0xDEADBEEF 的物理地址和值 10 被发送到要写入的内存 Controller )。

3)让我们假设,翻译在 TLB 中不可用(称为 TLB 未命中)。然后我们必须在页表中找到翻译,页表是内存中的结构,其结构由硬件定义并由操作系统管理。它们只包含将虚拟地址映射到物理地址的条目(更准确地说,是将虚拟页码映射到物理页码)。但是这些结构也驻留在内存中,所以必须有地址!硬件包含一个名为 cr3 的特殊寄存器,它包含当前页表的物理地址。我们可以使用我们的虚拟地址对该页表进行索引,因此硬件获取 cr3 中的值,通过添加偏移量计算地址,然后进入内存以获取页表条目 (PTE)。这个 PTE 将(希望)包含对应于 0xDEADBEEF 的物理地址,在这种情况下,我们将此映射放入 TLB(因此我们不必再次遍历页表)并继续我们的方式。

4)但是哦不!如果 0xDEADBEEF 的页表中没有 PTE 怎么办?这是一个页面错误,这就是操作系统发挥作用的地方。我们从页表中得到的 PTE 存在,因为它是(让我们假设)一个有效的内存地址来访问,但是操作系统还没有为它创建一个 VA->PA 映射,所以它会有一些设置表明它是无效的。硬件的编程方式是,当它在访问时看到这个无效位时,它会生成一个异常,在这种情况下是一个页面错误。

5) 异常导致硬件通过跳转到一个众所周知的位置——一段称为处理程序的代码来调用操作系统。可以有许多异常处理程序,页面错误处理程序就是其中之一。页错误处理程序将知道导致错误的地址,因为它存储在某个寄存器中,因此将为我们的虚拟地址 0xDEADBEEF 创建一个新映射。它将通过分配一个空闲的物理内存页面然后说“VA x 和 VA y 之间的所有虚拟地址将映射到这个新分配的物理内存页面内的某个地址”来实现。 0xDEADBEEF 将在该范围内的某处,因此映射现在安全地在页表中,我们可以重新启动导致页面错误(mov)的指令。

6) 现在,当我们再次浏览页表时,我们会找到一个映射,我们拉出的 PTE 将有一个很好的物理地址,我们想要存储到的地址。我们将值 10 提供给内存 Controller ,我们就完成了!

缓存将大大改变这个游戏,但我希望这有助于说明分页是如何工作的。同样,查看一些操作系统/计算机体系结构书籍会让您受益匪浅。我希望这很清楚。

关于operating-system - MMU 是在操作系统和物理内存之间进行调解还是只是一个地址转换器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4812137/

相关文章:

c - C之前用于操作系统开发的语言

multithreading - 程序的工作目录如何/在哪里存储?

operating-system - 如果物理内存的大小是 2^32-1,那么虚拟内存的大小是多少?

Android 清理虚拟内存

caching - PIPT L1 缓存也是 VIPT 的最小关联性,访问集合而不将索引转换为物理

x86 - 英特尔处理器的 TLB ASID 标签中有多少位?以及如何处理 'ASID overflow' ?

operating-system - 使用虚拟内存进行上下文切换?

linux - 如何解决 "Error code: sec_error_invalid_algorithm"?

multithreading - 进程是线程还是线程是进程?

php - 在 PHP 中检索浏览器和操作系统