freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

linux下網(wǎng)絡(luò)驅(qū)動程序設(shè)計與開發(fā)(參考版)

2025-07-10 11:57本頁面
  

【正文】 數(shù)據(jù)接收的最后一個步驟是通過調(diào)用 if_rx()函數(shù)來完成的,它負(fù)責(zé)將已經(jīng)處理過的套接字緩沖區(qū)傳遞給上層軟件。最后,驅(qū)動程序更新其統(tǒng)計計數(shù)器,以記錄已經(jīng)接收的每個數(shù)據(jù)包。為此必須在將緩沖區(qū)傳遞到上層之前,對 dev 和 protocol 成員正確賦值,而對 dev 的設(shè)置前面已經(jīng)討論過了。套接字緩沖區(qū)中有一個非常重要的字段 protocol,它代表的是協(xié)議類型。確定了設(shè)備后我們才能通過 dev_priv(dev)函數(shù)來獲取設(shè)備的私有數(shù)據(jù)結(jié)構(gòu)priv。數(shù)據(jù)的接收需要將從設(shè)備上得到的數(shù)據(jù)放入設(shè)備自己的套接字緩沖區(qū)中,最后提交給上層軟件處理。超時處理函數(shù)由 _device 結(jié)構(gòu)中的 tx_timeout 函數(shù)指針指向,在 BCM5464 的驅(qū)動程序中,該函數(shù)為 rmi_phnx_mac_tx_timeout,該函數(shù)負(fù)責(zé)重新設(shè)置數(shù)據(jù)傳輸時間、統(tǒng)計錯誤信息,并啟動端口的傳輸隊(duì)列。為了控制超時后數(shù)據(jù)可以被再次傳輸,驅(qū)動程序需要設(shè)置一個超時周期,該周期在 _device 結(jié)構(gòu)的 watchdog_timeo 中設(shè)置。一旦設(shè)備內(nèi)存填充到容不下最大可能的數(shù)據(jù)包的時候,驅(qū)動程序就要停止,直到空間再次可用為止。if_wake_queue()函數(shù)與前面在在討論設(shè)備端口打開時調(diào)用的if_start_queue()函數(shù)大致功能一樣。數(shù)據(jù)包的傳輸被停止后,還必須要在將來某個時刻設(shè)備接口能夠再次接收數(shù)據(jù)包傳輸時重新啟動該隊(duì)列。由于數(shù)據(jù)的傳輸是異步的傳輸?shù)?,而且可用來保存外發(fā)數(shù)據(jù)包的存儲空間有限,在內(nèi)存被耗盡時,驅(qū)動程序需要告訴網(wǎng)絡(luò)系統(tǒng)在硬件能夠接收新數(shù)據(jù)之前,不能啟動其他的數(shù)據(jù)包傳輸。在進(jìn)行數(shù)據(jù)傳輸時,負(fù)責(zé)傳輸?shù)姆椒ㄒ紫却_認(rèn)當(dāng)前的是哪一個線程在進(jìn)行數(shù)據(jù)的傳輸。傳遞給 rmi_phnx_mac_xmit 的套接字緩沖區(qū)包含了物理數(shù)據(jù)包,并且擁有完整的的傳輸層數(shù)據(jù)包頭,接口不需要修改待傳輸?shù)臄?shù)據(jù),skbdata 指向的就是要傳輸?shù)臄?shù)據(jù)包。內(nèi)核處理的每個數(shù)據(jù)包都位于一個套接字緩沖區(qū)結(jié)構(gòu) sk_buf 中,對于該結(jié)構(gòu)的細(xì)節(jié),在第二章中已經(jīng)闡述過,限與篇幅這里就不再重新討論了。設(shè)備關(guān)閉后不應(yīng)該再有數(shù)據(jù)傳輸?shù)墓δ?,所以關(guān)閉設(shè)備時還要停止端口的傳輸隊(duì)列,這一操作調(diào)用的是 if_start_queue(dev)的逆操作函數(shù)if_stop_queue(dev)來實(shí)現(xiàn)的,通過它來標(biāo)記設(shè)備不能傳輸數(shù)據(jù)包了。究其原因來講,如同前面討論的一樣,該主設(shè)備的處理器是一個多核多線程的設(shè)備,所以只能通過調(diào)用 del_timer_sync 來確保在返回時沒有任何 CPU 在運(yùn)行定時器函數(shù)。設(shè)備要關(guān)閉,首先讓端口不可用,即進(jìn)行使能的逆操作,使端口不能進(jìn)行數(shù)據(jù)的發(fā)送和接收。設(shè)備的關(guān)閉與設(shè)備的打開的操作是互逆的,要完成的工作很少,不象打開時那么的復(fù)雜,但是有些操作卻不是和打開時一樣的。如果沒有解除自旋鎖,系統(tǒng)將出現(xiàn)”panic”甚至崩潰。前面曾提到,設(shè)備端口的打開是在自旋鎖的保護(hù)下進(jìn)行的,現(xiàn)在已經(jīng)完成了設(shè)備的初始化急打開任務(wù),就必須解除自旋鎖。端口配置完畢,要使端口可以正常的工作,我們必須使能端口,即讓端口可以接收或者發(fā)送數(shù)據(jù),并將將這一關(guān)鍵設(shè)置的值寫入到寄存器,讓內(nèi)核知道該端口可以正常工作了。前面介紹過,端口的速率以及雙工能力是通過 MII 接口從 PHY 寄存器中獲取出來的,但是我們在設(shè)備打開時,可以重新根據(jù)具體的需求進(jìn)行配置,以盡可能的充分利用硬件資源同時滿足我們的實(shí)際需要。內(nèi)核定時器初始化,并且添加到內(nèi)核的一個合適的定時器鏈表中,內(nèi)核就會在定時器時間到達(dá)時調(diào)用定時器的回調(diào)函數(shù),在驅(qū)動程序中,定時器執(zhí)行的回調(diào)函數(shù)是 rmi_phnx_mac_timer。void init_timer(struct timer_list * timer)。unsigned long data。struct timer_list {…unsigned long expires。但在什么時候去檢測鏈路的這些變化,就需要一個定時器來確定。通常情況下,網(wǎng)絡(luò)接口只是接收 MAC 目的地址是自己或者廣播的數(shù)據(jù)包,但在專用網(wǎng)絡(luò)設(shè)備上,我們可以通過改變網(wǎng)卡的這一能力,讓它接收任何其它的數(shù)據(jù)包,例如,我們在進(jìn)行網(wǎng)絡(luò)偵測的時候,就需要網(wǎng)卡可以接收流經(jīng)網(wǎng)絡(luò)的所有數(shù)據(jù)包。網(wǎng)絡(luò)設(shè)備的任務(wù)就是完成數(shù)據(jù)包的接收和發(fā)送,在設(shè)備開始工作之前,我們必須要向系統(tǒng)申請緩沖區(qū),來保存數(shù)據(jù)包,值得注意的是,我們并不需要為待發(fā)送的數(shù)據(jù)申請緩沖區(qū)。很多網(wǎng)絡(luò)設(shè)備驅(qū)動程序?qū)⒃O(shè)備的部分初始化操作也放在了設(shè)備打開的時候完成,但是考慮到 BCM5464 是多端口的芯片,初始化的操作是在打開之前完成了的,因此設(shè)備打開的任務(wù)就相對的比較簡單了。但是在接口能傳遞數(shù)據(jù)包之前,內(nèi)核必須打開接口并賦予接口地址,在接口改變地址、I/O 地址、irq 等時必須先關(guān)閉設(shè)備。在向系統(tǒng)注冊網(wǎng)絡(luò)接口之前,我們必須要完成接口的初始化,否則在注冊時,系統(tǒng)會 panic 甚至崩潰,這也是為什么驅(qū)動程序在向系統(tǒng)注冊設(shè)備之前必須完成初始化的原因。 注冊、打開、關(guān)閉設(shè)備網(wǎng)絡(luò)設(shè)備完成初始化以后,系統(tǒng)還無法使用該設(shè)備,因?yàn)榇藭r設(shè)備還沒有向系統(tǒng)申明自己的存在,也即是向系統(tǒng)內(nèi)核注冊網(wǎng)絡(luò)設(shè)備。在驅(qū)動程序中,為了能在多處理器上同步執(zhí)行,在設(shè)備的私有數(shù)據(jù)結(jié)構(gòu)中設(shè)置了 privspill_configured這個特征值,在初始化時,該值設(shè)置為 0,表示還沒有被初始化,而一但設(shè)備驅(qū)動程序被執(zhí)行后,該字段的值被重新設(shè)置為 1,任何時候要執(zhí)行設(shè)備的初始化,都必須先檢測該字段,如果該值為 1,則表明已經(jīng)初始化,否則進(jìn)行初始化操作。驅(qū)動程序的私有數(shù)據(jù)結(jié)構(gòu)中,有一個比較陌生的成員 privspill_configured,這個字段在大多數(shù)的網(wǎng)絡(luò)設(shè)備驅(qū)動程序中不能看到的。開發(fā)板上芯片在生產(chǎn)制造時,確立了 phnx_mac 各個字段的值,我們只能引用它們,而不應(yīng)該試圖去修改,但是中斷號 irq 是可以通過用戶空間的 ifconfig 命令修改的。各個字段分別表示端口的物理地址、端口類型、中斷號、以及 I/O 偏移量。unsigned long phnx_io_offset。int type。前面已經(jīng)提及到,priv 是網(wǎng)卡設(shè)備的私有結(jié)構(gòu)的指針,用于保存和控制設(shè)備特征的信息以及芯片的每個端口的信息。privphy_addr = gmac_id_to_phy_addr(privinstance)。privinstance = phnx_mac_devices[i].instance。在程序中,在自旋鎖狀態(tài)下執(zhí)行的代碼都非常的簡短,一般都只有幾行,這樣就是為了減少擁有自旋鎖的時間,提高整個系統(tǒng)的性能。因?yàn)閾碛凶孕i的時間越長,其他處理器就不得不自旋以等待該自旋鎖的時間就越長,而它不得不永遠(yuǎn)自旋的可能性就越大。在正確使用的情況下,自旋鎖通??梢蕴峁┍刃盘柫扛叩男阅?。在 BCM5464 的網(wǎng)卡驅(qū)動程序中,對設(shè)備的互斥訪問是通過自旋鎖來實(shí)現(xiàn)的,而沒有采用普通的信號量機(jī)智。privlock)。在設(shè)置默認(rèn)值時,數(shù)據(jù)包傳輸隊(duì)列中 tx_queue_len 排隊(duì)的最大幀數(shù)目設(shè)置為了 1000,但是由于芯片的吞吐性能良好,因此在設(shè)備初始化時驅(qū)動程序把該值設(shè)置為了 10000,相比原來的最大幀數(shù)目增大了 10 倍,如果不這樣修改的話,將會浪費(fèi)很多的系統(tǒng)內(nèi)存。dev_watchdog_timeo 是網(wǎng)絡(luò)層在確定了數(shù)據(jù)傳輸已經(jīng)超時,并且調(diào)用驅(qū)動程序的數(shù)據(jù)傳輸超時處理函數(shù)之前的最小時間,在驅(qū)動程序中該函數(shù)就是上面注冊的rmi_phnx_mac_tx_timeout()函數(shù),這里被設(shè)置為 1000*HZ。devtx_queue_len = 10000。devchange_mtu = rmi_phnx_mac_change_mtu。devdo_ioctl = rmi_phnx_mac_do_ioctl。devget_stats = rmi_phnx_mac_get_stats。devhard_start_xmit = rmi_phnx_mac_xmit。設(shè)備要完成數(shù)據(jù)的接收和發(fā)送,僅僅依靠以太網(wǎng)默認(rèn)的回調(diào)函數(shù)還不能完成的,驅(qū)動程序還必須要有自己的回調(diào)函數(shù),以此充分利用設(shè)備性能,提高設(shè)備工作的效率。devmem_end = mmio_start + PHOENIX_IO_SIZE 1。這些值在設(shè)置以后,可以在我們自己的驅(qū)動程序中,根據(jù)需要重新定義或者賦值。正如我們所看到的一樣,廣播地址是 48bit 的全1(0xFF)的地址。設(shè)備結(jié)構(gòu)體值的初始化主要是針對了以太網(wǎng)特征,包括了設(shè)備類型、頭部長度、最大傳輸單元、物理地址長度、傳輸隊(duì)列容量以及接口標(biāo)志。ether_setup(dev);上面這個步驟是以太網(wǎng)網(wǎng)卡設(shè)備指針在進(jìn)行自己特有的初始化之前,對設(shè)備結(jié)構(gòu)體的大部分值使用以太網(wǎng)默認(rèn)值進(jìn)行初始化,具體的包括:devchange_mtu= eth_change_mtu;devhard_header= eth_header;devrebuild_header = eth_rebuild_header;devset_mac_address= eth_mac_addr;devhard_header_cache = eth_header_cache;devheader_cache_update= eth_header_cache_update;devhard_header_parse = eth_header_parse;devtype= ARPHRD_ETHER;devhard_header_len= ETH_HLEN;devmtu= ETH_DATA_LEN;devaddr_len= ETH_ALEN;devtx_queue_len = 1000;devflag= IFF_BROADCAST|IFF_MULTICAST;memset(devbroadcast,0xFF, ETH_ALEN);分析上面的代碼,很容易的看出,在 ether_setup 中所進(jìn)行的初始化操作。 初始化設(shè)備成員和函數(shù)完成了設(shè)備對資源的申請,就應(yīng)該對設(shè)備進(jìn)行初始化或者賦值了。在使用中斷前要先請求一個中斷通道,然后在使用完后釋放該通道。在大多數(shù)情況來講,一個驅(qū)動程序只需要為它自己設(shè)備的中斷注冊一個中斷處理例程,并且在中斷到達(dá)時進(jìn)行正確的處理。request_irq(devirq,rmi_phnx_mac_int_handler,SA_INTERRUPT, devname, dev);盡管有很多設(shè)備只是通過他們的 I/O 寄存器就可以得到控制,但實(shí)際使用中的大部分設(shè)備都要是無法這樣實(shí)現(xiàn)的,還必須依靠中斷。mmio_start =phoenix_io_base + phnx_mac_devices[i].phnx_io_offset;privmmio = (phoenix_reg_t *) mmio_start;訪問該 I/O 內(nèi)存不是通過頁表訪問來實(shí)現(xiàn)的,而是直接訪問的,主要有利于提高數(shù)據(jù)傳輸?shù)男?。為了性能和靈活性方面的考慮,linux 沒有直接返回網(wǎng)卡私有數(shù)據(jù)結(jié)構(gòu)。通過分析 alloc_etherdev()函數(shù)我們知道,alloc_etherdev()函數(shù)其實(shí)沒有做什么事,只是簡單的調(diào)用了 alloc_dev()函數(shù)。在設(shè)備完成注冊以后,%d 將被一個從 0 開始的可用數(shù)字替代,使之成為唯一的名字。由于芯片內(nèi)有四路接口,因此需要循環(huán)初始化過程四次,以便完成對所有接口的初始化。instance 的值代表了端口,四個端口的 instance 值分別為11116,這四個值是由芯片生產(chǎn)時設(shè)置的,驅(qū)動程序不應(yīng)該試圖修改它。例如,鏈路狀態(tài)、物理地址、以及端口速率和雙工通信能力等信息。在初始化之前先定義了指向網(wǎng)絡(luò)設(shè)備的指針、指向設(shè)備私有數(shù)據(jù)塊的指針以及/proc 入口項(xiàng):struct _device *dev = 0;struct driver_data *priv = 0;struct proc_dir_entry *entry;entry = create_proc_read_entry(xlr_mac, 0, 0,xlr_mac_proc_read,0);創(chuàng)建/proc 的入口項(xiàng),該網(wǎng)卡設(shè)備的入口項(xiàng)的文件名稱為 xlr_mac,同時指定實(shí)現(xiàn)該文件的 read_proc 函數(shù)為 xlr_mac_proc_read,從而實(shí)現(xiàn)內(nèi)核到用戶空間的通信。為了保證網(wǎng)卡設(shè)備的正常運(yùn)行,就必須在設(shè)備準(zhǔn)備就緒以后,完成對設(shè)備的初始化,并為設(shè)備分配系統(tǒng)資源,操作成功以后向系統(tǒng)內(nèi)核注冊該網(wǎng)絡(luò)設(shè)備,這樣一個網(wǎng)絡(luò)設(shè)備就能被正常使用了。待內(nèi)核收到模塊的符號引用后,分配內(nèi)核內(nèi)存驅(qū)動程序模塊來容納該模塊,而且添加網(wǎng)卡驅(qū)動的模塊到內(nèi)核模塊鏈表的尾部。該過程的實(shí)現(xiàn)由內(nèi)核定義的特殊宏 module_init()來完成,module_init()的參數(shù)為 rmi_phnx_mac_init_module。在實(shí)際情形中,驅(qū)動程序筆者要復(fù)雜得多,如在多 CPU 上的同步控制、定時器的維護(hù)、數(shù)據(jù)傳輸超時處理、最大傳輸單元的控制、MII 接口的使用等多方面的問題,不同的是這些都附著在圖 52 中的主模塊之上。可以根據(jù)其它網(wǎng)絡(luò)設(shè)備驅(qū)動程序,設(shè)計了如下圖 42 所示開發(fā)板驅(qū)動程序的模塊結(jié)構(gòu): 驅(qū)動程序?qū)崿F(xiàn)模式圖從圖中,我們看到,整體結(jié)構(gòu)相對簡單的開發(fā)板網(wǎng)卡驅(qū)動程序主要由以下模塊構(gòu)成:模塊加載、網(wǎng)絡(luò)設(shè)備初始化、注冊、設(shè)備打開與關(guān)閉、種模式有以下優(yōu)點(diǎn):首先就是模塊化的實(shí)現(xiàn)方式能夠使功能的分割和程序的調(diào)試
點(diǎn)擊復(fù)制文檔內(nèi)容
試題試卷相關(guān)推薦
文庫吧 www.dybbs8.com
備案圖鄂ICP備17016276號-1