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

相关文章

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

usb接口驱动异常问题常用解决方案

《usb接口驱动异常问题常用解决方案》当遇到USB接口驱动异常时,可以通过多种方法来解决,其中主要就包括重装USB控制器、禁用USB选择性暂停设置、更新或安装新的主板驱动等... usb接口驱动异常怎么办,USB接口驱动异常是常见问题,通常由驱动损坏、系统更新冲突、硬件故障或电源管理设置导致。以下是常用解决

CentOS7更改默认SSH端口与配置指南

《CentOS7更改默认SSH端口与配置指南》SSH是Linux服务器远程管理的核心工具,其默认监听端口为22,由于端口22众所周知,这也使得服务器容易受到自动化扫描和暴力破解攻击,本文将系统性地介绍... 目录引言为什么要更改 SSH 默认端口?步骤详解:如何更改 Centos 7 的 SSH 默认端口1

Windows Docker端口占用错误及解决方案总结

《WindowsDocker端口占用错误及解决方案总结》在Windows环境下使用Docker容器时,端口占用错误是开发和运维中常见且棘手的问题,本文将深入剖析该问题的成因,介绍如何通过查看端口分配... 目录引言Windows docker 端口占用错误及解决方案汇总端口冲突形成原因解析诊断当前端口情况解

如何使用Nginx配置将80端口重定向到443端口

《如何使用Nginx配置将80端口重定向到443端口》这篇文章主要为大家详细介绍了如何将Nginx配置为将HTTP(80端口)请求重定向到HTTPS(443端口),文中的示例代码讲解详细,有需要的小伙... 目录1. 创建或编辑Nginx配置文件2. 配置HTTP重定向到HTTPS3. 配置HTTPS服务器

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