資源描述:
《Linux網(wǎng)卡驅(qū)動分析(精品)》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在工程資料-天天文庫。
1、Linux網(wǎng)卡驅(qū)動分析學(xué)習(xí)應(yīng)該是一個先把問題簡單化,在把問題復(fù)雜化的過程。一開始就著手處理復(fù)雜的問題,難免讓人有心驚膽顫,捉襟見肘的感覺。讀Linux網(wǎng)卡驅(qū)動也是一樣。那長長的源碼夾雜著那些我們陌牛?的變量和符號,望而生畏便是理所當(dāng)然的了。不要擔(dān)心,事情總有解決的辦法,先把一些我們管不著的代碼切割出去,留下必須的部分,把框架掌握了,哪其他的事情自然就水到渠成了,這是筆者的心得。-般在使用的Linux網(wǎng)卡驅(qū)動代碼動輒3000行左右,這個代碼量以及它所表達(dá)出來的知識量無疑是龐大的,我們有沒有辦法縮短一卜-這個代碼量,使我們的學(xué)習(xí)變的簡單些呢,經(jīng)
2、過筆者的不懈努力,在仍然能夠使網(wǎng)絡(luò)設(shè)備正常工作的前提下,把它縮減到了60()多行,我們把暫時還用不上的功能先割出去。這樣一來,事情就簡單多了,真的就剩下一個框架了(欲索取者請通過xhbbs@tom.com聯(lián)系我)。下面我們就來剖析這個可以執(zhí)行的框架。限于篇幅,以下分析用到的所有涉及到內(nèi)核中的函數(shù)代碼,我都不予列出,但給出在哪個貝-體文件中,請讀者口行査閱。首先,我們來看看設(shè)備的初始化。當(dāng)我們正確編譯完我們的程序示,我們就需要把生成的目標(biāo)文件加載到內(nèi)核屮去,我們會先ifconfigethOdown和rmmod8139too來卸載止在使用的網(wǎng)卡
3、驅(qū)動,然后insmod8139too.o把我們的驅(qū)動加載進去(其中8139too.o是我們編譯生成的冃標(biāo)文件)。就像C程序冇主函數(shù)main()一樣,模塊也有第一個執(zhí)行的函數(shù),即module_init(rtl8139_init_module);在我們的程序'I1*rtl8139_init_module()在insmod之后首先執(zhí)行,它的代碼如下:staticint_initrtl8139_init_module(void){returnpci_module_init(&rtl8139_pci_driver);}它總接調(diào)用了pci_module
4、_init(),這個函數(shù)代碼在Linux/drivers/net/eepro1OO.c中,并且把rtl8139_pci_drivcr(這個結(jié)構(gòu)是在我們的驅(qū)動代碼里定義的,它是驅(qū)動程序和PCI設(shè)備聯(lián)系的紐帶)的地址作為參數(shù)傳給了它。rtl8139_pci_driver定義如下:staticstructpci_driverrtl8139_pci_driver={name:MODNAME,id_table:rtl8139_pci_tbl,probe:rtl8139_init_one,remove:rtl8139_rcmovc_onc,};pci_
5、module_init()在張動代碼里沒有定義,你一定想到了,它是Linux內(nèi)核提供給模塊是一個標(biāo)準(zhǔn)接口,那么這個接口都干了些什么,筆者跟蹤了這個函數(shù)。里血?調(diào)用了pci_register_driver(),這個函數(shù)代碼在Linux/drivers/pci/pci.c屮,pci_register_driver做了三件事情。①是把帶過來的參數(shù)rtl8139_pci_driver在內(nèi)核中進行了注冊,內(nèi)核中冇一個PCI設(shè)備的大的鏈表,這里負(fù)責(zé)把這個PCI驅(qū)動掛到里面去。②是查看總線上所有PCI設(shè)備(網(wǎng)卡設(shè)備屬于PCI設(shè)備的一?種)的配置空間如呆發(fā)
6、現(xiàn)標(biāo)識信息與rtl8139_pci_drivcr中的id_tablc相同即rtl8139_pci_tbl,而它的定義如下:staticstructpci_dcvicc_idrtl8139_pci_tbl[]_devinitdata={{OxlOec,0x8129,PCI_ANY_ID,PCI_ANY_ID,0,0,1},{PCI_ANYJD,0x8139,Ox1Oec,0x8139,0,0,0},{0,}};,那么就說明這個驅(qū)動程序就是用來驅(qū)動這個設(shè)備的,于是調(diào)川rtl8139_pci_driver中的probe兩數(shù)即rtl8139_ini
7、t_one,S個函數(shù)是在我們的驅(qū)動程序屮定義了的,它是川來初始化整個設(shè)備和做一些準(zhǔn)備工作。這里需要注意一下pci_device_id是內(nèi)核定義的用來辨別不同PCI設(shè)備的一個結(jié)構(gòu),例如在我們這里OxlOcc代表的是Rcaltck公司,我們掃描PCI設(shè)備配置空間如果發(fā)現(xiàn)有Realtek公同制造的設(shè)備時,兩者就對上了。當(dāng)然對上了公司號后還得看其他的設(shè)備號什么的,都対上了才說明這個驅(qū)動是可以為這個設(shè)備服務(wù)的。①是把這個rtl8139_pci_driver結(jié)構(gòu)掛在這個設(shè)備的數(shù)據(jù)結(jié)構(gòu)(pci_dev)上,表示這個設(shè)備從此就有了自己的驅(qū)動了。而驅(qū)動也找到
8、了它服務(wù)的對象了。PCI是一個總線標(biāo)準(zhǔn),PCI總線上的設(shè)備就是PCI設(shè)備,這些設(shè)備冇很多類型,當(dāng)然也包括網(wǎng)卡設(shè)備,每一個PCI設(shè)備在內(nèi)核中抽彖為一個數(shù)據(jù)結(jié)構(gòu)pci.dev,它描述