1. 在 DriverEntry 里设置一个_NDIS_MINIPORT_DRIVER_CHARACTERISTICS结构,初作为参数提供给 NdisMRegisterMiniportDriver 函数
  NDIS_MINIPORT_DRIVER_CHARACTERISTICS MPChar;MPChar.InitializeHandlerEx          = MPInitialize;  // 初始化handle...// 注册小端口驱动 Status = NdisMRegisterMiniportDriver(DriverObject,RegistryPath,(PNDIS_HANDLE)MiniportDriverContext,&MPChar,&NdisMiniportDriverHandle);
  1. 系统会调用上面的初始化handle, 函数的模型如下
 NDIS_STATUS MPInitialize( NDIS_HANDLE NdisMiniportHandle, NDIS_HANDLE MiniportDriverContext,PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters // 由系统传来的一个 _NDIS_MINIPORT_INIT_PARAMETERS 参数                    )

其中 _NDIS_MINIPORT_INIT_PARAMETERS 结构里包含一项(PNDIS_RESOURCE_LIST AllocatedResources)

  typedef struct _CM_PARTIAL_RESOURCE_LIST {  // PNDIS_RESOURCE_LIST 结构USHORT Version;USHORT Revision;ULONG Count;CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]; //}
  resList = MiniportInitParameters->AllocatedResources; // 取得参数里的resourcefor (index=0; index < resList->Count; index++)    {pResDesc = &resList->PartialDescriptors[index];     // 取得resource里的PartialDescriptorsswitch(pResDesc->Type) {case CmResourceTypePort:Adapter->IoBaseAddress = pResDesc->u.Port.Start ; // 得到了一个IoBaseAddressAdapter->IoRange = pResDesc->u.Port.Length; //...}

硬件资源参考:https://blog.csdn.net/xiangbaohui/article/details/105179813

3 调用函数 NdisMRegisterIoPortRange 去注册一个I/O Port,以后通过返回的PortOffse去操控网卡

 Status = NdisMRegisterIoPortRange( (PVOID *)&Adapter->PortOffset, // 返回一个portoffset,就是通过这个portoffset去操控硬件的,和以前的in out端口指令一样 Adapter->AdapterHandle,NdisGetPhysicalAddressLow ( Adapter->IoBaseAddress ) , // 上面我们得到的IoBaseAddress Adapter->IoRange); `
  1. 有了上面的portoffset,我们给网卡设置收包/发包的数据存放地址,通过写 PortOffset+reg 来给网卡下命令。 不同的reg对应不同的命令
enum RTL8169_registers { // 硬件网卡的reg命令表 ,/* PHY access */TxDescStartAddr = 0x20,RxDescStartAddr = 0xE4, ...};ULONG_PTR ioaddr = A->PortOffset;  // PortOffset由上面调用 NdisMRegisterIoPortRange 函数得到的#define RTL_W32(reg, val32) WRITE_PORT_ULONG((PULONG)(ioaddr + reg),(ULONG)val32 ) // // 传递命令case SCB_RUC_LOAD_BASE : // 写入收包地址RTL_W32 ( RxDescStartAddr, NdisGetPhysicalAddressLow ( Adapter->HwRbdBasePa ) );     //  Adapter->HwRbdBasePa 是收包数据地址RTL_W32 ( RxDescStartAddr + 4, NdisGetPhysicalAddressHigh ( Adapter->HwRbdBasePa )); // case SCB_TBD_LOAD_BASE : // 写入发包地址`RTL_W32 ( , NdisGetPhysicalAddressLow ( Adapter->HwTbdBasePa ) );  TxDescStartAddr   // Adapter->HwTbdBasePa 是发包数据的存放地址`RTL_W32 ( TxDescStartAddr + 4, NdisGetPhysicalAddressHigh ( Adapter->HwTbdBasePa ) );//`
  1. 地址设置好了,当有数据要处理的时候,网卡会从 发包地址里读取要发送的数据 或 向收包地址里写入收到的数据。
      收包 — 网卡写数据到收包地址,生成一个硬件中断通知中断处理函数,中断处理函数先关闭中断,然后取数据,通过NdisMIndicateReceiveNetBufferLists函数把数据传递到上层, 再打开中断,等待下一次中断( 数据传递路径:miniport驱动-> (filter) -> protocol驱动 -> 应用层recv(),驱动之间还可以有过滤驱动,如防火墙就是在底层驱动 之间装一个filter driver,这样数据包会在recv之前被抓到 )
     发包 — 把上层传递下来的数据写到发包地址,通过portoffse+reg给网卡下指令,通知网卡去取数据 ( 路径很上面相反,send() -> protocol -> (filter) ->miniport )

  2. 传给网卡的地址,参考 https://blog.csdn.net/hz5034/article/details/79794615 这篇文章,是一串的连续的描述符,addr —> [描述符][描述符][描述符]…[描述符]
      把这个addr通过传给网卡,网卡/dma能够认识这个描述符的,他们会自动工作。【 这文章对这个描述符说的很好 https://www.cnblogs.com/CasonChan/p/5166239.html 】

数据在驱动中是以net_buffer_lists(NBL)结构存在的,一个NBL又有N个net_buffer(NB),一个NB下又有N个MDL,这Mdl存放的就是数据,
  描述符描述的就是每个Mdl的地址。一连串的Mdl组成一个NB,一连串的NB组成一个NBL。
  描述符的结构大概如下:

  typedef struct _TBD_STRUC { // 发包的描述符,UINT16        FrameLength ;UINT16        status;UINT32        notused;UINT32        TbdBufferAddress;       // 网卡会去这个地址取发包的数据UINT32        TbdBufferAddressHigh ;} TBD_STRUC, *PTBD_STRUC;typedef struct _RTK_RECEIVE_BUFFER_DESCRIPOR_STRUC { //  收包的描述符UINT32        status;UINT32        vlan_tag;UINT32        buf_addr;      // 网卡会把数据写到这个地址UINT32        buf_Haddr;} HW_RBD, *PHW_RBD;

6.参考资料 NDIS sample - 6.0 miniport driver for realtek 168/8169/8111/8110
https://www.codeproject.com/Articles/24384/NDIS-sample-miniport-driver-for-realtek

Ndis网卡驱动是如何操控硬件的相关推荐

  1. windows7以上平台NDIS6框架的NDIS协议驱动开发

    by fanxiushu 2019-01-30 转载或引用请注明原始作者. 提到NDIS协议驱动,可能比较陌生,因为毕竟用得挺少的. 但是一提到WireShark或ethereal等抓包软件,大家就不 ...

  2. 《转》关于ath5k网卡驱动中beacon的发送过程(特别是timestamp字段)

    转自:http://blog.csdn.net/liujihang88/article/details/39700385 ath5k网卡驱动中beacon 工作模式:ad-hoc    内核版本:3. ...

  3. 一文搞懂网卡驱动的原理与移植方法

    1.网卡设备驱动原理 1.1 层次结构 Linux系统对网络设备驱动定义了4个层次, 这4个层次有到下分为: 1.网络协议接口层:实现统一的数据包收发的协议.该层主要负责调用dev_queue_xmi ...

  4. 基于NDIS(网络驱动接口标准)包拦截技术

    看了很多提供数据包的拦截技术,其中最多的是编写IM DRIVER在NDIS中间层对MINIPORT(网卡驱动程序)和协议驱动程序之间的数据包进行拦截.但编写该过滤程序拦截程序非常的复杂,这里介绍一种更 ...

  5. 【转帖】基于NDIS(网络驱动接口标准)包拦截技术

    通常用户都知道,NDIS协议驱动程序是通过填写一张NDIS_PROTOCOL_CHARACTERISTICS的表,并调用NDIS API函数NdisRegisterProtocol进行注册.现在我们来 ...

  6. 关闭Win8快速启动,解决网卡识别错误/网卡驱动安装不正确的问题

    阴魂不散的问题 笔者安装的Windows 8是64位专业版,主板內建Intel 82597V千兆网络芯片.Windows 8系统的识别错误经常出现,尤其是当笔者上不了网时,一查看网络适配器,发现它被识 ...

  7. 字符设备驱动基础篇5——驱动如何操控硬件(动静态映射操作LED)

    以下内容源于朱有鹏嵌入式课程的学习,,如有侵权,请告知删除. 参考资料:http://www.cnblogs.com/biaohc/p/6575074.html 这里的映射,是指物理地址和虚拟地址的对 ...

  8. intel x520网卡驱动_手工编译linux桌面内核(二)——硬件驱动的配置 下篇

    前言: 前面的方法讲完了,接下来我们来看看实例(我自己电脑的配置). 这里我只打算列出几项重要的驱动配置来,其它的请自行查阅gentoo wiki! 再次强调,这是我自己电脑的硬件驱动配置,不可能完全 ...

  9. enc28j60 linux 驱动_linux enc28j60网卡驱动移植(硬件spi和模拟spi)

    本来想移植DM9000网卡的驱动,无奈硬件出了点问题,通过杜邦线链接开发板和DM9000网卡模块,系统上电,还没加载网卡驱动就直接崩溃了,找不到原因...刚好手上有一个enc28j60的网卡模块,于是 ...

最新文章

  1. dis的前缀单词有哪些_英语单词词根.词缀II 5个最高频英语前缀 必背
  2. python是一种面向对象、直译式的脚本编程语言_什么是python编程语言
  3. jquery插件的写法
  4. 拼接路径优雅方式_章泽天“学生装”穿出高级感,缎面衬衫配小香风裙,温柔又优雅...
  5. 审计日志删除 oracle,oracle audit,怎么审计ORACLE日志
  6. c语言程序兔子反之问题,C语言解决兔子产子问题代码及解析
  7. cmake编译Debug和Release
  8. [bzoj] 2049 洞穴勘探 || LCT
  9. MyBatis第1天
  10. zookeeper 进入客户端_Zookeeper基础知识简单介绍
  11. 信息系统开发平台OpenExpressApp - ClickOnce智能部署
  12. c语言模拟试卷答案,C语言模拟试卷2(带答案)
  13. 如何注册CSDN博客
  14. WebService之CXF框架
  15. html视频播放卡顿,网页看视频卡怎么解决
  16. source insight使用2---设置全选为Ctrl+a
  17. 便利店卷疯了:便利蜂、罗森、易捷“激战”
  18. 项目需求的重要性和开发步骤
  19. 微信分享链接不显示缩略图
  20. 【软件测试】软件测试的方法

热门文章

  1. 2021-10-27【WGS】丨Pacbio三代甲基化修饰流程
  2. Linux设备模型(2)——Kobject
  3. 基于工业智能网关的PLC远程控制解决方案
  4. MSSQLSERVER 2019修改数据库文件存放路径的简单实现
  5. python爬虫利用线程池下载视频
  6. API调用,淘宝天猫、1688、京东、拼多多商品页面APP端原数据获取
  7. python文献知识图谱可视化_知识图谱可视化工具(知识图谱可视化python)
  8. 中止执行后超过2年_申请执行超过2年时效,法院还处理吗?
  9. 利用QProcess::finished信号(signal)来保持目标程序始终运行
  10. Synchronized详细介绍之锁升级过程