我想知道当需要在地址空间中维护一些“固定”地址时,如何将虚拟内存系统与 MMU 一起管理。
例如,当机器启动时,CPU 开始从固定地址(映射到某种 ROM)读取第一条指令,然后为外围设备提供地址(如果使用内存映射 I/O 系统),然后然后操作系统被引导。我还知道中断例程和此类内容需要位于内存中的“固定”位置,并且这些内容由操作系统加载。
我可能认为MMU在这样的过程中被禁用,然后在操作系统加载后启用它。
我可能认为上面的进程使用系统地址空间,并且系统地址空间没有虚拟化,尽管用户地址空间实际上是虚拟化的。
这将导致物理地址池保持不变,以便访问 I/O 外设、中断例程等,以及由 MMU 管理的虚拟用户空间,进程可以在其中详细说明它们需要详细说明的所有数据,要求操作系统访问 I/O 外设。
但我不确定这些事情。那么我问你,MMU什么时候才真正启用呢?它处理所有地址,还是只处理用户空间的地址?即使系统正在运行,某些地址是否也可以绕过 MMU,以访问固定的内存位置?或者我错过了一些重要的线索?
抱歉,所选答案中的猜测具有误导性,并且遗漏了最重要的方面,即通过页表进行地址转换。
确实,当任何 PC 兼容机器启动时,它都会以“实模式”启动。x86 上的现代 32 位操作系统确实在“保护模式”下运行,其中包括 GDT 定义的分段寻址。然而,它们随后还通过设置 CR0 中的 PG(分页)位(第 31 位)来启用基于页表的地址转换。这在操作系统的生命周期中永远不会关闭。
此外,在大多数现代 32 位操作系统中,基于 GDT 的分段寻址基本上被绕过:所有常用的 GDTE 均使用基地址 0 进行设置,大小为 40 亿字节。因此,尽管 MMU 确实执行了将相关段“基地址”添加到来自指令的“位移”的动作,但这实际上是一个无操作。环 0 与环 3 使用不同的 GDTE 集,但它们都具有相同的基地址和大小。“权限级别”字段(0 与 3)是关于所有不同之处。这使得页表条目中的“特权访问”位有效,从而允许逐页保护内存以进行内核模式或用户+内核模式访问。对于段描述符来说这是不可能的;它们的粒度太粗了。
在 x64 CPU 中,在长模式下分段机制基本上消失了。当然,只要设置了 PG 位,基于页表的地址转换仍然会发生,这在操作系统的整个生命周期中都是如此。最重要的是,在内核模式下,MMU 不会被禁用,“SO”(或任何东西)也不会在虚拟地址和物理地址之间使用 1:1 映射。
对已知物理地址的访问(如分配给类 PCI 外设的物理地址)是通过分配未使用的虚拟地址并使用所需的物理页号设置相应的页表条目来完成的。然后设备驱动程序中的代码使用虚拟地址。
是的,DMA 主要作用于物理地址。哑/便宜的 DMA 控制器实际上只是传输到具有给定起始地址和长度的物理连续缓冲区。为了支持此类设备,操作系统或设备驱动程序将分配物理上连续的“反弹缓冲区”供 DMA 设备访问,并在缓冲区和用户缓冲区之间复制数据。
智能/更昂贵的 DMA 控制器可以处理占用不连续物理地址范围的缓冲区(称为“分散-聚集映射”)。这些是高性能设备的首选。
IOMMU 可以允许愚蠢/廉价的 DMA 控制器访问物理上不连续的缓冲区,就好像它是连续的一样。然而,带有 IOMMU 的平台还不够普遍,不足以说明“您的平台必须为我们的操作系统配备 IOMMU”。因此,目前IOMMU主要用于虚拟机监视器。
| 归档时间: |
|
| 查看次数: |
1946 次 |
| 最近记录: |