物理地址、设备地址和虚拟地址的区别

2024-04-17

有什么区别设备地址, 实际地址 and 虚拟地址?

其实我正在努力mmap在驱动程序中,我一直坚持这个概念。


The 文档 https://www.kernel.org/doc/Documentation/DMA-API-HOWTO.txt says:

内核通常使用虚拟地址。返回的任何地址 kmalloc()、vmalloc()和类似接口是虚拟地址,可以 存储在“void *”中。

虚拟内存系统(TLB、页表等)将虚拟内存转换为内存 地址到CPU物理地址,存储为“phys_addr_t”或 “资源大小_t”。内核管理设备资源,如寄存器 物理地址。这些是 /proc/iomem 中的地址。物理方面 地址对驾驶员没有直接用处;它必须使用 ioremap() 来映射 空间并产生虚拟地址。

I/O 设备使用第三种地址:“总线地址”或“DMA 地址”。 如果设备在 MMIO 地址处有寄存器,或者如果它执行 DMA 来读取 或者写系统内存,设备使用的地址都是总线地址。 在某些系统中,总线地址与CPU物理地址相同,但是 一般来说,它们不是。 IOMMU 和主桥可以产生任意 物理地址和总线地址之间的映射。

这是一张图片和一些示例:

             CPU                  CPU                  Bus
           Virtual              Physical             Address
           Address              Address               Space
            Space                Space

          +-------+             +------+             +------+
          |       |             |MMIO  |   Offset    |      |
          |       |  Virtual    |Space |   applied   |      |
        C +-------+ --------> B +------+ ----------> +------+ A
          |       |  mapping    |      |   by host   |      |
+-----+   |       |             |      |   bridge    |      |   +--------+
|     |   |       |             +------+             |      |   |        |
| CPU |   |       |             | RAM  |             |      |   | Device |
|     |   |       |             |      |             |      |   |        |
+-----+   +-------+             +------+             +------+   +--------+
          |       |  Virtual    |Buffer|   Mapping   |      |
        X +-------+ --------> Y +------+ <---------- +------+ Z
          |       |  mapping    | RAM  |   by IOMMU
          |       |             |      |
          |       |             |      |
          +-------+             +------+

在枚举过程中,内核了解 I/O 设备并 它们的 MMIO 空间以及将它们连接到系统的主桥。为了 例如,如果 PCI 设备有 BAR,则内核读取总线地址 (A) 从 BAR 并将其转换为 CPU 物理地址 (B)。地址B 存储在结构资源中,通常通过 /proc/iomem 公开。当一个 驱动程序声明一个设备,它通常使用 ioremap() 来映射物理地址 B 位于虚拟地址 (C)。然后它可以使用 ioread32(C) 等来访问 设备在总线地址 A 处注册。

如果设备支持 DMA,驱动程序会使用 kmalloc() 或 类似的接口,返回虚拟地址(X)。虚拟的 内存系统将 X 映射到系统 RAM 中的物理地址 (Y)。司机 可以使用虚拟地址X来访问缓冲区,但是设备本身 不能,因为 DMA 不经过 CPU 虚拟内存系统。

在一些简单的系统中,设备可以直接对物理地址进行DMA Y. 但在许多其他方面,有 IOMMU 硬件来转​​换总线 地址到物理地址,例如,它将 Z 转换为 Y。这是一部分 DMA API 的原因:驱动程序可以给一个虚拟地址 X 类似 dma_map_single() 的接口,用于设置任何所需的 IOMMU 映射并返回总线地址 Z。然后驱动程序告诉设备 对Z进行DMA,IOMMU将其映射到系统中地址Y处的缓冲区 内存。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

物理地址、设备地址和虚拟地址的区别 的相关文章

随机推荐