现在的位置: 首页 > 综合 > 正文

AlignmentRequirement

2014年09月05日 ⁄ 综合 ⁄ 共 1710字 ⁄ 字号 评论关闭

执行DMA(DirectMemoryAccess,直接内存存取)传输的设备直接使用内存中的数据缓冲区工作。HAL要求DMA传输中使用的缓冲区必须按某个特定界限对齐,而且设备也可能有更严格的对齐需求。设备对象中的AlignmentRequirement域表达了这个约束,它是一个位掩码,等于要求的地址边界减一。下面语句可以把任何地址圈入这个界限:

PVOID address = ...;
SIZE_T ar = fdo->AlignmentRequirement;
address = (PVOID) ((SIZE_T) address & ~ar);

还可以把任意地址圈入下一个对齐边界:

PVOID address = ...;
SIZE_T ar = fdo->AlignmentRequirement;
address = (PVOID) (((SIZE_T) address + ar) & ~ar);

在这两段代码中,我使用了SIZE_T把指针类型(它可以是32位也可以是64位,这取决于编译的目标平台)转化成一个整型,该整型与原指针有同样的跨度范围。

IoCreateDevice把新设备对象中的AlignmentRequirement域设置成HAL要求的值。例如,Intel的x86芯片没有对齐需求,所以AlignmentRequirement的默认值为0。如果设备需要更严格的缓冲区对齐(例如设备有总线主控的DMA能力,要求对齐数据缓冲区),应该修改这个默认值,如下:

if (MYDEVICE_ALIGNMENT - 1 > fdo->AlignmentRequirement)
fdo->AlignmentRequirement = MYDEVICE_ALIGNMENT - 1;

我假设你在驱动程序某处已定义了一个名为MYDEVICE_ALIGNMENT的常量,它是2的幂,代表设备的数据缓冲区对齐需求。

 

另外在osr的论坛里看到的回复

<!--StartFragment-->The alignment requirement indicates, funnily enough, the alignment ofthe buffer that is required for the device. It is expressed as a maskindicating the lower bits of the virtual address that need to be zerofor buffers that are sent to
the driver. 0 indicates that there are noalignment restrictions, 1 indicates the buffer must be aligned on a word boundary, 3 for 4-byteboundary etc. By definition,(AlignmentRequirement+1) must be a power of 2. For non-cached i/o for instance, the virtual
address actually makes itto the hardware for DMA. Most modern disk controller hardware in realitydon't have alignment restrictions.

Tidbit: unfortunately as far as I can tell, there is no way to query thealignment requirement for user-mode. So the win32 documentation forinstance indicates folks should use sector-size alignment for buffersfor unbuffered i/o - in fact the alignment requirement
could be muchless restrictive (or non-existent) for many devices. Fortunately though,there are no block devices that need alignment > sector size for thedevice, so this is not fatal.

抱歉!评论已关闭.