NDIS小端口驱动(七)

2024-05-25 07:04
文章标签 驱动 端口 ndis

本文主要是介绍NDIS小端口驱动(七),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

NDIS微型端口驱动不可避免的可能和DMA相关,这种情况下,我们也需要考虑DMA相关的情况,不过,NDIS本身也支持常规的DMA操作,这里需要特殊对待的是Scatter/Gather DMA,因为NDIS似乎天然的需要这种技术。

NDIS Scatter/Gather DMA

对于 Arm 和 Arm64 处理器,我们强烈建议 NDIS 驱动程序编写器使用 WDF DMA 或 WDM DMA,而不是 NDIS Scatter/Gather DMA。

NDIS 微型端口驱动程序可以使用Scatter/Gather DMA (SGDMA) 方法在 NIC 和系统内存之间传输数据。 成功的 DMA 传输要求数据的物理地址位于 NIC 支持的地址范围内。 HAL 为驱动程序提供一种机制,用于获取 MDL 链的物理地址列表,并在必要时将数据双缓冲到物理地址范围。

在 NDIS 6.0 之前的 NDIS 版本中,微型端口驱动程序和 NDIS 中的 SGDMA 支持在某些方面受到限制,尤其是在多包发送方案中效果不佳。 NDIS 6.0 SGDMA 支持克服了这些限制,同时为微型端口驱动程序提供简单的接口。

NDIS SGDMA 的历史

在 NDIS 6.0 之前的 NDIS 版本中,NDIS 在将数据包发送到微型端口驱动程序之前,获取每个数据包的散点聚集 (SG) 列表。 NDIS 还处理原始尝试获取 SG 列表因过度碎片而失败的情况。 在这种情况下,NDIS 将数据包双重缓冲到连续缓冲区,然后重试。 例如,如果数据的物理地址高于 32 位最大值,并且 NIC 不支持 64 位 DMA,则 HAL 还可以将数据双缓冲到 NIC 支持的物理地址。

为了避免死锁情况,NDIS 获取数据包的 SG 列表,并一次发送一个数据包。 如果 NDIS 在将数据包发送到微型端口驱动程序之前尝试映射所有数据包,则系统可能会耗尽资源。 在这种情况下,NDIS 将等待映射寄存器变得可用,而某些映射寄存器被锁定为尚未发送的数据包。 锁定的数据包不能重复使用。

这种 SGDMA 支持方法具有以下限制:

  • 由于数据包在到达微型端口驱动程序之前已映射,因此驱动程序无法针对小数据包或过于碎片的数据包进行优化。 微型端口驱动程序无法将数据包缓冲到已知的物理地址;
  • 无法保证 NDIS 传递给微型端口驱动程序的物理地址数组映射到原始数据的虚拟地址。 因此,如果驱动程序在发送之前更改了 MDL 链中虚拟地址处的数据,则对数据所做的修改不会反映在物理地址中的数据中。 在这种情况下,NIC 发送未修改的数据;
  • NDIS 限制为一次发送一个数据包,以避免由于资源问题而导致的死锁。 这不如发送多个数据包那么高效;
  • 由于 NDIS 无法确定微型端口驱动程序的传输功能,因此无法为 SG 列表缓冲区预分配存储。 因此,NDIS 必须在运行时分配必要的存储。 这不如预分配存储那么高效;
  • 分配 SG 列表的 HAL 函数应在 IRQL = DISPATCH_LEVEL 调用。 NDIS 没有当前的 IRQL 信息,因此它必须将 IRQL 设置为 DISPATCH_LEVEL即使它已处于DISPATCH_LEVEL。 如果 IRQL 已在DISPATCH_LEVEL,则此方法效率不高;
NDIS SGDMA 支持的优势

在 NDIS 6.0 及更高版本的 SGDMA 接口中,NDIS 不会在将数据缓冲区发送到微型端口驱动程序之前映射数据缓冲区。 相反,NDIS 为驱动程序提供了一个接口来映射网络数据。

此方法具有以下优势:

  • 由于 NDIS 提供用于映射网络数据的 HAL 接口,NDIS 使微型端口驱动程序免受映射过程的复杂性和细节的防护;
  • 微型端口驱动程序在映射数据之前有权访问数据。 因此,即使 NDIS 或 HAL 对数据进行双重缓冲,对原始数据所做的任何更改也会反映在 SG 列表表示的数据中;
  • 微型端口驱动程序可以通过将小型数据包或高度分段数据包复制到具有已知物理地址的预分配缓冲区来优化这些数据包的传输。 此方法可避免不需要的映射,从而提高系统性能;
  • NDIS 可以安全地将多个缓冲区发送到微型端口驱动程序。 这可以减少对微型端口驱动程序的调用,从而提高系统性能;
  • 微型端口驱动程序可以将 SG 列表的内存预先分配为传输描述符块的一部分。 因此,NDIS 或微型端口驱动程序不需要在运行时为 SG 列表分配内存;
  • 由于微型端口驱动程序可以在 IRQL = DISPATCH_LEVEL 下运行,因此微型端口驱动程序可以避免不必要的调用来将 IRQL 提升为DISPATCH_LEVEL。 例如,由于完成发送发生在中断 DPC 的上下文中,因此微型端口驱动程序可以在不引发 IRQL 的情况下释放 SG 列表;
注册和取消注册 DMA 通道

NDIS 微型端口驱动程序从其 MiniportInitializeEx 函数调用 NdisMRegisterScatterGatherDma 函数,以向 NDIS 注册 DMA 通道。

微型端口驱动程序在 DmaDescription 参数中将 DMA 说明传递给 NdisMRegisterScatterGatherDma。 NdisMRegisterScatterGatherDma 返回缓冲区的大小,该大小应足以容纳Scatter/Gather列表。 微型端口驱动程序应使用此大小来预分配Scatter/Gather列表的存储。

