所以我一直认为 MMU 是 Unix 内核的一部分,它将地址转换为物理地址,但在 MMU wiki 页面中,它说它是一个通常有自己的内存的计算机硬件,但该页面并没有过多谈论 Unix/Linux 操作系统
所以我很困惑,所有翻译都发生在硬件中而内核不做任何翻译吗?基本上操作系统对真实的物理地址一无所知?
我问的是基于 Unix 的操作系统,但如果您也了解其他操作系统(例如 Windows),或者它是否在现代计算机中很常见,请告诉我,谢谢。
答案1
MMU(内存管理单元)是计算机系统的物理组件,通常是 CPU 的一部分(但不一定)。它将虚拟地址(在 x86 世界中也称为线性地址)转换为物理地址;它还可以强制执行内存访问控制、高速缓存控制和总线仲裁。它通常没有自己的内存,它依赖系统主存中的数据来操作。
MMU 通过使用存储在数据结构(例如页表)中的信息来执行此转换;这些指定哪些物理地址范围对应于线性地址范围(如果有的话——页面可以“不存在”)。页表由内核设置,内核决定映射应该是什么——因此物理地址的最终权力是内核,但它总是在 MMU 的帮助下运行。换句话说,CPU 始终在线性地址上运行,这些地址由 MMU 转换为物理地址,但内核知道这些转换并对 MMU 进行编程来执行它们。
用户空间进程对所有这些都一无所知,并且(通常)不知道它们使用的线性地址对应的物理地址,并且通常也无法访问映射。在某些情况下,物理映射会泄露,但这些通常被视为安全漏洞并很快得到解决。然而,在 Linux 中,具有足够权限的进程可以在中查看其物理映射/proc/<pid>/pagemap
。
答案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 的布局略有不同。