MMU 是在 Unix/Linux 内核内部吗?或者只是在有自己的内存的硬件设备中?

MMU 是在 Unix/Linux 内核内部吗?或者只是在有自己的内存的硬件设备中?

所以我一直认为 MMU 是 Unix 内核的一部分,它将地址转换为物理地址,但在 MMU wiki 页面中,它说它是一个通常有自己的内存的计算机硬件,但该页面并没有过多谈论 Unix/Linux 操作系统

所以我很困惑,所有翻译都发生在硬件中而内核不做任何翻译吗?基本上操作系统对真实的物理地址一无所知?

我问的是基于 Unix 的操作系统,但如果您也了解其他操作系统(例如 Windows),或者它是否在现代计算机中很常见,请告诉我,谢谢。

答案1

MMU(内存管理单元)是计算机系统的物理组件,通常是 CPU 的一部分(但不一定)。它将虚拟地址(在 x86 世界中也称为线性地址)转换为物理地址;它还可以强制执行内存访问控制、高速缓存控制和总线仲裁。它通常没有自己的内存,它依赖系统主存中的数据来操作。

MMU 通过使用存储在数据结构(例如页表)中的信息来执行此转换;这些指定哪些物理地址范围对应于线性地址范围(如果有的话——页面可以“不存在”)。页表由内核设置,内核决定映射应该是什么——因此物理地址的最终权力是内核,但它总是在 MMU 的帮助下运行。换句话说,CPU 始终在线性地址上运行,这些地址由 MMU 转换为物理地址,但内核知道这些转换并对 MMU 进行编程来执行它们。

用户空间进程对所有这些都一无所知,并且(通常)不知道它们使用的线性地址对应的物理地址,并且通常也无法访问映射。在某些情况下,物理映射会泄露,但这些通常被视为安全漏洞并很快得到解决。然而,在 Linux 中,具有足够权限的进程可以在中查看其物理映射/proc/<pid>/pagemap

具体针对 Linux,请参阅内存管理文档,特别是检查页表的部分

答案2

内存管理单元 (MMU) 是将虚拟地址转换为物理地址的硬件。例如,当 CPU 发出要读取的地址时,MMU 将该虚拟地址转换为物理地址,然后将该物理地址发送到内存总线。

MMU 由操作系统编程。操作系统管理内存(物理和虚拟)并管理虚拟到物理的映射。

答案3

决定写一个答案,因为我正在确切地搜索从物理到虚拟的转换是在哪里完成的:

让我留下 Linus 原始帖子的链接: 翻译内核空间中的地址 这样就可以找到这个文件了

#include <asm/io.h>

不在 mm 文件夹中,这是我最初预期的,原因是架构之间的差异太宽,因此每个架构都有更多差异来将所有内容嵌入 mm 文件夹中。

因此,请查看 arch/x86/include/asm/io.h 文件,特别是 virt_to_phys https://codebrowser.dev/linux/linux/arch/x86/include/asm/io.h.html#virt_to_phys

根据 Linus 在 x86 中的评论,一切都更简单,因为总线地址是相同的虚拟地址,总线地址和虚拟地址之间的区别在于总线地址是非 CPU 设备如何看待内存布局。

再次因为在 x86 中它更简单并且两个术语(总线地址和虚拟地址)可以互换使用

下面的定义可以证明我的话

#define isa_bus_to_virt     phys_to_virt

假设isa/pci是外部(非CPU)设备。

如果我们详细说明一下,我们可以在文件 linux/arch/powerpc/mm/ioremap_32.c 中看到,该文件与其他体系结构(PowerPC)相关,其中 ISA 设备的内存布局不同

https://codebrowser.dev/linux/linux/arch/powerpc/mm/ioremap_32.c.html

并且可以在函数中看到

__ioremap_caller 

这样的评论:

/*
* If the address lies within the first 16 MB, assume it's in ISA
* memory space
*/
if (p < 16 * 1024 * 1024)
    p += _ISA_MEM_BASE;

这实际上证实了 Linus 的说法,即考虑到总线地址和虚拟地址不同,PowerPC 的布局略有不同。

相关内容