前言
windowsnt是一个功能全面的操作系统,具有完全集成式的连网能力,它的网络模型开始于mac子层,网络接口卡(networkinterfacecard以后简称网卡或nic)驱动程序驻留在其中。通过相关的网卡把windowsnt与网络连接起来,但一直到80年代后期,许多传输协论文网议的实现受限于mac层接口的独特实现,因为mac层定义了协议与网卡之间的转换机制。
1989年,microsoft和3com两公司提出了一个定义mac层与osi模型高层协议驱动程序之间的网络设备接口规范(networkdeviceinterfacespecification:ndis),ndis给数据交换提出了一个灵活的环境,它规范了软件接口──称为ndis接口,传输协议可用它与网卡驱动程序进行通信。因此在windowsnt环境下开发核心态网卡驱动程序应遵循ndis规范。
对于高速网络fddi(fiberdistributeddatainterface)网卡驱动程序还需要smt(stationmanagement)站管理功能的实现,否则将不能作为一个fddi站连入环结构中,只能实现点到点间的数据通信。故有必要将smt软件移植到网卡驱动程序中,这将又导致对miniportnic驱动程序编程框架的破坏,于是有必要形成fddi网卡驱动程序(包含smt)与windowsnt操作系统的良好接口──由逻辑网卡的注册和mac层驱动程序的初始化来完成。
所以,本课题旨在深入研究应用microsoft公司的ddk(devicedriverkit)将smt移植于windowsnt的fddi网卡驱动程序过程中如何注册miniportnic驱动程序。即怎样正确注册逻辑网卡和mac驱动程序的初始化。着重讨论与初始化相关的上边缘函数的使用和调用关系以及初始化过程中遇到的各种问题的具体解决。
第一章windowsnt环境下fddi网卡驱动程序
总体结构介绍
第一节windowsnt网络结构
§1。1。1windowsnt网络体系结构
windowsnt的网络体系结构是国际标准化(iso)制定的标准模型──开放式系统互连(opensysteminterconnection:osi)参考模型分层建立的,这种方式有利于随时扩展其它功能和服务。
windowsnt网络模型开始于mac子层,网卡驱动程序就驻留在其中。它通过相关的网卡把windowsnt与网络连接起来,图中的多个网卡表明在一台运行windowsnt的计算机上能使用多种网卡。
这一网络体系结构包括两个重要接口──ndis接口与传输驱动
程序接口(tdi)。这两个接口把两个层隔离开来,办法是相邻的部件只允许按单一的标准来写,不允许多重标准。例如一个网卡驱动程序(在ndis接口的下面)就不需要特地按每个传输协议来写它的代码块,恰恰相反,该驱动程序是写给ndis接口的,它通过符合ndis的相应传输协议来请求服务。这些接口包含在windowsnt的网络体系结构中,以容纳可移植。可互换的模块。
在两个接口之间,是传输协议。它在网络中起着组织者的作用。一个传输协议规定了数据以何种方式呈递给下一个接收层,以及如何对数据相应地进行打包。它通过ndis把数据传给网卡驱动程序,并通过tdi把数据传给转发程序(redirector)
tdi之上是转发程序,它把本地的网络资源申请转送给网络。
为了能和其他厂商的网络互连,windowsnt允许有多个转发程序。对于每一个转发程序windowsnt计算机必须也有一个相应的供应者(provider)(由网络厂商提供)。多供应者路由选择程序决定适当的供应者,然后借助于供应者,对应用请求到相应的转发程序做出选择。
§1。1。2windowsnt网络驱动程序
windowsnt支持两种类型的网络驱动程序
传输驱动程序
实现数据链路层中的逻辑链路控制子层协议和传输层协议。向下与ndis接口,向上与tdi接口。
网卡驱动程序
实现对物理层的管理和数据链路层中介质访问控制子层协议,通过ndis向下管理物理网卡,向上与传输驱动程序通信。
§1。1。3windowsnt网卡驱动程序
windowsnt环境下的网卡驱动程序也分为两种:
miniport网卡驱动程序:miniport驱动程序只须实现与网络硬件相关的操作(包括发送和接收)。而所有底层网卡驱动程序的通用操作(如同步),一般由ndis接口程序来实现。
full网卡驱动程序:full网卡驱动程序必须实现所有硬件相关和同步。排队等操作。例如full网卡驱动程序为了响应数据接收,需要保持本身的捆绑信息,而miniport就可以由ndis接口库来实现。
在windowsnt的早期版本中,full网卡驱动程序要求开发者实现许多底层操作,来处理多处理器的核心问题以及处理器。线程的同步,这样不同的开发者在大量重复着许多相同的工作。
而miniport网卡驱动程序允许开发者仅仅写一些与网络硬件相关的代码即可,而那些通用的函数由ndis接口库来实现,这样开发出来的驱动程序减少了不必要的工作。
第二节miniport驱动程序的结构
ndis接口规范了网卡驱动程序的实现,同时也对tdi驱动程序的实现提出了一定的要求,在nt中,ndis约束下的网卡驱动程序。tdi驱动程序和系统的关系如下图所示:
图2。0ndis约束下的网卡驱动程序。tdi驱动程序和系统的关系
miniport驱动程序包括驱动程序对象。驱动程序源代码和ndis接口库代码。windowsntddk提供ndis。h作为miniport驱动程序的主要头文件,定义了miniport驱动程序的入口点。ndis接口库函数和通用数据结构。
上边缘函数的作用是网卡驱动与ndis接口库进行通信,而下边缘函数是tdi协议驱动程序与ndis通信的手段。
§1。2。1miniport网卡对象
ndis用一个叫做逻辑网卡的软件对象来描述系统中的每块网卡,而逻辑网卡与windowsnt设备对象的通信由i/o子系统来管理,描述网卡的设备对象包括相关的网络信息如名字。网络地址和网卡内存基地址等,它还包含与硬件相关的驱动程序状态数据(捆绑数目,捆绑句柄,包过滤数据库等)。ndis分配一个句柄到miniportinitialize这个上边缘函数的一个结构中,然后miniport网卡驱动程序将在以后提供这个句柄来给ndis调用,这个结构一直被ndis保持,并且对miniport驱动程序不透明。
当miniport网卡驱动程序初始化一块网卡时,它创立自己的内部数据结构来描述网卡,记录需要它管理的与设备相关的状态信息。当miniport网卡驱动程序调用ndismsetatttibutes或ndismsetattributesex两ndis库函数时,它传递一个句柄给这数据结构。这样,当调用miniport驱动程序入口点时,它就传递这个句柄来验证驱动程序所对应的网卡的正确性。这个数据结构为miniport网卡驱动程序所拥有并维护。
§1。2。2网络对象标识符
miniportnic驱动程序还需要维护一组对象,这些对象是系统定义的对象标识符(objectidetifier:oid)来标识,以描述驱动程序的性能和当前状态信息。为查询这些信息,上层驱动程序调用ndisrequest向ndis接口库指示oid。oid表示了调用所需的信息类型,如miniport驱动程序所支持的lookahead缓冲区大小等。ndis接到上层驱动程序的查询请求,将oid传递给上边缘函数miniportqueryinformation实现对oid的查询,如果上层驱动程序请求改变状态信息则调用miniportsetinformation实现对oid的设置。
§1。2。3miniport网卡驱动程序代码
典型的miniportnic驱动程序必须有一些函数来通过ndis接口实现上层驱动程序与硬件的通信。这些函数称为上边缘服务函数。
这些上边缘服务函数由驱动程序的开发者根据驱动程序面向的特定低层网络类型和硬件以及相应环境,可以有选择地实现,但必须保证驱动程序最基本的功能,这些基本功能包括初始化。发送。中断处理。重置。参数查询与设置和报文接收。
miniportinitialize:操作系统根据系统配置信息,检测出网卡已安装时,由ndis接口在初始化时调用,主要完成低层网络类型确定,对应于物理网卡的逻辑网卡初始化,中断信息注册,网卡与主机通讯方式的确认。i/o端口的申请与注册,内存映像,mib的初始化,物理网卡的验证与初始化等。
miniportreconfigure:支持网卡参数动态变化,和miniportinitilize一样由ndis接口以初始化级别调度执行(不能屏蔽中断,必须由驱动程序承认并清除在此期间产生的中断),支持即插即用和软配置的网卡在动态改变参数时,必须提供此函数。
miniportqueryinformation:查询网卡的状态以及网卡驱动程序的操作或统计参数,如是否支持组通讯。网卡的物理速率是否支持回环。是否支持直接拷贝等,这些参数以oid方式统一管理。
miniportsetinformation:ndis接口或协议驱动程序通过调用此接口改变驱动程序维护的oid库,一些操作参数的改变也将同时改变驱动程序状态,例如组地址的设置。
miniportreset:包括网卡硬件重置和驱动程序软件重置,软件重置包括驱动程序状态重置,以及一些相关的参数重置,还需考虑有些参数的恢复,重置时不必完成所有正在活跃的外部请求,但必须释放已占用的外部资源。
miniporthalt:挂起网卡并释放该网卡驱动程序占用的所有资源,在此期间不屏蔽中断。
miniportisr:高优先级的中断处理程序,进行的工作包括初始中断处理类型,决定是否进行中断转交,对卡上中断进行处理等,该服务类型只在以下情况被调用:
ndis接口调用miniportinitialize和miniporthalt两函数时。
.中断处理类型设为每此中断处理过程都调用时。
为使系统能及时响应所有硬件中断,高优先级的硬件中断处理程序应尽可能的减少运行时间,防止长时间的屏蔽低优先级中断,避免造程中断丢失。
miniporthandleinterrupt:由中断延时处理程序在中断延时处理时进行调用。ndis排队所有的延时处理,该服务主要处理发送完成。报文接收。描述符用尽。溢出。网卡异常等中断。
miniportsend:ndis收到上层发送请求时经过若干协议处理再向下调用此服务过程,发送的packet已含有llc和mac头,该服务过程进行边界对齐。packet约束重整。描述符映射和报文发送。以及发送资源和packet缓冲队列管理。
miniporttransferdata:多个已和网卡捆绑的协议驱动程序在接收到报文到达指示后,向网卡驱动程序发出传送请求以拷贝各自所需的报文数据部分,网卡驱动程序根据各协议驱动程序对单个packet是否进行多次拷贝,以决定是否暂存只允许单次拷贝的packet等。
miniportcheckhandle:ndis每秒调用此服务函数一次,驱动程序发现网卡异常时报告给ndis由ndis调用miniportreset进行硬件重恢复。
miniportenableintrrupt:中断使能。
miniportdisableinterrupt:中断屏蔽。
另外,每个网卡驱动程序必须有一个初始化入口点,由driverentry函数实现,它和系统相关,由操作系统在装入驱动程序时调用,主要完成初始化ndiswrapper,再由wrapper初始生成驱动程序管理块并完成相应各种初始化工作,登录网卡驱动程序所有上边缘服务入口点,同时写入ndis版本信息。
§1。2。4ndis接口库
ndis接口库包括在ndis。sys中,它是一个核态函数库,有一套抽象的函数,无论协议驱动程序还是nic驱动程序都连接到这个库中,以实现上下层之间的操作。
第二章fddi网卡驱动程序的加载和运行
第一节网卡驱动程序的安装
windowsnt网卡驱动程序安装的目的是实现网卡相应硬件信息和驱动程序在windowsnt注册库中的注册,使windowsnt能够正确识别网卡,了解所必需的软硬件信息并能在windowsnt启动时加载相应驱动程序。
网卡驱动程序安装时,首先在主群组的控制面板中选择网络“,然后添加网卡,指定相应信息文件──oemsetup。inf的路径,以完成以下两个必要的操作:
复制驱动程序到相应的系统目录(windowsnt根目录system32drivers)中;
在windowsnt注册库中存入相应软硬件信息。
下面主要以fddi网卡为例介绍安装驱动程序所必需的工作:
§2。1。1网卡一般硬件参数
对于fddi网卡,必须在编写其oemsetup。inf文件时确定以下硬件参数:
总线类型:pci(5)……括号中的数字5表示pci总线在ndis中的总线类型代码;
厂商代号:0x5588……系统加载时确定网卡的标记,也是编程时确定pci槽号的标识;
cfid:0x01;
介质类型:光纤(3)……括号中的数字表示光纤在ndis中的介质类型代码;
是否支持全双工:支持。
对于其它的硬件信息在此inf配置信息文件中可有可无,如若配置,则可在驱动程序的编写时利用这些信息,方便编程,同时有利于其它应用对其参数的确定和使用。
§2。1。2fddi网卡加载时需在注册库登录表里做的网络配置
网卡驱动程序的安装通常将创建登录表中的四个不同子键:
softwareregistrion键,对应于驱动程序,存在于hkey_local_machinesoftwarecompanyproductnameversion中。我们的fddi网卡驱动程序所对应的是hkey_local_machinesoftwarenet612yhfddiyhfddi1。0;
网卡的软件登录键,存在于hkey_local_machinesoftwaremicrosoftwindowsntnt3。51networkcardsyhfddi1;
驱动程序的服务登录键,存在于hkey_local_machinesystemcurrentcontrolsetservices
网卡的服务登录键,存在于hkey_local_machinesystemcurrentcontrolsetservices
对于每一个网络部件,一个名为netrules的特殊子键在邻近的驱动程序或网卡登录子键里创建,netrules标识网络部件为网络整体的一部分。
fddi网卡驱动程序对应的标准软件登录表项将出现在以下路径:
hkey_local_machinesoftwarenet612yhfddiyhfddi1。0;
驱动程序对应的标准项的值为:
description=yhfddi/pciadaptercontroller
installdate=……
……
refcount=0x01
servicename=yhfddi
softwaretype=driver
title=yhfddi/pciadaptercontroller
而且在yhfddi驱动程序相关的netrules子键下,这些值项为:
bindable=yhfddidriveryhfddiadapternonexclusiver
bindform=yhfddisys“yesnocontainer
class=reg_multi_szyhfddidriverbasic“
infname=oemnad1。inf
type=yhfddisysndisdriveryhfddidriver
use=driver
yhfddi网卡在如下路径的networkcards子键里介绍:
hkey_local_machinesoftwaremicrosoft
windowsntnt3。51networkcardsyhfddi1;
网卡的标准项包括以下这些值:
description=yhfddi/pciadaptercontroller
installdate=……
manufacturer=net612
productname=yhfddi
servicename=yhfddi01
title=[01]yhfddi/pciadaptercontroller
§2。1。3编写inf信息配置文件
guiinf描述语言被windowsnt用以书写系统所有部件的配置文件,当然也可以用以书写网络系统各部件的配置文件,该配置文件描述了网络部件安装。配置。删除的执行过程。当网络部件进行初始安装或二次安装(通常通过ncpa进行)时,安装程序读取部件对应的配置文件,进行解释执行。guiinf描述语言由节。命令。逻辑操作。变量规范。流程控制以及一套调用dll或外部程序的机制组成,其中,节是配置文件的主体,节可分为install节(类似于函数),shell节(也类似于函数,但可调用insall和shell节),detect节(不包含命令),一个配置文件一般由若干不同类型的节组成。驱动程序的开发者根据需要可以在配置文件中编写相应代码,使得用户和系统之间能进行交互,并且由用户决定一些配置参数。
nt网卡配置文件有其一套规范,驱动程序开发者必须按规范编写配置文件,一般来说,一个配置文件至少应该提供下面三个节:
安装入口点:[identify]shell节。该节主要功能是给出安装部件的类型名,系统通过它识别该部件属于哪一大类(display,mouse,scsi,network等)中的哪一类(网络adapter,driver,transport,service,network和netprovidor),同时,还需要给出映像文件和配置文件所在的源介质及标识。
[returnoption]shell节。系统执行安装identify节后,执行该节。它主要功能是检查所需安装的部件是否支持的硬件平台和语言,并给出网卡名(有些配置文件支持多类网卡,此时必须让用户进行选择,并获得选择结果)。
[installoption]shell节。该节是配置文件得主体,也是上次安装完后再次进行配置。删除。更新的入口点。主要功能是拷贝映像文件和配置文件,生成配置的各种选项,创建该部件在注册库中对应的各种登录子树并更新重写。
第二节驱动程序的加载过程
§2。2。1windowsnt的启动过程
第一阶段:调入装入程序。和硬件平台相关,x86机器首先由rom装入根扇区,再由根扇区装入ntldr;
第二阶段:硬件检测。x86机器调ntdetect程序最大限度地获取各种硬件设备信息,引导hal及基本卷设备驱动程序,以便引导nt内核;
第三阶段:获取注册库中各种控制信息,如用户定义的非页内存大小;第四阶段:初始化注册库registrymachine下system和hardware并创建currentcontrolset,为装入相关硬件设备驱动程序作准备;
第五阶段:装入基本核心驱动程序;
第六阶段:释放一些已经完成使命的装入初始数据块;
第七阶段:进一步初始化注册库,以便有些依赖于基本核心驱动程序的上层驱动程序能顺利装入;
第八阶段:服务控制器装入应该由该服务控制器装入的各种驱动程序。
§2。2。2fddi网卡驱动程序的加载过程
在windowsnt启动的第五个阶段,将加载核心驱动程序。而对于ndis网卡驱动程序是在ndis接口(ndis。sys)加载后调入运行,向ndiswrapper注册。初始化。查询设置参数等。
windowsnt启动时,相应的实体如nt的服务控制器根据注册库中yhfddi驱动程序的配置注册信息,初始化ndiswrapper,并装入相应的驱动程序,生成驱动程序管理块结构,申请内存以保存各种信息,向ndiswrapper注册驱动程序。初始化和注册完毕后,再由服务控制器读取注册库中相应的链接信息。
在ndiswrapper和yhfddi驱动程序初始化和注册成功后,ndiswrapper根据系统相应的注册信息,加入和yhfddi驱动程序所对应的fddi网卡,同时读入网卡的注册信息,并进行网卡注册和网卡初始化。
在以上过程成功后,wrapper将查询和设置驱动程序的各种参数,了解驱动程序对哪些操作支持,决定对上层驱动程序的支持范围。
第三节fddi网卡驱动程序的注册
driverentry函数是windowsntddk规定的核心驱动程序的入口点,wrapper识别到入口点后,调入驱动程序,在driverentry函数内完成两个基本注册任务:
调用ndisminitializewapper函数向ndis接口报告驱动程序将以miniport类网卡驱动程序注册。ndis建立它需要记录的驱动程序状态信息,同时返回ndiswrapperhandle,驱动程序保存这个句柄,以利后来调用ndisxxxconfiguration和initialization等函数。
填写ndisxx_miniport_characteristics属性结构,主要记录ndis版本号和驱动程序支持的miniportxxx函数的入口点,然后调用ndismregisterminiport函数实现驱动程序的整体注册。
以yhfddi为例所要注册的属性结构的内容大致如下:
ndis_miniport_characteristicsyhfddichar;
(ndis_miniport_characteristics这个结构将在第三章介绍)
yhfddichar。majorndisversion=yhfddi_ndis_major_version;
yhfddichar。minorndisversion=yhfddi_ndis_minor_version;
这两个属性决定驱动程序是ndis的哪个版本所支持,我们所用的是ndis3。0
yhfddichar。disableinterrupthandler=yhfddidisableinterrupt;
yhfddichar。enableinterrupthandler=yhfddienableinterrupt;
yhfddichar。isrhandle=yhfddiinterruptservice;
yhfddichar。handleinterrupthandler=yhfddihandleinterrupt;
以上四项属性是中断处理所需的上边缘服务函数的入口点(句柄)。fddi网卡驱动程序需要有smt站管理功能,而smt是以中断处理方式进行的,故这四项属性在fddi网卡驱动程序中是很重要的。
yhfddichar。initializehandler=yhfddiinitialize;
此项注册的是驱动程序的初始化函数句柄。
yhfddichar。queryinformationhandler=yhfddiqueryinformation;
yhfddichar。setinformationhandler=yhfddisetinformation;
这两项注册的是参数查询和设置函数的句柄。
yhfddichar。sendhanler=yhfddisend;
yhfddichar。transferdatahandler=yhfdditransferdata;
主要提供数据发送和接收函数句柄。
yhfddichar。resethandler=yhfddireset;
此项注册网卡软硬件重置函数句柄。
yhfddichar。halthandler=yhfddihalt;
此项注册网卡驱动程序挂起函数句柄。
yhfddichar。checkforhandler=null;
yhfddichar。reconfigurehandler=null;
这两个上边缘服务函数是fddi网卡驱动程序所不提供的,故置为null。
填好这些结构以后,调用以下函数实现驱动程序的注册:
ndismregisterminiport(
yhfddiwrapperhandle,
yhfddichar,
sizeof(yhfddichar));
其中yhfddiwrapperhandle是在此之前初始化wrapper调用ndisminitializewrapper所得的句柄。
如果调用ndismregisterminiport不能返回ndis_status_success,必须在退出driverentry之前释放已经分配的资源(如yhfddiwrapperhandle等),故调用
ndisterminatewrapper(yhfddiwrapperhandle,null)。
这样驱动程序没能正确注册,亦不能正常运行。
第四节网卡驱动程序对象查询与设置
如果ndis的管理实体要查询或设置一个特定的网络对象,它必须提供一个32位的oid。oid的结构如下:图2。3。0oid结构图
由上可以看到,oid可分为三大类:
所有ndis驱动程序都有的一般对象;
特定介质的对象;
特殊的与具体实现相关的对象(如多目地址表的长度)。
一般的和特定介质的oid被记录在windowsntddk中,对于这些oidddk文本指明了相关的对象能否通过miniportqueryinformation查询参数和通过miniportsetinformation设置参数。
oid也可被分为操作特性(如多目地址表长度参数)和统计参数(如广播包接收)。最后oid可分为必须的和可选的两种。
oid的前三个字节表明oid的不同类别,而最后一个字节确定这一类别内特定的信息管理对象。
针对于fddi网卡,被查询的oid的第一个字节为0x03。而ndis所查询的介质相关参数为:
0x03010104oid_fddi_long_max_list_size
0x03010108oid_fddi_short_max_list_size
0x03010102oid_fddi_long_current_addr
0x03010106oid_fddi_short_current_addr
tcp/ip传输驱动程序所要查询的fddioid为:
0x03010102oid_fddi_long_current_addr
0x03010103oid_fddi_long_multicast_list
0x03010107oid_fddi_short_multicast_list
通过以上两阶段的查询,ndis和tcp/ip驱动程序就分别了解了网卡驱动程序对其的支持,从而进行相应的捆绑,以便数据传输时正确选择网卡驱动程序。
第五节开发环境与调试方法
开发环境:
fddi网卡驱动程序的开发环境为ntserver3。51,sdk,ddkforworkstation3。51,vc++4。1,硬件平台为586。
调试平台:
主机为ntserver3。51,windbg32
目标机为ntworkstation3。51(check944)
调试方法:
※利用dbgprint把目标机上关键信息通过串口传到主机进行分析,以得出ndis驱动程序的调度机制和运转状况;
※利用assert产生异常断点,由主机对异常进行控制
※自定义宏,进行分级控制,以根据不同情况产生不同调试信息
第四章与smt移植相关的问题讨论
在本yhfddi网卡驱动程序中,smt的移植是极其关键的一部分,主要承担了驱动程序中硬件初始化和中断延迟处理。但由于smt是相对独立的软件,这样就有一个ndiswrapper与smt间参数传递的问题。所以本章主要讨论miniport驱动程序与smt的关系和移植smt过程中初始化的要求。中断处理的要求,ndiswrapper与smt如何传递参数。
(一)miniportfddi网卡驱动程序与smt的关系。
在第一章已经谈及网卡驱动程序主要实现osi参考模型中的物理层和mac层。而对于fddi网络的物理层又可分为介质相关子层和介质无关子层。
对于我们的fddi/pci是x。3。19。x3。148。x3。166和x3。229而实现的。
smt在整个iso七层模型中属低两层范畴。下图是iso模型与fddi层次的对应关系,从而可知fddiminiport驱动程序在nt网络结构中的位置。
即在windowsntfddi网卡驱动程序应包含smt,实现fddi拓扑环上的站管理。
而在驱动程序内部smt主要是在miniport驱动程序中的中断延迟处理上边缘服务中实现的,也可以说是将smt嵌入中断延迟处理程序中,实现ndis接口对smt的正确调度。
yh-fddi驱动程序的实现可分为硬件无关部分和硬件相关部分。
移植smt过程中初始化的要求。
这里的初始化主要是指硬件初始化,包括寄存器的初始化和数据结构的初始化,由smt共用的硬件相关例程库中硬件初始化部分来完成。我们在开发过程序是调用fddi_main(bdd_t星号bdd)这个函数来调用smt共用的硬件相关例程库的。可见使用fddi_main(bdd_t星号bdd)时,需要传递bdd这个参量,而bdd_t这个数据结构的定义如下:
它包含了各类硬件寄存器的基址,所以要对其进行正确赋值就必须首先在nt的内存中映射一块虚存与网卡内存相对应,也就实现了bdd_t结构的赋值,对fddi_main(bdd_t星号bdd)的正确调用。
因此,我们在调用fddi_main前首先将网卡上寄存器内存空间映射到nt的虚存空间上,并将bdd结构正确赋值。以映射bsi_phy_base为例,具体过程如下:
pchardestination;
bdd_t星号bdd;
ndis_physical_addressphysicaladdress;
ulongbaseaddress;
ndis_statusstatus;
baseadress=0x0d0000+bsi_phy_base;
ndissetphysicaladdresshigh(physicaladdress,0);
ndissetphysicaladdresslow(physicaladdress,baseaddress);
status=ndismmapiospace(
(pvoid星号) destination,
miniportadapterhandle,
physicaladdress,
bsi_phy_len
);
bdd->bsi_vir_base=(pchar)destination;
adapter->bdd->bsi_vir_base=bsi_vir_base;
/星号对adapter结构中的bdd结构赋值,以便在其它上边缘函数中使用这些虚存基地址星号/
中断处理要求。
对于中断处理,在smt中主要调用cspintrhandandler()来实现。我们的fddi网卡驱动程序是miniport方式的,若在isr中做此处理将占用大量系统资源,使系统崩溃,所以我们采用只在isr中进行中断的排队,而在dpc中调用cspintrhandler()来完成中断处理。
在中断处理方面还有一个中断屏蔽和中断使能的问题,这两方面smt并不提供,故我们要正确处理。
具体处理方法见第三章。
ndiswrapper与smt间参数如何传递。
miniport方式的网卡驱动程序中,网卡上有中断时,系统反映给ndiswrapper,再由wrapper调度中断处理上边缘服务实现中断处理,在我们的yhfddi网卡驱动程序的中断具体处理是smt完成的所以在调用cspintrhandler时应将adapter结构传进smt以便在以后应用。
如在处理接收中断时,处理的最后应调用ndisindicatefddireceive,向ndiswrapper指示以接收到一个数据包,而ndisindicaterfddireceive的调用需要adapterminiporthandle作为参数,这就必须一级级从中断延迟处理函数(yhfddihandleinterrupt)中将adapter结构传递下来。当然,其它方面如发送,也会有类似的问题需要考虑。
总之,对于smt的移植,需要详尽的在程序中做好接口,才能实现与
smt的数据交换。
结束语
ndis规范在网络两层间提供了一个统一界面,ndis对网络本身而言,是一个带有协议功能的标准接口,对实现者而言,它应该是一个环境,这种环境不仅带有协议功能,更重要的是带有和软。硬平台无关的核心功能支持,它不会受软。硬平台的变化严重影响,无疑,它是软件的移植和兼容的可靠保证,ndis把网络的一部分共性抽象出来,并根据具体的操作系统实现系统和平台相关的基础库以保证ndis的标准性和对开发者提供最大的功能支持,这也将加速和规范开发过程,但是,在操作系统之上提供ndis基础库获得标准同时也失去直接作用于操作系统带来的灵活性以及更强的功能支持,同时,ndis处于网络中层和低层之间,低层网络的快速发展和ndis对网络部分共性的抽象必然导致ndis对实现者的滞后,例如ddk3。51提供的ndis开发环境只支持10m以太网。fddi。令牌网(802。5)。localtalk。arcnet等,而对新出现的快速以太网及atm不提供支持,这对我们如何在ndis环境下实现诸如atm的lanemulation,ipoveratm。快速以太网带来很大问题。
smt是实现fddi网卡驱动程序的关键,然而由于应用ddk开发miniport驱动程序时要遵循其结构框架,所以要想完整地按其结构移植smt,就必须分解smt适应之,即要求对smt有一个很好的理解。但smt是庞大的给开发带来了一定的困难。
参考文献
[1]devicedriverkit用户手册
[2]devicedriverkit核心驱动程序设计
[3]devicedriverkit网络驱动程序设计
[4]windowsnt核心内幕
[5]windowsnt资源之三性能评测