windowsnt環境下fddi網卡驅動程序設計(2)
未知
第三階段:獲取注冊庫中各種控制信息,如用戶定義的非頁內存大小;第四階段:初始化注冊庫 \registry\machine下system和hardware并創建currentcontrolset,為裝入相關硬件設備驅動程序作準備;
第五階段:裝入基本核心驅動程序;
第六階段:釋放一些已經完成使命的裝入初始數據塊;
第七階段:進一步初始化注冊庫,以便有些依賴于基本核心驅動程序的上層驅動程序能順利裝入;
第八階段:服務控制器裝入應該由該服務控制器裝入的各種驅動程序。
§2.2.2 fddi網卡驅動程序的加載過程
在windows nt啟動的第五個階段,將加載核心驅動程序。而對于ndis網卡驅動程序是在ndis接口(ndis.sys)加載后調入運行,向ndis wrapper注冊、初始化、查詢設置參數等。
windows nt啟動時,相應的實體如nt的服務控制器根據注冊庫中yhfddi驅動程序的配置注冊信息,初始化ndis wrapper,并裝入相應的驅動程序,生成驅動程序管理塊結構,申請內存以保存各種信息,向ndis wrapper注冊驅動程序。初始化和注冊完畢后,再由服務控制器讀取注冊庫中相應的鏈接信息。
在ndis wrapper和yhfddi驅動程序初始化和注冊成功后,ndis wrapper根據系統相應的注冊信息,加入和yhfddi驅動程序所對應的fddi網卡,同時讀入網卡的注冊信息,并進行網卡注冊和網卡初始化。
在以上過程成功后,wrapper將查詢和設置驅動程序的各種參數,了解驅動程序對哪些操作支持,決定對上層驅動程序的支持范圍。
第三節fddi網卡驅動程序的注冊
driverentry函數是windows nt ddk規定的核心驅動程序的入口點,wrapper識別到入口點后,調入驅動程序,在driverentry函數內完成兩個基本注冊任務:
調用ndisminitializewapper函數向ndis接口報告驅動程序將以miniport類網卡驅動程序注冊。ndis建立它需要記錄的驅動程序狀態信息,同時返回ndiswrapperhandle,驅動程序保存這個句柄,以利后來調用ndisxxxconfiguration和initialization等函數。
填寫ndisxx_miniport_characteristics屬性結構,主要記錄ndis版本號和驅動程序支持的miniportxxx函數的入口點,然后調用ndismregisterminiport函數實現驅動程序的整體注冊。
以yhfddi為例所要注冊的屬性結構的內容大致如下:
ndis_miniport_characteristics yhfddichar;
(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.0 oid結構圖
由上可以看到,oid可分為三大類:
所有ndis驅動程序都有的一般對象;
特定介質的對象;
特殊的與具體實現相關的對象(如多目地址表的長度)。
一般的和特定介質的oid被記錄在windows nt ddk中,對于這些oid ddk文本指明了相關的對象能否通過miniportqueryinformation查詢參數和通過miniportsetinformation設置參數。
oid也可被分為操作特性(如多目地址表長度參數)和統計參數(如廣播包接收)。最后oid可分為必須的和可選的兩種。
oid的前三個字節表明oid的不同類別,而最后一個字節確定這一類別內特定的信息管理對象。
針對于fddi網卡,被查詢的oid的第一個字節為0x03。而ndis所查詢的介質相關參數為:
0x03010104 oid_fddi_long_max_list_size
0x03010108 oid_fddi_short_max_list_size
0x03010102 oid_fddi_long_current_addr
0x03010106 oid_fddi_short_current_addr
tcp/ip傳輸驅動程序所要查詢的fddi oid為:
0x03010102 oid_fddi_long_current_addr
0x03010103 oid_fddi_long_multicast_list
0x03010107 oid_fddi_short_multicast_list
通過以上兩階段的查詢,ndis和tcp/ip驅動程序就分別了解了網卡驅動程序對其的支持,從而進行相應的捆綁,以便數據傳輸時正確選擇網卡驅動程序。
第五節 開發環境與調試方法
開發環境:
fddi網卡驅動程序的開發環境為nt server 3.51,sdk,ddk for workstation 3.51, vc++4.1,硬件平臺為586。
調試平臺:
主機為nt server 3.51,windbg32
目標機為nt workstation3.51 (check 944)
調試方法:
※利用dbgprint把目標機上關鍵信息通過串口傳到主機進行分析,以得出ndis驅動程序的調度機制和運轉狀況;
※利用assert產生異常斷點,由主機對異常進行控制
※自定義宏,進行分級控制,以根據不同情況產生不同調試信息
第四章 與smt移植相關的問題討論
在本yhfddi網卡驅動程序中,smt的移植是極其關鍵的一部分,主要承擔了驅動程序中硬件初始化和中斷延遲處理。但由于smt是相對獨立的軟件,這樣就有一個ndis wrapper與smt間參數傳遞的問題。所以本章主要討論miniport驅動程序與smt的關系和移植smt過程中初始化的要求、中斷處理的要求,ndis wrapper與smt如何傳遞參數。
(一)miniport fddi網卡驅動程序與smt的關系。
在第一章已經談及網卡驅動程序主要實現osi參考模型中的物理層和mac層。而對于fddi網絡的物理層又可分為介質相關子層和介質無關子層。
對于我們的fddi/pci是基于x.3.19、x3.148、x3.166和x3.229而實現的。
smt在整個iso七層模型中屬低兩層范疇。下圖是iso模型與fddi層次的對應關系,從而可知fddi miniport驅動程序在nt網絡結構中的位置。
即在windows nt fddi網卡驅動程序應包含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為例,具體過程如下:
pchar destination;
bdd_t *bdd;
ndis_physical_address physicaladdress;
ulong baseaddress;
ndis_status status;
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并不提供,故我們要正確處理.
具體處理方法見第三章.
ndis wrapper與smt間參數如何傳遞.
miniport方式的網卡驅動程序中,網卡上有中斷時,系統反映給ndiswrapper,再由wrapper調度中斷處理上邊緣服務實現中斷處理,在我們的yhfddi網卡驅動程序的中斷具體處理是smt完成的所以在調用cspintrhandler時應將adapter結構傳進smt以便在以后應用.
如在處理接收中斷時,處理的最后應調用ndisindicatefddireceive,向ndiswrapper指示以接收到一個數據包,而ndisindicaterfddireceive的調用需要adapterminiporthandle作為參數,這就必須一級級從中斷延遲處理函數(yhfddi handleinterrupt)中將adapter結構傳遞下來. 當然,其它方面如發送,也會有類似的問題需要考慮.
總之,對于smt的移植,需要詳盡的在程序中做好接口,才能實現與
smt的數據交換.
結束語
ndis規范在網絡兩層間提供了一個統一界面,ndis對網絡本身而言,是一個帶有協議功能的標準接口,對實現者而言,它應該是一個環境,這種環境不僅帶有協議功能,更重要的是帶有和軟、硬平臺無關的核心功能支持,它不會受軟、硬平臺的變化嚴重影響,無疑,它是軟件的移植和兼容的可靠保證,ndis把網絡的一部分共性抽象出來,并根據具體的操作系統實現系統和平臺相關的基礎庫以保證ndis的標準性和對開發者提供最大的功能支持,這也將加速和規范開發過程,但是,在操作系統之上提供ndis基礎庫獲得標準同時也失去直接作用于操作系統帶來的靈活性以及更強的功能支持,同時,ndis處于網絡中層和低層之間,低層網絡的快速發展和ndis對網絡部分共性的抽象必然導致ndis對實現者的滯后,例如ddk3.51提供的ndis開發環境只支持10m以太網、fddi、令牌網(802.5)、localtalk、arcnet等,而對新出現的快速以太網及atm不提供支持,這對我們如何在ndis環境下實現諸如atm的lan emulation,ip over atm、快速以太網帶來很大問題。
smt是實現fddi網卡驅動程序的關鍵,然而由于應用ddk開發miniport驅動程序時要遵循其結構框架,所以要想完整地按其結構移植smt,就必須分解smt適應之,即要求對smt有一個很好的理解。但smt是龐大的給開發帶來了一定的困難。
參考文獻
【1】《device driver kit用戶手冊》
【2】《device driver kit核心驅動程序設計》
【3】《device driver kit網絡驅動程序設計》
【4】《windows nt核心內幕》
【5】《windows nt資源》之三《性能評測》