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

正文內(nèi)容

基于arm的linux網(wǎng)卡驅(qū)動程序的開發(fā)與設(shè)計(論文最終完成)-wenkub.com

2025-01-13 13:04 本頁面
   

【正文】 在進行數(shù)據(jù)傳輸時,負責(zé)傳輸?shù)姆椒ㄒ紫却_認當(dāng)前的是哪一個線程在進行數(shù)據(jù)的傳輸。內(nèi)核處理的每個數(shù)據(jù)包都位于一個套接字緩沖區(qū)結(jié)構(gòu)sk_buf中,對于該結(jié)構(gòu)的細節(jié),在第二章中已經(jīng)闡述過,限與篇幅這里就不再重新討論了。究其原因來講,如同前面討論的一樣,該主設(shè)備的處理器是一個多核多線程的設(shè)備,所以只能通過調(diào)用del_timer_sync來確保在返回時沒有任何CPU在運行定時器函數(shù)。設(shè)備的關(guān)閉與設(shè)備的打開的操作是互逆的,要完成的工作很少,不象打開時那么的復(fù)雜,但是有些操作卻不是和打開時一樣的。前面曾提到,設(shè)備端口的打開是在自旋鎖的保護下進行的,現(xiàn)在已經(jīng)完成了設(shè)備的初始化急打開任務(wù),就必須解除自旋鎖。前面介紹過,端口的速率以及雙工能力是通過MII接口從PHY寄存器中獲取出來的,但是我們在設(shè)備打開時,可以重新根據(jù)具體的需求進行配置,以盡可能的充分利用硬件資源同時滿足我們的實際需要。void init_timer(struct timer_list * timer)。struct timer_list { … unsigned long expires。通常情況下,網(wǎng)絡(luò)接口只是接收MAC目的地址是自己或者廣播的數(shù)據(jù)包,但在專用網(wǎng)絡(luò)設(shè)備上,我們可以通過改變網(wǎng)卡的這一能力,讓它接收任何其它的數(shù)據(jù)包,例如,我們在進行網(wǎng)絡(luò)偵測的時候,就需要網(wǎng)卡可以接收流經(jīng)網(wǎng)絡(luò)的所有數(shù)據(jù)包。很多網(wǎng)絡(luò)設(shè)備驅(qū)動程序?qū)⒃O(shè)備的部分初始化操作也放在了設(shè)備打開的時候完成,但是考慮到BCM5464是多端口的芯片,初始化的操作是在打開之前完成了的,因此設(shè)備打開的任務(wù)就相對的比較簡單了。在向系統(tǒng)注冊網(wǎng)絡(luò)接口之前,我們必須要完成接口的初始化,否則在注冊時,系統(tǒng)會panic甚至崩潰,這也是為什么驅(qū)動程序在向系統(tǒng)注冊設(shè)備之前必須完成初始化的原因。在驅(qū)動程序中,為了能在多處理器上同步執(zhí)行,在設(shè)備的私有數(shù)據(jù)結(jié)構(gòu)中設(shè)置了privspill_configured這個特征值,在初始化時,該值設(shè)置為0,表示還沒有被初始化,而一但設(shè)備驅(qū)動程序被執(zhí)行后,該字段的值被重新設(shè)置為1,任何時候要執(zhí)行設(shè)備的初始化,都必須先檢測該字段,如果該值為1,則表明已經(jīng)初始化,否則進行初始化操作。開發(fā)板上芯片在生產(chǎn)制造時,確立了phnx_mac各個字段的值,我們只能引用它們,而不應(yīng)該試圖去修改,但是中斷號irq是可以通過用戶空間的ifconfig命令修改的。 unsigned long phnx_io_offset。前面已經(jīng)提及到,priv是網(wǎng)卡設(shè)備的私有結(jié)構(gòu)的指針,用于保存和控制設(shè)備特征的信息以及芯片的每個端口的信息。privinstance = phnx_mac_devices[i].instance。因為擁有自旋鎖的時間越長,其他處理器就不得不自旋以等待該自旋鎖的時間就越長,而它不得不永遠自旋的可能性就越大。在BCM5464的網(wǎng)卡驅(qū)動程序中,對設(shè)備的互斥訪問是通過自旋鎖來實現(xiàn)的,而沒有采用普通的信號量機智。在設(shè)置默認值時,數(shù)據(jù)包傳輸隊列中tx_queue_len排隊的最大幀數(shù)目設(shè)置為了1000,但是由于芯片的吞吐性能良好,因此在設(shè)備初始化時驅(qū)動程序把該值設(shè)置為了10000,相比原來的最大幀數(shù)目增大了10倍,如果不這樣修改的話,將會浪費很多的系統(tǒng)內(nèi)存。devtx_queue_len = 10000。devdo_ioctl = rmi_phnx_mac_do_ioctl。devhard_start_xmit = rmi_phnx_mac_xmit。devmem_end = mmio_start + PHOENIX_IO_SIZE 1。正如我們所看到的一樣,廣播地址是48bit的全1(0xFF)的地址。ether_setup(dev);上面這個步驟是以太網(wǎng)網(wǎng)卡設(shè)備指針在進行自己特有的初始化之前,對設(shè)備結(jié)構(gòu)體的大部分值使用以太網(wǎng)默認值進行初始化,具體的包括: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中所進行的初始化操作。在使用中斷前要先請求一個中斷通道,然后在使用完后釋放該通道。request_irq(devirq,rmi_phnx_mac_int_handler,SA_INTERRUPT, devname, dev);盡管有很多設(shè)備只是通過他們的I/O寄存器就可以得到控制,但實際使用中的大部分設(shè)備都要是無法這樣實現(xiàn)的,還必須依靠中斷。為了性能和靈活性方面的考慮,linux沒有直接返回網(wǎng)卡私有數(shù)據(jù)結(jié)構(gòu)。在設(shè)備完成注冊以后,%d將被一個從0開始的可用數(shù)字替代,使之成為唯一的名字。instance的值代表了端口,四個端口的instance值分別為11116,這四個值是由芯片生產(chǎn)時設(shè)置的,驅(qū)動程序不應(yīng)該試圖修改它。在初始化之前先定義了指向網(wǎng)絡(luò)設(shè)備的指針、指向設(shè)備私有數(shù)據(jù)塊的指針以及/proc入口項:struct net_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的入口項,該網(wǎng)卡設(shè)備的入口項的文件名稱為xlr_mac,同時指定實現(xiàn)該文件的read_proc函數(shù)為xlr_mac_proc_read,從而實現(xiàn)內(nèi)核到用戶空間的通信。內(nèi)核接收到模塊的符號引用以后,為驅(qū)動程序模塊分配內(nèi)核內(nèi)存來容納該模塊,并將網(wǎng)卡驅(qū)動的模塊添加到內(nèi)核模塊鏈表的尾部。 網(wǎng)卡驅(qū)動實現(xiàn)由于網(wǎng)卡驅(qū)動的代碼量大,文章不會將所有的代碼全部列出進行討論,而只是將最具有代表意義和普遍意義的代碼挑選出來進行解釋和分析。如何設(shè)計設(shè)備驅(qū)動驅(qū)動功能層的結(jié)構(gòu)就成了開發(fā)板驅(qū)動程序開發(fā)的首要任務(wù),也是該驅(qū)動程序開發(fā)的基礎(chǔ)。在設(shè)計網(wǎng)絡(luò)驅(qū)動程序時,最主要的工作就是完成設(shè)備驅(qū)動功能層,使其滿足自己所需要的功能。不同的影子寄存器的訪問方式又是不相同的,比如24號寄存器(輔助控制寄存器)和28號寄存器可以直接通過影子寄存器的來實現(xiàn)寄存器值的讀寫操作;但擴展寄存器卻要通過23號寄存器和21號寄存器聯(lián)合才能實現(xiàn)讀寫操作。 寄存器的訪問方式上面已經(jīng)說過,MAC對PHY寄存器的讀寫訪問是通過MII接口實現(xiàn)的。(MAC)相連接的通用總線。MII(Management interface)只有兩條信號線。每條信道都有自己的數(shù)據(jù)、時鐘和控制信號。,目前正在做驅(qū)動程序,相信很快就可以完成移植。存儲器包括下列幾部分:64M SDRAM,64M Nand Flash(用于存放應(yīng)用程序),32M Intel StrataFlash 32M(默認不焊接),SD卡,一個VGA(直接連接普通PC顯示器), CS8900以太網(wǎng)控制器,IDE接口,一個USB 主機接口,一個USB設(shè)備接口(可以切換成第二主機,需要更改驅(qū)動),一個總線擴展接口(包含16位數(shù)據(jù),12位地址,兩個片選,可以通過CPLD控制)。由于該設(shè)備是一款網(wǎng)絡(luò)設(shè)備,所以網(wǎng)卡就成了該設(shè)備的重要組件。如果內(nèi)核認為模塊仍然在使用狀態(tài)(例如,某個程序正打開由該模塊導(dǎo)出的設(shè)備文件),或者內(nèi)核被配置為禁止移除該模塊,則無法移除該模塊。如果注冊成功,則調(diào)用init函數(shù)指針所指向的初始化函數(shù)來對設(shè)備初始化,將設(shè)備的net_device數(shù)據(jù)結(jié)構(gòu)插入到鏈表的末尾。模塊設(shè)計是Linux中特有的技術(shù),它使Linux內(nèi)核功能易于擴展,采用模塊方式來設(shè)計Linux網(wǎng)絡(luò)設(shè)備驅(qū)動程序也很方便,并且能夠形成固定的模式。void *kmap_skb_frag(skb_frag_t *frag);void kunmap_skb_frag(void *vaddr);如果要在內(nèi)核中直接訪問非線性skb中的數(shù)據(jù)片段,這些函數(shù)負責(zé)映射和解除映射。unsigned char *skb_pull(struct sk_buff *skb, int len);從報文的頭部刪除數(shù)據(jù)。返回data前面的可用空間數(shù)量,也即是有多少字節(jié)能夠保存在該緩沖區(qū)中。在傳輸數(shù)據(jù)包之前,可使用該函數(shù)添加硬件頭。在非中斷上下文中使用dev_kfree_skb,在中斷上下文中使用dev_kfree_skb_irq,dev_kfree_skb_any在上面兩種情況下均可以使用。dev_alloc_skb函數(shù)以GFP_ATOMIC的優(yōu)先級調(diào)用 alloc_skb函數(shù),并且在skbhead和skbdata之間保留了一些空間,網(wǎng)絡(luò)層使用這一數(shù)據(jù)空間進行優(yōu)化工作,驅(qū)動程序不應(yīng)該訪問它。(2) 作用于緩沖區(qū)的函數(shù)使用sk_buff[11]結(jié)構(gòu)的網(wǎng)絡(luò)驅(qū)動程序通過一些正式的接口函數(shù)來操作該結(jié)構(gòu)。unsigned char pkt_type;在發(fā)送過程使用的數(shù)據(jù)包類型。通過它們可以計算出可用的緩存空間(skbend skbhead)和當(dāng)前使用的空間(skbtail skbdata)。h中含有傳輸層頭部指針(例如struct tcphdr *th);nh包含網(wǎng)絡(luò)層頭部(例如struct iphdr *iph);以及mac包含鏈路層頭部指針(例如struct ethkr * ethernet)。(1). 重要成員變量這里描述的成員都是驅(qū)動程序需要訪問的。除開上面提及到的基本方法以外,還有很多的可選方法。例如,當(dāng)ifconfig或者netstat i運行時將利用到該方法。int (*rebuild_header)(struct sk_buff *skb);該函數(shù)用來在ARP[4]解析完成之后、在報文發(fā)送之前重新建立硬件頭。完整的數(shù)據(jù)包(協(xié)議頭和所有)包含在一個套接字緩存區(qū)(sk_buff)結(jié)構(gòu)中。int (*stop)(struct net_device *dev);停止接口?;痉椒òㄊ褂媒涌诒仨毜姆椒?;可選的方法實現(xiàn)了更為高級的功能,但并不是嚴格要求的功能。 網(wǎng)卡驅(qū)動程序的基本方法每個網(wǎng)絡(luò)設(shè)備都聲明了很多能操作它的函數(shù)。另外,設(shè)備地址必須以特定于設(shè)備的方式從接口板卡中讀出,驅(qū)動程序應(yīng)當(dāng)將它拷貝到dev_addr中??勺R別的類型定義于linux/中。例如,plip設(shè)置為10來避免浪費系統(tǒng)內(nèi)存(相比真實以太網(wǎng)接口,plip 有一個低些的吞吐量)。網(wǎng)絡(luò)層使用該成員變量驅(qū)動數(shù)據(jù)包的傳輸。如果設(shè)備是一個嶄新的類,就需要手工設(shè)置下面的成員:unsigned short hard_header_len。void fddi_setup(struct net_device *dev);配置一個光纖分布數(shù)據(jù)接口(FDDI)網(wǎng)絡(luò)的接口。以太網(wǎng)卡可以依賴這個通用的函數(shù)設(shè)置大部分這些成員,但是flags和dev_addr成員是特定設(shè)備的, 必須在初始化期間顯示賦值。unsigned char dma;為設(shè)備分配的DMA通道。這個值常常在啟動或者加載時設(shè)置,其后可以通過ifconfig命令修改。base_addr可以在系統(tǒng)啟動時、或者在模塊加載時在內(nèi)核命令行中顯式賦值。根據(jù)規(guī)定,end成員的設(shè)置要保證end start等于可用的板卡內(nèi)存量。unsigned long rmem_end;unsigned long rmem_start;unsigned long mem_end;unsigned long mem_start;設(shè)備的內(nèi)存信息.。如果設(shè)置了這個指針,這個函數(shù)被 register_netdev 調(diào)用來完成對net_device結(jié)構(gòu)的初始化。驅(qū)動程序在正常情況下不直接操作這些標志,相反,內(nèi)核提供了一組工具函數(shù)來專門操作該標志。(1) 全局信息結(jié)構(gòu) net_device 的第一部分是由下面成員組成:char name[IFNAMSIZ];設(shè)備名稱。內(nèi)核中的網(wǎng)絡(luò)驅(qū)動程序接口是為不同模式的操作而精心設(shè)計的。如某些協(xié)議里的超時處理,沒有中斷機制的硬件的輪詢等,操作系統(tǒng)應(yīng)為驅(qū)動程序提供定時機制,一般是在預(yù)定的時間過了以后,系統(tǒng)自動回調(diào)注冊的時鐘函數(shù)。驅(qū)動程序由于是直接操縱硬件的,所以網(wǎng)絡(luò)硬件有數(shù)據(jù)收到時,最先能得到這個數(shù)據(jù)的就是驅(qū)動程序,它負責(zé)把這些原始數(shù)據(jù)進行必要的處理,然后送給系統(tǒng)。下面簡單介紹一下網(wǎng)絡(luò)設(shè)備驅(qū)動程序的一些基本的也是最重要的概念。Unix訪問網(wǎng)絡(luò)接口的方法仍然是給他們分配一個唯一的名字(比如eth0),但這個名字在文件系統(tǒng)中不存在對應(yīng)的節(jié)點。網(wǎng)絡(luò)接口由內(nèi)核中的網(wǎng)絡(luò)子系統(tǒng)驅(qū)動,負責(zé)數(shù)據(jù)包的接收和發(fā)送,但它不需要了每項事務(wù)是如何映射到實際傳送的數(shù)據(jù)包的。Linux可以讓應(yīng)用程序像字符設(shè)備一樣地讀寫塊設(shè)備,允許依次傳遞任意多的字節(jié)的數(shù)據(jù)。當(dāng)然,也存在具有數(shù)據(jù)特性的字符設(shè)備,訪問它們時可以前后移動訪問位置。device)三種:字符設(shè)備:字符(char)設(shè)備是個能夠像字節(jié)流一樣被訪問的設(shè)備,由字符設(shè)備的驅(qū)動程序來實現(xiàn)這種特性。Linux系統(tǒng)的設(shè)備分為字符設(shè)備(char設(shè)備驅(qū)動程序的角色就是將這些調(diào)用映射到作用于實際硬件設(shè)備相關(guān)的操作上。網(wǎng)
點擊復(fù)制文檔內(nèi)容
黨政相關(guān)相關(guān)推薦
文庫吧 www.dybbs8.com
備案圖片鄂ICP備17016276號-1