微型端口驱动程序还会传递 NdisMRegisterScatterGatherDma 为处理Scatter/Gather列表而调用的 MiniportXxx 函数的入口点。 NDIS 在 HAL 为缓冲区生成Scatter/Gather列表后调用微型端口驱动程序的 MiniportProcessSGList 函数。 NdisMRegisterScatterGatherDma 在 pNdisMiniportDmaHandle 参数中提供句柄,微型端口驱动程序必须在后续调用 NDIS Scatter/Gather DMA 函数时使用该句柄。

NDIS 微型端口驱动程序从其 MiniportHaltEx 函数调用 NdisMDeregisterScatterGatherDma 函数,以释放Scatter/Gather DMA 资源。

分配和释放Scatter/Gather列表

NDIS 微型端口驱动程序在其 MiniportSendNetBufferLists 函数中调用 NdisMAllocateNetBufferSGList 函数。 微型端口驱动程序为其必须映射的每个NET_BUFFER结构调用 NdisMAllocateNetBufferSGList 一次。 资源可用且 HAL 已准备好 SG 列表后,NDIS 会调用驱动程序的 MiniportProcessSGList 函数。 NDIS 可以在微型端口驱动程序调用 NdisMAllocateNetBufferSGList 返回之前或之后调用 MiniportProcessSGList。

为了提高系统性能,将从在关联NET_BUFFER_DATA结构的 CurrentMdl 成员中指定的 MDL 开头的网络数据生成散点 / 收集列表。 SG 列表中的网络数据的开头从 SG 列表的开头偏移到关联的 NET_BUFFER_DATA 结构的 CurrentMdlOffset 成员中指定的值。

处理发送完成中断的 DPC 时,在微型端口驱动程序不再需要 SG 列表后,微型端口驱动程序应调用 NdisMFreeNetBufferSGList 函数来释放 SG 列表。

注意当驱动程序或硬件仍在访问由与Scatter/Gather列表关联的NET_BUFFER结构所描述的内存时,请不要调用 NdisMFreeNetBufferSGList。 

在访问接收的数据之前,微型端口驱动程序必须调用 NdisMFreeNetBufferSGList 以刷新内存缓存。

这篇关于NDIS小端口驱动(七)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1000799

相关文章

Flask解决指定端口无法生效问题

《Flask解决指定端口无法生效问题》文章讲述了在使用PyCharm开发Flask应用时,启动地址与手动指定的IP端口不一致的问题,通过修改PyCharm的运行配置,将Flask项目的运行模式从Fla... 目录android问题重现解决方案问题重现手动指定的IP端口是app.run(host='0.0.

nginx配置多域名共用服务器80端口

《nginx配置多域名共用服务器80端口》本文主要介绍了配置Nginx.conf文件,使得同一台服务器上的服务程序能够根据域名分发到相应的端口进行处理,从而实现用户通过abc.com或xyz.com直... 多个域名,比如两个域名,这两个域名其实共用一台服务器(意味着域名解析到同一个IP),一个域名为abc

Nginx启动失败:端口80被占用问题的解决方案

《Nginx启动失败:端口80被占用问题的解决方案》在Linux服务器上部署Nginx时,可能会遇到Nginx启动失败的情况,尤其是错误提示bind()to0.0.0.0:80failed,这种问题通... 目录引言问题描述问题分析解决方案1. 检查占用端口 80 的进程使用 netstat 命令使用 ss

Windows设置nginx启动端口的方法

《Windows设置nginx启动端口的方法》在服务器配置与开发过程中,nginx作为一款高效的HTTP和反向代理服务器,被广泛应用,而在Windows系统中,合理设置nginx的启动端口,是确保其正... 目录一、为什么要设置 nginx 启动端口二、设置步骤三、常见问题及解决一、为什么要设置 nginx

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

驱动(RK3588S)第七课时:单节点设备树

目录 需求一、设备树的概念1、设备树的后缀名:2、设备树的语法格式3、设备树的属性(重要)4、设备树格式举例 二、设备树所用函数1、如何在内核层种获取设备树节点:2、从设备树上获取 gpio 口的属性3、获取节点上的属性只针对于字符串属性的4、函数读取 np 结点中的 propname 属性的值,并将读取到的 u32 类型的值保存在 out_value 指向的内存中,函数的返回值表示读取到的

驱动安装注册表指令

HKCR: HKEY_CLASSES_ROOT HKCU: HKEY_CURRENT_USER HKLM: HKEY_LOCAL_MACHINE HKU: HEKY_USER HER: 相对根键

UMDF驱动安装

VS2013 + WDF8.1,UMDF驱动选择User Mode Driver,不要选User Mode Driver 2.0,否则Win7安装有问题,如图 另外,在驱动安装时不要忘记WUDFUpdate_<主版本号><次版本号>.dll文件,具体文件名在INF中查找。此文件可在WDF的安装目录中找到。注意:在WDF的安装目录中会有3个WUDFUpdate_xxx.dll文件,x86,x6

电脑驱动分类

电脑驱动程序(驱动程序)是操作系统与硬件设备之间的桥梁,用于使操作系统能够识别并与硬件设备进行通信。以下是常见的驱动分类: 1. 设备驱动程序 显示驱动程序:控制显卡和显示器的显示功能,负责图形渲染和屏幕显示。 示例:NVIDIA、AMD 显示驱动程序。打印机驱动程序:允许操作系统与打印机通信,控制打印任务。 示例:HP、Canon 打印机驱动程序。声卡驱动程序:管理音频输入和输出,与声卡硬件