To illustrate these two strategies, consider the example of a fax board in an MS-DOS environment. The controlling application creates an image of the fax in application memory. It then programs the DMA controller to move the fax image to the memory on the fax board. The application then sends a command to the fax board (through an I/O port operation or other means) telling it to receive the DMA transfer and start sending the fax. In Windows NT, the unmodified MS-DOS application running under VDM requests the DMA and then signals the fax board to receive the DMA and begin sending the fax. However, there are two differences:
Using the double-buffer strategy described in Double-Buffer DMA Transfer, the VDD calls VDDRequestDMA to move the data from the application’s buffer to the VDD buffer. This call does not actually use the DMA controller, but performs the equivalent data transfer by other means. The VDD then calls the kernel-mode driver to move the data to the device. Finally, the VDD relays the send fax command to the kernel-mode driver.
Using the single-buffer strategy described in Single Buffer DMA Transfer, the VDD calls VDDQueryDMA to determine the parameters for the DMA request. The VDD then sends these parameters to the kernel-mode driver and enables the driver to control the data transfer directly from the application’s buffer to the device. When the driver has transferred the data, the VDD calls VDDSetDMA to update the DMA state. Finally, the VDD relays the send fax command to the kernel-mode driver.
The following functions are used for memory accesses:
FlushVDMPointer |
Flushes data associated with a memory range. |
FreeVDMPointer |
Releases a pointer returned by GetVDMPointer. |
GetVDMPointer |
Returns a linear address for an x86 address. |
VDDAllocMem |
Allocates memory at a given virtual address. |
VDDFreeMem |
Releases previously allocated memory. |
VDDDeInstallMemoryHook |
Releases a range of memory-mapped I/O addresses. |
VDDIncludeMem |
Includes a particular memory range for use as a UMB. |
VDDInstallMemoryHook |
Releases memory-mapped addresses. |
VDDQueryDMA |
Gathers all DMA data. |
VDDRequestDMA |
Requests a DMA transfer from a VDD. |
VDDSetDMA |
Resets the state of the virtual DMA controller. |