Linux 使用什么指令指示英特尔 CPU 设置 DMA 传输?
What instruction does Linux use to direct Intel CPU to setup a DMA transfer?
我知道设备驱动程序可以使用内核 api 来设置传输方向、计数等,但我想了解 CPU 指令对 api 用于通知 cpu 启动此 DMA 传输?
在大多数情况下,每个设备都有自己的 DMA/bus 内置于设备中的母带处理能力;并且设备驱动程序使用设备的 DMA/bus 控制(以“设备特定”方式),而不涉及任何内核 API。在这些情况下,通常 OS 会阻止其他代码使用设备的寄存器(通过拒绝访问 IO 端口或不将“内存映射 IO 寄存器”映射到普通代码可以使用的区域);因此其他代码也无法使用设备的 DMA/bus 母带处理。
在极少数情况下,DMA/bus 母带处理能力未内置于特定设备中;但它们本身就是一个单独的设备。这包括 PC 中古老的“DMA 控制器芯片”,以及一些更现代的设备(例如“Intel Quickdata IO Accelerator”)。在这些情况下;你可能有一个 DMA 引擎的设备驱动程序,其他设备驱动程序可以通过它使用。某种“特定于 DMA 引擎”的接口,或者它可能(如果硬件非常普遍)“更集成”到内核中(这样“DMA 引擎驱动程序代码”内置到内核中,而“特定于 DMA 引擎接口”更像是一个内核 API).
另请注意:
a) 现代计算机几乎所有软件都使用虚拟地址,但硬件设备只能使用物理地址。这意味着在某些时候虚拟地址(对于一个虚拟地址space)需要转换为设备可以使用的物理地址。
b) 对于现代操作系统,设备驱动程序通常直接传输数据 to/from 属于某个进程的内存(在用户 space 中)。在这些情况下,设备驱动程序需要确保内核的虚拟内存管理不会干扰传输(例如,确保内核不能't/won 发送 RAM 的内容以交换 space 和在设备传输数据时释放 RAM)。通常,设备驱动程序通过在开始 DMA/bus 掌握之前要求内核“固定”虚拟内存来做到这一点(并要求内核在之后“取消固定”)。
c) 对于现代计算机,可能涉及 IOMMU。如果 IOMMU 被用于增强安全性(而不仅仅是用于虚拟化或“通过”);那么设备驱动程序可能需要在开始任何 DMA/bus 控制之前要求内核配置 IOMMU(如果不这样做,IOMMU 硬件可能会拒绝允许设备传输数据)。在某些情况下,IOMMU 也可用于 IO 重新映射到 fix/avoid 设备的限制 - 例如如果设备只能使用 32 位地址但需要传输数据 to/from 64 位地址,那么 IO MMU 可以配置为将区域重新映射到设备支持的地址范围(并防止设备驱动程序从需要在 RAM 中使用“反弹缓冲区”,其中数据在 DMA 传输之前被复制到该临时缓冲区或在 DMA 传输之后从临时缓冲区复制出来。
出于这些原因;内核可能会提供一个接口,设备驱动程序在开始 DMA/bus 主控传输之前和 DMA/bus 主控传输完成后将使用该接口;但这不应被视为设置 DMA/bus 母带传输本身的一部分。
我知道设备驱动程序可以使用内核 api 来设置传输方向、计数等,但我想了解 CPU 指令对 api 用于通知 cpu 启动此 DMA 传输?
在大多数情况下,每个设备都有自己的 DMA/bus 内置于设备中的母带处理能力;并且设备驱动程序使用设备的 DMA/bus 控制(以“设备特定”方式),而不涉及任何内核 API。在这些情况下,通常 OS 会阻止其他代码使用设备的寄存器(通过拒绝访问 IO 端口或不将“内存映射 IO 寄存器”映射到普通代码可以使用的区域);因此其他代码也无法使用设备的 DMA/bus 母带处理。
在极少数情况下,DMA/bus 母带处理能力未内置于特定设备中;但它们本身就是一个单独的设备。这包括 PC 中古老的“DMA 控制器芯片”,以及一些更现代的设备(例如“Intel Quickdata IO Accelerator”)。在这些情况下;你可能有一个 DMA 引擎的设备驱动程序,其他设备驱动程序可以通过它使用。某种“特定于 DMA 引擎”的接口,或者它可能(如果硬件非常普遍)“更集成”到内核中(这样“DMA 引擎驱动程序代码”内置到内核中,而“特定于 DMA 引擎接口”更像是一个内核 API).
另请注意:
a) 现代计算机几乎所有软件都使用虚拟地址,但硬件设备只能使用物理地址。这意味着在某些时候虚拟地址(对于一个虚拟地址space)需要转换为设备可以使用的物理地址。
b) 对于现代操作系统,设备驱动程序通常直接传输数据 to/from 属于某个进程的内存(在用户 space 中)。在这些情况下,设备驱动程序需要确保内核的虚拟内存管理不会干扰传输(例如,确保内核不能't/won 发送 RAM 的内容以交换 space 和在设备传输数据时释放 RAM)。通常,设备驱动程序通过在开始 DMA/bus 掌握之前要求内核“固定”虚拟内存来做到这一点(并要求内核在之后“取消固定”)。
c) 对于现代计算机,可能涉及 IOMMU。如果 IOMMU 被用于增强安全性(而不仅仅是用于虚拟化或“通过”);那么设备驱动程序可能需要在开始任何 DMA/bus 控制之前要求内核配置 IOMMU(如果不这样做,IOMMU 硬件可能会拒绝允许设备传输数据)。在某些情况下,IOMMU 也可用于 IO 重新映射到 fix/avoid 设备的限制 - 例如如果设备只能使用 32 位地址但需要传输数据 to/from 64 位地址,那么 IO MMU 可以配置为将区域重新映射到设备支持的地址范围(并防止设备驱动程序从需要在 RAM 中使用“反弹缓冲区”,其中数据在 DMA 传输之前被复制到该临时缓冲区或在 DMA 传输之后从临时缓冲区复制出来。
出于这些原因;内核可能会提供一个接口,设备驱动程序在开始 DMA/bus 主控传输之前和 DMA/bus 主控传输完成后将使用该接口;但这不应被视为设置 DMA/bus 母带传输本身的一部分。