P302提到操作系统向DMA控制器注册DMA内存缓冲区时,需要填写的是总线地址。 P357提到虚拟机在直接使用DMA时候需要提供主机物理地址。 这两块地方是不是存在矛盾,我的疑问是操作系统在使用DMA的时候究竟使用是物理地址还是总线地址? 我的理解是操作系统使用DMA的时候用的是物理地址,总线地址只是设备在使用的地址,不知道是否正确呢
这两块地方是不是存在矛盾
两个地方看似矛盾,其实都是对的 😃
操作系统在使用DMA的时候究竟使用是物理地址还是总线地址?
设备访存用的是总线地址。由于注册DMA缓冲区就是提供给设备用的,因此应该是总线地址。 其他书上也有说明:"DMA operations, in the end, come down to allocating a buffer and passing bus addresses to your device" from https://www.oreilly.com/library/view/linux-device-drivers/0596005903/ch15.html 在x86平台上,总线地址和物理地址相同,但在其他平台和不一定哦~
虚拟机在直接使用DMA时候需要提供主机物理地址
虚拟化中,并没有对总线地址进行虚拟化。物理设备的DMA直接用了主机物理地址,这里默认了是x86系统。
MaxulLee 我可以理解为总线地址是OS为设备提供的“虚拟”地址空间中的地址吗,通常情况下这片地址空间是直接映射到物理内存中的一片区域的。(就是总线地址等于物理地址的情况) 不过在有IOMMU的时候,我们可以为设备设置一片不同于物理地址的总线地址空间,设置好页表,然后设备对总线地址进行访问的时候就会被IOMMU翻译为物理地址(类似于虚拟地址空间)。
zenotme
总线地址是OS为设备提供的“虚拟”地址空间中的地址吗
你的第一次理解是对的。总线地址确实是设备访问物理内存时用的地址,但不是OS提供的(和有没有OS无关)。可以参考第一张图:https://www.kernel.org/doc/Documentation/DMA-API-HOWTO.txt
IOMMU可以将总线地址映射到任意物理地址。第二段理解应该是没问题的。最好表达为“可以为设备设置一片不同于原先总线地址的物理地址区间”。