?? ethernet-howto-8.html
字號:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=gb2312"> <META NAME="GENERATOR" CONTENT="ZH-SGML-Tools 1.0.9"> <TITLE>Linux以太網-HOWTO: 技術信息</TITLE> <LINK HREF="Ethernet-HOWTO-9.html" tppabs="http://www.linux.org.tw/CLDP/gb/Ethernet-HOWTO-9.html" REL=next> <LINK HREF="Ethernet-HOWTO-7.html" tppabs="http://www.linux.org.tw/CLDP/gb/Ethernet-HOWTO-7.html" REL=previous> <LINK HREF="Ethernet-HOWTO.html#toc8" tppabs="http://www.linux.org.tw/CLDP/gb/Ethernet-HOWTO.html#toc8" REL=contents><SCRIPT src="menu.js"> function BeginPage() {} function EndPage() {} </SCRIPT> </HEAD> <BODY bgcolor=#FFFFFF MARGINHEIGHT=0 MARGINWIDTH=0> <A HREF="Ethernet-HOWTO-9.html" tppabs="http://www.linux.org.tw/CLDP/gb/Ethernet-HOWTO-9.html"><IMG SRC="next.gif" tppabs="http://www.linux.org.tw/CLDP/gb/img/next.gif" ALT="Next"></A><A HREF="Ethernet-HOWTO-7.html" tppabs="http://www.linux.org.tw/CLDP/gb/Ethernet-HOWTO-7.html"><IMG SRC="prev.gif" tppabs="http://www.linux.org.tw/CLDP/gb/img/prev.gif" ALT="Previous"></A><A HREF="Ethernet-HOWTO.html#toc8" tppabs="http://www.linux.org.tw/CLDP/gb/Ethernet-HOWTO.html#toc8"><IMG SRC="toc.gif" tppabs="http://www.linux.org.tw/CLDP/gb/img/toc.gif" ALT="Contents"></A><HR><H2><A NAME="tech-intro"></A> <A NAME="s8">8. 技術信息</A></H2><P><P>對于那些想了解更多有關網卡如何工作、或如何使用現有驅動程序,以及試圖為目前不支持的網卡編寫自己的驅動程序的人來說,這些信息應該會有用。如果你沒有這種想法,那么最好跳過這一節。<P><H2><A NAME="data-xfer"></A> <A NAME="ss8.1">8.1 可編程I/O、共享內存與DMA</A></H2><P><P>如果已經可以發送接收背靠背數據包,就無法把更多的數據放到網絡上。每一個現代的以太網卡都可以接收背靠背數據包。Linux的DP8390驅動程序(wd80x3、SMC-Ultra、3c503、ne2000,等等)基本上都可以發送背靠背數據包(依賴于當前的中斷延遲),3c509和AT1500的硬件在自動發送背靠背數據包上沒有一點問題。<P>ISA總線可以達到5.3MB/sec (42Mb/sec),對10Mbps以太網而言已經足夠了。對于100Mbps網卡,顯然需要更快的總線來充分利用網絡帶寬。<P><H3>可編程I/O(如NE2000、3c509)</H3><P><P>優點:沒有使用任何受限制的系統資源,只用了若干I/O寄存器,而且沒有16M的限制。<P>缺點:一般傳輸速率較慢,CPU需要等待,幾乎不可能訪問交叉的數據包。<P><H3>共享內存(如WD80x3、SMC-Ultra、3c503)</H3><P><P>優點:簡單,比可編程I/O速度快,允許隨機訪問數據包。在可能的情況下,Linux驅動程序在從網卡復制出接收的IP數據包時計算其校驗和,從而比相應的PIO網卡進一步減少了對CPU的占用。<P>缺點:使用高端內存空間(對DOS用戶來說是個大問題,在Linux下沒有問題),依然要占用CPU。<P><H3>從屬(普通)的直接內存存取(Linux下沒有這種情況!)</H3><P><P>優點:在實際數據傳遞過程中不占用CPU。<P>缺點:檢查邊界條件、分配相鄰的緩存和DMA寄存器編程使該方法成為最慢的技術。它還占用了一個珍貴的DMA通道,并要求對齊的低端內存緩存。<P><H3><A NAME="master"></A> 總線控制的直接內存存取(如LANCE、DEC 21040)</H3><P><P>優點:在數據傳輸過程中不占用CPU,可以把緩存串起來,CPU時間很少或不花費在ISA總線上。大多數總線控制的Linux驅動程序現在使用一種“copybreak”方案,較大的數據包直接從網卡放進內核的網絡緩存,小的數據包被CPU復制到cache里進行下一步的處理。<P>缺點:(只適用于ISA總線的網卡)網卡要求低端內存緩存和一個DMA通道。任何總線控制器在與其它強占總線的總線控制器,如某些古老的SCSI適配器,一起工作時都會出問題。有幾個設計低劣的主板芯片組在與總線控制器一起使用時也有麻煩。不使用<EM>任何</EM>類型的DMA設備的一個原因是使用了設計為代替386的486處理器插件:這些處理器在每個DMA周期都必須刷新cache。(這其中包括Cx486DLC、Ti486DLC、Cx486SLC、Ti486SLC,等等。)<P><P><H2><A NAME="skel"></A> <A NAME="ss8.2">8.2 編寫驅動程序</A></H2><P><P>在Linux下使用以太網卡所必需的只不過是相應的驅動程序。因此,關鍵是制造商要向公眾公開編程的技術資料,而無需你(或其他什么人)簽署什么協議。關于獲取資料的可能性(也許你不編寫代碼,那么就是其他人編寫你確實需要的驅動程序的可能性),一個較好的指南是Crynwr (昵稱Clarkson)的包驅動程序的可用性。Russ Nelson在干這些事,對開發Linux驅動程序很有幫助。<EM>網上沖浪者</EM>可以試著看一下Russ的軟件。<P><A HREF="javascript:if(confirm('http://www.crynwr.com/crynwr/home.html \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?'))window.location='http://www.crynwr.com/crynwr/home.html'" tppabs="http://www.crynwr.com/crynwr/home.html">Russ Nelson's Packet Drivers</A><P>有了資料,就可以為網卡編寫驅動程序并在Linux下使用(至少從理論上來說是這樣)。記住,有些為XT一類機器設計的老式硬件在Linux這樣的多任務環境下工作得不是很好。如果網絡流量較大,使用這些網卡會帶來大麻煩。<P>大多數網卡都帶有如NDIS和ODI一類的MS-DOS接口的驅動程序,但對Linux沒有用。許多人建議直接鏈接它們或自動翻譯一下,但這幾乎是不可能的。MS-DOS驅動程序需要在16比特模式,并依賴于“軟件中斷”,這二者與Linux內核不兼容。這種不兼容實際上是Linux的一個特性,有些Linux驅動程序比其相應的MS-DOS驅動程序要好得多。比如“8390”系列驅動程序使用乒乓傳送緩存,該方法剛剛被引進MS-DOS。<P>(乒乓傳送緩存意味著為傳送數據包使用至少兩個最大大小的包緩存。在網卡發送其中的一個時,載入另一個。在第一個包被發出去后,立刻發送第二個包,依次類推。這樣,大多數網卡就可以連續向線路上發送背靠背數據包。)<P>好啦。你可以決定為Foobar Ethernet網卡編寫驅動程序了,因為你有編程資料,而且還沒人寫這個驅動程序。(......這是兩個主要的需求 ;-)你可以從Linux內核源碼樹中提供的網絡驅動程序框架開始。在所有近期的內核里都能找到這個文件/usr/src/linux/drivers/net/skeleton.c。也可以看看如下URL的Kernel Hackers Guide:<A HREF="javascript:if(confirm('http://www.redhat.com:8080/HyperNews/get/khg.html \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?'))window.location='http://www.redhat.com:8080/HyperNews/get/khg.html'" tppabs="http://www.redhat.com:8080/HyperNews/get/khg.html">KHG</A><P><P><H2><A NAME="ss8.3">8.3 內核的驅動程序接口</A></H2><P><P>下面對編寫一個新驅動程序所必需的函數進行了若干說明。和上面提到的驅動程序框架一起閱讀可以更清楚一些。<P><P><H3>探測</H3><P><P>在啟動時調用以檢查網卡存在與否。如果可以通過讀取內存等非強制手段進行檢查最好。也可以從I/O端口讀取。在探測開始向I/O端口寫<EM>不好</EM>,因為這樣可能會損害另一個設備。通常在這里還進行一些設備初始化(分配I/O空間、IRQ、填充dev->???域等等)。必須了解網卡可以配置到哪些I/O端口/內存、如何啟用共享內存(如果用了的話)以及如何選擇/啟用中斷產生,等等。<P><H3>中斷處理程序</H3><P><P>在網卡發出一個中斷時內核調用的程序。他需要確定網卡發出中斷的原因并進行相應的操作。一般的中斷條件是接收到數據、發送完成、報告出錯狀況。需要了解相關的中斷狀態位以進行相應的操作。<P><H3>傳送函數</H3><P><P>與dev->hard_start_xmit()鏈接,在內核想通過設備傳送數據時調用它。該函數把數據放入網卡并觸發傳送。需要了解如何把數據打包并傳給網卡(共享內存拷貝、PIO傳送、DMA?),以及放入網卡正確的位置。然后需要了解如何通知網卡把數據發送到線路上,(可能)在發送完成后發出一個中斷。在硬件無法接收更多數據包時需要設置dev->tbusy標志。在網卡有空間可用時,一般這發生在傳送完成中斷過程中,清除dev->tbusy標志并用<CODE>mark_bh(INET_BH)</CODE>通知上一層。<P><H3>接收函數</H3><P><P>在網卡報告有數據時由內核中斷處理程序調用。它把數據從網卡上移出,放入一個sk_buff并通過執行netif_rx(sk_buff)告訴內核數據所在位置。需要了解如何在接收數據時啟用中斷生成,如何檢查相關的接收狀態位,以及如何從網卡獲取數據(通過共享內存拷貝、PIO、DMA,等等)。<P><H3>打開函數</H3><P><P>與dev->open鏈接,在有人使用<CODE>ifconfig eth0 up</CODE>時網絡層調用它——把設備連到線路上并啟用來接收/發送數據。任何在探測過程中(啟用
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -