|
論壇說明 |
歡迎您來到『史萊姆論壇』 ^___^ 您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的! 請點擊這裡:『註冊成為我們的一份子!』 |
|
主題工具 | 顯示模式 |
2004-06-06, 05:42 AM | #1 |
榮譽會員
|
Linux操作系統下乙太網卡的安裝及配置
隨著Linux操作系統日益被人們所接受,如何在Linux系統上展開網路套用越來越成為人們關心的問題。本文詳細論述了作為基礎工作的網路卡安裝配置的原理、方法與步驟,並且描述了一個實際工作中的例子。
關鍵詞 Linux 乙太網卡 Linux核心 可裝載模組 Linux操作系統以其獨有的開放性、穩定性、高效率等特點,受到越來越多有識之士的青睞。隨著IT產業巨頭紛紛宣佈對Linux的支持,Linux正在迅速擴展其套用市場,特別是伺服器市場。在標準上,Linux與POSIX1003.1相容,但它具有比以住的UNIX系統更合理的內核結構。由於它的開放性,各種被人們廣泛套用的網路傳輸協定都在該系統中得到了實現。目前人們所使用的Linux系統一般是指由Linux核心、外殼(SHELL)及外圍應用軟體構成的發行版本。Linux發行版本是不同的公司或組織將Linux核心、外殼、安裝工具、應用軟體有效元件服務起來的結果,所以種類繁多,各有各的優缺點。但就其總體而言,這些發行版本具有對盡可能多的網路卡的支持。本文僅就RedHat5.1這個特定發行版本下的網路卡的選項、安裝、配置進行討論,希望對於其他發行版本的同樣問題有點借鑒作用。 就像UNIX,Linux支持的網路卡主要是乙太網卡。如3COM、ACCTON、AT&T、IBM、CRYSTAL、D-LINK等眾多品牌的乙太網卡只要安裝配置正確,都可以得到你所期望的效果。 一、 Linux中網路卡的工作原理 為了將這個問題說明的更清楚一些,不妨先簡要地剖析一下Linux是如何讓網路卡工作的。一般來說,Linux核心已經實現了OSI參考模型的網路層及更上層部分。網路層的實現依賴於資料鏈路層的有效工作。網路卡的驅動程式就是資料鏈路層與物理層的接頭。通過使用驅動程式的傳送例程向物理連接阜傳送資料,使用驅動程式的接收例程從物理連接阜接收資料。 1.網路卡驅動程式 簡單地說,要將你手中的網路卡利用起來,你唯一要做的是得到這塊網路卡的驅動程式。驅動程式提供了面向操作系統核心的接頭和面向物理層的接頭。 驅動程式的操作系統接頭是一些用於發現網路卡、檢測網路卡參數以及傳送接收資料的例程。當驅動程式開始運作時,操作系統首先使用檢測例程以發現系統中安裝的網路卡。如果該網路卡支持即插即用,那麼檢測例程應該可以自動發現網路卡的各種參數;否則你就要在驅動程式運作前,設定好網路卡的參數供驅動程式使用。當核心要傳送資料時,它使用驅動程式的傳送例程。傳送例程將資料寫入正確的空間,然後啟動物理傳送程序。 驅動程式面向物理層的接頭是中斷處理例程。當網路卡接收到資料、傳送程序結束,或者發現錯誤時,網路卡產生一個中斷,然後核心使用該中斷的處理例程。中斷處理例程判斷中斷髮生的原因,並進行回應的處理。比如當網路卡接收到資料而發生中斷時,中斷處理例程使用接收例程進行接收。 2.驅動程式工作參數 驅動程式的工作參數因網路卡性質的不同而不同,大致包括I/O連接阜號、中斷號、DMA通道、共享存儲區等。輸入輸出連接阜號又被稱為輸入輸出基位址,當網路卡工作於連接阜輸入輸出模式時被使用。連接阜輸入輸出模式需要CPU的全程干預,但所需硬體及存儲空間要求較低。CPU通過連接阜號指定的空間與網路卡交換資料。中斷號是網路卡的中斷序號,只要不與其它設備衝突即可。當網路卡使用DMA方式時,它要使用DMA通道批量傳輸資料而不需要CPU的干預。 對於一塊具體的網路卡,如果網路卡支持完全自動檢測,那麼一個參數也不用指定,驅動程式的檢測例程會自動設定所需參數。一般情況,你需要人工設定這些參數的一部分。如果你的網路卡使用連接阜輸入輸出模式,你要設定連接阜號和中斷號。如果你的網路卡使用DMA模式,你要設定DMA通道和中斷號。如果你的網路卡使用共享存儲區的模式,那你就得設定共享存儲區的位址範圍。 3.驅動程式的使用方式 有了網路卡的驅動程式後,你可以選項是把驅動程式加入到Linux核心之中還是把驅動程式加工成獨立模組。Linux系統一個引人入勝的長處就是可以定制系統的核心。把需要頻繁使用的功能加入系統核心,可以大大提高系統的效率。在這種情況下系統啟動時,系統核心自動載入網路卡的驅動程式。驅動程式的參數可以通過LILO指令參數加以指定。系統啟動後驅動程式永久駐留核心,不能用一般的方法將其卸載。至於定制的系統核心,是通過重新編譯得到的;如何編譯核心將在後文敘及。 如果把驅動程式編譯成可裝載模組,就可以用系統提供的指令在系統啟動後隨時載入。隨時載入的好處是減少記憶體預先配置,易於管理,但同時也犧牲了一點網路傳輸的效率。驅動程式的參數是在指令行中直接輸入或通過配置文件指定。二、 網路卡安裝前的準備 在安裝網路卡前,務必檢查是否具備下列條件: 1.硬體方面 ●乙太網卡 ●網路連接線及連接頭,如10base-T一般為8芯雙絞線配RJ-45接頭 2.軟體方面 ●Linux操作系統 ●網路卡驅動程式(目標碼或來源碼) ●*網路卡配置程序 ●*軟體開發工具,如GNU工具包(包括編譯器gcc、make等) 3.系統配置資訊 ●可用的連接阜位址 ●可用的中斷號 以上不帶星號標記的是必要條件,帶星號的是視情況不同而要求的條件。具體情況在下面進一步說明。 三、 網路卡的安裝及配置 第一步:配置乙太網卡的工作參數 配置網路卡就是配置網路卡的工作參數,如連接阜位址、中斷號等。網路卡的預設參數一般存儲於網路卡內部的EEPROM,這是網路卡出廠前設定好的。預設參數在大多數情況下是可行的,但如果這些參數與你的系統有衝突並且網路卡又不支持軟體動態設定,那麼你就要使用網路卡的設定程序。並不是所有的網路卡都要經過這一步,因為有些網路卡支持通過驅動軟體及其輸入參數來確定網路卡的工作參數。可以通過查閱網路卡使用說明書來確定這一點。 網路卡的設定程序與驅動程式不同,設定程序僅僅用來對網路卡EEPROM中的設定進行修改。網路卡程序本身可能執行在其它操作系統下,如WINDOWS95/98、OS/2、DOS等。如果是非Linux平台,那你就先在適合設定程序執行的系統中安裝網路卡,按設定程序說明設定網路卡參數。然後再在Linux系統下安裝該網路卡。 第二步:安裝Linux系統 假如你將要安裝乙太網卡的Linux系統本身還未安裝,那麼可以先試著在安裝Linux的同時安裝網路卡。這一步成功的前提是你的Linux發行版本包含將要安裝的網路卡的驅動程式。 執行Linux的安裝程序,按提示進行操作,別忘了安裝核心的網路部分。當進行到LAN配置時,安裝程序會列出它支持的所有網路卡的類型。看看你的網路卡是否榜上有名。隨著Linux發行版本的不斷昇級,目前RedHat 6.0已經覆蓋了常用的網路卡類型。如果很幸運地你的網路卡恰好在其中,那麼下文討論的很多步驟都可以不必考慮了,安裝程序會自動完成網路卡的安裝與驅動。但如果沒找到適用於你的網路卡類型,也不必擔心,繼續下一步。 第三步:手工安裝網路卡 安裝網路卡也就是安裝網路卡的驅動程式。網路卡要工作必須要有驅動程式,並且驅動程式越成熟越好。驅動程式一般由網路卡的生產或供應商提供。由於Linux是一個起步不久的新興操作系統,網路卡的生產商並不一定提供Linux環境下的驅動程式。這時候你就得從其它途徑想辦法了,比如到INTERNET上專門提供硬體驅動程式的網站搜尋一下,也可以在新聞組上貼個求助資訊。總之,只有得到網路卡的驅動程式後,方可進行下一步。 網路卡的驅動程式有兩種類型。一是可直接使用的二進制程式碼;另一種是驅動程式的來源碼。二進制程式碼一般是預先編譯好的可裝載模組。來源碼可以編譯成可裝載模組,也可以編譯成系統核心的一部分。如何把來源碼編譯成可裝載模組不在本文討論之列,具體可以查閱驅動程式的說明書。 1.可裝載模組的使用 系統提供了一組指令用於將驅動程式模組載入記憶體執行。這些指令包括modprobe、insmod、Ismod、rmmod。modprobe 與insmod指令功能相似,但是方式各異。 ●modprobe 指令使用配置文件/erc/config.modules來載入可執行模組。要用 modprobe指令載入乙太網卡的驅動程式,可以在 config.modules文件中加入: alias eth0 drivermodule (drivermodule是驅動程式模組的名稱) 這行配置資訊把乙太網卡的設備名與驅動程式模組聯繫起來。modprobe指令依據這條資訊,自動載入存放於 /lib/library/xxxx/net目錄下名為 drivermodule.o的模組。因此要使 modprobe指令找到驅動程式模組,必須將該模組放在 /lib/library/xxxx/net目錄下。 那麼驅動程式的參數如何指定呢?還是使用conf.modules文件。方法是在接著上述配置資訊的後面加入下行資訊: options drivermodule parml=valuel,parm2=value2,…… 這裡parm1 是驅動程式可以接受的參數名,valuel是該參數值;依次類推。 比如options cs89x0 io=0x200 irq=0xA media=aui ●insmod指令直接通過指令行參數將驅動程式模組載入記憶體,並可以在指令中指定驅動程式參數。例如: insmod drivermodule.o parml=valuel,parm2=value2,…… 以上兩個指令中可以使用驅動程式參數要依據具體的網路卡及其驅動程式而定,要仔細閱讀網路卡及驅動程式的說明書。有的網路卡驅動程式可以用這些參數覆蓋網路卡本身EEPROM中存儲的參數。有的則必須使用EEPROM中的參數。有的因為驅動程式不自動檢測網路卡使用的參數,所以還得把網路卡使用的EEPROM中的參數傳給驅動程式。 卸載驅動程式模組使用rmmod指令: rmmod drivermodule.o 2.把驅動程式編譯入系統核心 除了以可裝載模組的形式使用驅動程式,還可以把驅動程式編譯進Linux核心,以獲取更高的效率。這種方式需要驅動程式的來源碼、Linux核心來源碼及其編譯工具。Linux核心的編譯程序包括配置核心、重建依賴關係、產生核心程式碼等步驟。配置核心的程序是用系統提供的配置工具(make config 或make menuconfig)重新產生用來編譯核心的眾多make文件的程序。為了讓核心的配置工具瞭解你的網路卡驅動程式,你需要修改一些核心的配置文件。 (1)修改配置文件:主要修改核心來源碼目錄下的四個文件,即drivers/net/CONFIG文件、drivers/net/Config.in文件、drivers/net/Makefile 文件和drivers/net/Space.c文件。CONFIG和Config.in文件用於控制核心配置工具(make config 或make menuconfig)的執行,主要是加入關於是否包括該網路卡的支持提示。Makefile 和Space.c文件用於編譯核心程式碼並說明面向核心的接頭。詳細語句參見下面例子。 (2)執行核心配置工具:在核心來源碼目錄下執行make config或 make menuconfig指令。 make config是面向指令行的,通過逐句回答提問來配置核心。由於其在配置程序中不可改變或撤消以前的回答,故多有不便。make menuconfig 則是通過視窗表單方式,使用起來很方便。就本文而言,你只要在上一步中正確修改了配置文件,那麼在config中會出現是否需要該網路卡支持的提問,你選項『y』。或者在menuconfig中的 network表單中出現表示該網路卡的表單項,把它選上即可。 (3)重建依賴關係:很簡單,執行make dep和make clean指令。 (4)產生核心程式碼:執行make zImage 指令。這個指令開始真正編譯核心程式碼,並把核心程式碼存放為arch/i386/boot 目錄下的zImage。 (5)為了使用新的核心程式碼,你需要用新的核心程式碼替換原有的。原有的核心程式碼一般存放在/boot 目錄下,檔案名稱類似於vmlinuz-v.s.r-m (v.s.r-m)表示核心的版本號)。如vmlinuz-2.0.34-1。執行下列指令: cp arch/i386/boot/zImage /boot/vmlinuz-v.s.r-m 為了安全起見,可以先把原有的核心程式碼做個制作備份,以便發生錯誤時恢復。 至此,你可以重新起始系統以使用新的帶有正確網路卡驅動支持的Linux核心。唯一剩下未解決的是驅動程式的參數問題。有些網路卡驅動程式如果不輸入參數,那它工作就會不正常,甚至根本不工作。由於現在網路卡的驅動程式是系統啟動時由核心載入執行的,系統啟動之後用戶就很難改變這些參數了,所以你必須在系統啟動時告訴Linux核心網路卡驅動程式使用的參數。具體方法有兩種: (1)在系統啟始程序LILO中輸入。 在LILO開始啟始系統時,用ether子指令設定乙太網卡驅動程式的參數。ether指令的使用方式為: LILO:linu xether=IRO.BASE_ADDR,NAME 這裡帶底線的是要輸入的部分,IRQ表示中斷號,BASE_ADDR表示連接阜號,NAME表示網路卡的設備名。例如:linux ether=15,0x320,eth0 (2)在LILO配置文件中設定。 每次在系統啟動時再輸入驅動程式參數似乎有點過於麻煩。幸好系統提供了LILO的配置文件可以用來永久性的設定Linux系統啟動時的子指令。方法是在/etc/lilo.conf文件中的適當位置加入以下一行: append=「ether=IRQ, BASE_ADDR,NAME」 這裡帶底線部分的意義同上。加入這一行後,還需要用/sbin/lilo指令把這個配置寫入啟始程序。 第四步:網路配置及測試 安裝完網路卡就可以配置網路通信了。配置網路簡單地就是使用ifconfig指令, 例如: ifconfig eth0 1.2.3.4 netmask 255.0.0.0 up 最後ping一下網上其它機器的ip位址,檢查網路是否連通。 五、一個乙太網卡安裝實例 下面以Cirrus公司生產的Crystal CS8920乙太網卡為例,詳細說明上述安裝配置程序。本例中,有些指令參數,如核心來源碼目錄等,是以我使用的系統環境為出發點。具體套用中還要加以本機化。為了更接近實際,例子中也包括了對安裝中碰到的問題的描述。 1.此網路卡是IBM PC機的內裝式網路卡,機器只提供了Windows95/98環境下的驅動程式。由於RedHat 5.0發行版本尚未提供對此網路卡的直接支持,所以從Cirrus的站點上找到並下載了該網路卡驅動程式的Linux版本,是一個名為Linux102_tar.gz的壓縮檔案。 2.文件Linux102_tar.gz解壓縮後包括五個文件。包括來源碼,僅適用於Linux 2.0版本的目標模組以及readme文件。 3.查閱readme文件後,瞭解到這個驅動程式只能使用網路卡EEPROM中設定的連接阜號(I/O基位址)、中斷號。為了知道網路卡EEPROM的設定,又從Cirrus站點下載了該網路卡DOS版本的設定程序setup.exe 4.在DOS中執行setup.exe,發現網路卡的起始連接阜號為0x360,中斷號為10,與別的設備有衝突。選項setup.exe程序的相應表單,把中斷號改成5。另外,此驅動程式不支持plug and Play,故也在setup.exe中將網路卡的PnP功能遮閉掉。 5.我所使用的RedHat 5.0的Linux核心版本為2.0.34,所以不能用現成的驅動程式目標模組,需要自己動手編譯。如上文所述,有兩種方式使用此驅動程式。 6.如果要編譯成獨立模組,執行下列指令: gcc -D_KERNEL_-I/usr/src/linux/include -I/usr/src/linux/net/inet-Wall -Wstrictprototypes -02 -fomit-frame-pointer -DMODULE -DCONFIG_MODVERSIONS -ccs89x0.c 編譯結果是名為cs89x0.o的驅動程式目標模組。要裝載此驅動程式,輸入下列指令: insmod cs89x0.o io=0x360 irq=10 要卸載此驅動程式,用rmmod指令: rmmod cs89x0.o 7.如果要將驅動程式編進系統核心, 修改/usr/src/linux/drivers/net/CONFIG,加入: CS89x0_OPTS= 修改/usr/src/linux/drivers/net/Config.in,加入: tristate『CS8920 Support』CONFIG_CS8920 以上兩行是為了讓make config在配置程序中詢問是否增加CS8920網路卡的支持。修改/usr/src/linux/drivers/net/Makefile加入: ifeq((CONFIG_CS8920),y) L_OBJS+=cs89x0.o endif 修改/usr/src/linux/drivers/net/Space.c,加入: extern int cs89x0_probe(struct device *dev); …… #ifdef CONFIG_CS8920 && cs89x0_probe(dev); #endif 以上兩段是為了編譯並輸出網路卡驅動程式及其例程。 把驅動程式來源碼拷到/usr/src/linux/drivers/net目錄下。 在/usr/src/linux目錄下執行 make config或 make menuconfig,選項核心CS8920網路卡支持。 執行make dep、make clean指令。最後用 make zImage 編譯Linux核心。 如何設定核心驅動程式參數,上節已有說明,不再贅述。 六、結束語 與其它外設一樣,乙太網卡種類繁多,對於新興的操作系統Linux來說,是否能夠有效地支持這些設備,直接關係著Linux的發展前途。本文敘述的乙太網卡安裝配置只是其中的一小部分,未盡事宜希望與有識之仕共同探討。 |
送花文章: 3,
|
2004-06-06, 05:45 AM | #2 (permalink) |
榮譽會員
|
Linux下網路卡設定一般問題
-------------------------------------------------------------------------------- 伺服器類 1 Alpha驅動程式——獲取與使用 2 一台機器使用多個乙太網卡 3 這個以太東東不幹活。為什麼? 4 NE1000 / NE2000網路卡(及其系列)的問題 5 SMC Ultra/EtherEZ和WD80*3網路卡的問題 6 3Com網路卡的問題 7 非特定網路卡的FAQs 這裡是一些有關使用Linux進行乙太網連接的一般問題。某些特定問題按照製造商進行分類。可能你想問的問題別人已經問過(而且被回答了!),所以即使沒有在這裡找到你的答案,還可能在諸如Dejanews之類的新聞檔案中找到你所要的。 1 Alpha驅動程式——獲取與使用 我聽說我的網路卡有一個更新的或初步的/alpha驅動程式。從哪兒得到它呢? 最新的「新」驅動程式可以在Donald的FTP站點:cesdis.gsfc.nasa.gov裡面的/pub/linux/下找到。因為事情變化很頻繁,可能需要四處找一找。或者使用WWW瀏覽器去: Don的Linux主頁 搜尋你想要的驅動程式更簡單一些。(留神WWW瀏覽器會悄悄地把源碼中的TABs替換為空格,等等 - 如果無法確定的話,使用FTP下載,至少也得用WWW瀏覽器的FTP URL。) 如果驅動程式確實是alpha版本,或pre-alpha版本,那麼請恰當地對待它。換句話說,不要抱怨,因為你無法弄清用它能做些什麼。同樣,如果它使你的機器宕機了,不要抱怨。相反,你應該發給我們一份材料組織很好的Bug報告,如果是一個布丁,那就更好! 注意,某些「可用」的實驗性/alpha驅動程式已經包含在標準的內核源碼樹中。在執行make config時你首先要回答的一個問題就是「Prompt for development and/or incomplete code/drivers」。在此你要回答「Y」以包括任何alpha/實驗性驅動程式。 2 一台機器使用多個乙太網卡 做些什麼才能讓Linux執行兩塊乙太網卡? 這個問題的答案取決於驅動程式是否被用做可載入的模組或者直接編譯進了內核。大多數Linux發行版本現在都使用模組化的驅動程式。這樣就不用發行許多內核,每種內核設定一個不同的內建驅動程式。使用一個單一的基本內核,如果特定用戶系統需要,一旦系統啟動,就足以從驅動程式模組文件(通常存儲在/lib/modules/)中載入個別的驅動程式。 把驅動程式作為模組使用:對於PCI驅動程式,模組通常會自動檢測該品牌類型所有安裝的網路卡。但對於ISA網路卡,探尋一個網路卡是不安全的操作,因此你需要提供網路卡的I/O位址以便模組知道去哪裡搜尋。這一資訊存儲在文件/etc/conf.modules中。 例如,如果一個用戶有兩塊ISA NE2000網路卡,一塊在0x300,一塊在0x240,它們在/etc/conf.modules文件中顯示如下: alias eth0 ne alias eth1 ne options ne io=0x240,0x300 這幾行的意義:就是說如果管理員(或內核)進行modprobe eth0或者modprobe eth1,那麼為eth0或者eth1載入ne.o驅動程式。此外,在載入ne.o模組時,使用選項io=0x240,0x300,這樣驅動程式就知道去哪裡尋找網路卡。注意0x很重要 - DOS裡常用的300h在這裡沒有用。改變0x240和0x300的順序會使哪一塊物理網路卡以eth0和eth1結尾發生改變。 同這個例子一樣,大多數ISA模組驅動程式可以接受多個以逗號分隔的I/O值以處理多塊網路卡。但是,某些(老的?)驅動程式,比如3c501.o模組,目前載入一個模組只能處理一塊網路卡。這樣,要檢測兩塊網路卡就必須載入兩次該模組。此時,文件/etc/conf.modules將如下所顯示: alias eth0 3c501 alias eth1 3c501 options eth0 -o 3c501-0 io=0x280 irq=5 options eth1 -o 3c501-1 io=0x300 irq=7 在此例中,選項-o用來給每個模組實例一個唯一的名字,因為不能用同一個名字載入兩個模組。選項irq=也是用來指定網路卡設定的硬體IRQ。(此方法也能用於可接受多個以逗號分隔的I/O值的模組,但這樣會使模組被不必要地載入兩次,降低了效率。) 最後一個例子,假設用戶有一塊在0x350的3c503網路卡和一塊在0x280的SMC Elite16 (wd8013)網路卡。則應該這樣: alias eth0 wd alias eth1 3c503 options wd io=0x280 options 3c503 io=0x350 對於PCI網路卡,只要用alias語句把ethN接頭和相應的驅動程式名聯繫起來就行了,因為PCI網路卡的I/O位址可以被安全地檢測到。 可用的模組一般存放在/lib/modules/`uname -r`/net下,這裡uname -r指令可以得到內核的版本(比如2.0.34)。你可以在這裡看看哪一個驅動程式適合你的網路卡。一旦你在conf.modules文件裡進行了正確的設定,就可以用下面的方法檢查一下: modprobe ethN dmesg | tail 這裡「N」是你要檢測的乙太網卡的接頭號。 使用編譯進內核的驅動程式:如果你需要的驅動程式編譯進了內核,那麼處理多塊乙太網卡的接頭已經存在了。但預設情況下只自動檢測一塊乙太網卡。這樣就避免了啟動時檢測敏感網路卡可能引起的麻煩。 (注意:在2.1.x之後的內核中,啟動檢測被分為安全和不安全的兩類,所有安全的檢測(如對PCI和EISA網路卡)可以自動找到所有相關的網路卡。在至少有一塊ISA網路卡的多網路卡系統中還需要進行以下的處理。) 有兩種方法可以啟動對第二塊(或第三塊等等)網路卡的自動檢測。最簡單的方法是向內核傳遞啟動參數,由LILO完成。使用ether=0,0,eth1這樣簡單的啟動參數就可以完成對第二塊網路卡的檢測。此時按照啟動時找到的網路卡順序分配eth0和eth1。假如你想讓0x300處的網路卡為eth0,而0x280處的網路卡為eth1,那麼可以使用 LILO: linux ether=5,0x300,eth0 ether=15,0x280,eth1 指令ether=可以接受的參數並不僅限於如上所顯示的IRQ + I/O + name。請參看傳遞乙太網參數......以瞭解全部的句法、網路卡特定參數和LILO使用技巧。 這些啟動參數可以類BIOS,這樣就不用每次都必須重新敲一遍。參看LILO手冊中有關LILO 的配置選項「append」。 第二種方法(不建議使用)是編輯文件Space.c並用零替換I/O位址中的0xffe0入口。0xffe0入口是用來告訴內核不要檢測該設備 -- 把它替換為零就啟動了對該設備的自動檢測。 注意,如果想用Linux作為兩個網路間的路由,你需要啟動IP轉發並重新編譯內核。一般在一台老式的AT/286上執行「kbridge」一類的軟體就相當不錯了。 如果你是一邊在網路衝浪,一邊看本我的文件,最好去閱讀Donald的WWW站點上的mini-howto。看一下多塊乙太網卡. 3 這個以太東東不幹活。為什麼? 如上所述,指令ether=只對編譯進了內核的驅動程式起作用。現在大多數的發行版本都用模組的方式使用驅動程式,所以很少再使用ether=指令了。(某些早期我的文件需要更新以反映這一變化。)如果你想使用模組化的乙太網驅動程式的選項,必須修改/etc/conf.modules文件。 如果你是使用編譯的驅動程式,而且已經把ether=加進了LILO 配置文件,需要重新執行lilo使更新後的配置文件生效。 4 NE1000 / NE2000網路卡(及其相容卡)的問題 問題:在用v2.0.x啟動時沒有檢測到PCI NE2000相容網路卡。 原因:在v2.0.30之前的ne.c驅動程式只知道關於RealTek 8029的相容網路卡的PCI ID號。在此只後才出現了使用其它PCI ID號的PCI NE2000相容網路卡,所以驅動程式無法檢測這些網路卡。 解決方案:最簡單的方法是把Linux內核昇級到v2.0.31以上版本。它可以識別五種不同的NE2000-PCI晶片的ID號,在啟動或載入模組時自動檢測到它們。 如果你昇級到了2.0.34以上版本,會有一個比原先的ISA/PCI驅動程式稍小但更高效的PCI專用NE2000驅動程式。 問題:啟動時PCI NE2000相容網路卡被報告為ne1000(8比特網路卡!)或者在v2.0.x下載入ne.o模組不起作用。 原因:某些PCI相容網路卡不支持字元存取(因此不是百分之百的相容NE2000)。這使檢測時被誤認為NE1000網路卡。 解決方案:你需要昇級到v2.0.31以上版本。現在的驅動程式會檢測到這種硬體Bug。 問題:PCI NE2000網路卡的效能很差,即使按照效能技巧章節所說的減小了視窗大小。 原因:十多年前設計和出售的初始8390晶片的技術資料手冊上提到,為了得到最高的可靠性,在每次寫操作之前需要一個讀操作。驅動程式能夠輕易地做到這一點,但從v1.2內核時代起,預設情況下取消了這一操作。有一個用戶報告說重新使用這一「錯誤的特性」就可以改善廉價的PCI NE2000相容網路卡的效能。 解決方案:由於只有一個用戶提出報告把它作為解決方案,不要對此寄予太大的希望。重新使用寫之前的讀操作可以簡單地編輯linux/drivers/net/下的驅動程式文件,取消包含NE_RW_BUGFIX的那一行的註釋,然後重建內核或載入相應的模組。如果這樣確實有效,請給我發一封e-mail,描述效能上的差異和你所使用的網路卡/晶片類型。(對ne2k-pci.c驅動程式也可以如法炮製。) 問題:ne2k-pci.c驅動程式對PCI NE2000網路卡報告諸如timeout waiting for Tx RDC錯誤資訊,無法正常工作。 原因:你的網路卡或網路卡到PCI總線的連接無法處理該驅動程式使用的長字I/O最佳化。 解決方案:首先,檢查BIOS/CMOS設定,看看與PCI總線相關的計時對於可靠的操作是否過於嚴格了。否則,使用ISA/PCI的ne.c驅動程式(或者刪除ne2k-pci.c中的#define USE_LONGIO),使你的網路卡可用。 問題:沒檢測到ISA的即插即用NE2000網路卡(如RealTek 8019)。 原因:初始的NE2000特性不支持即插即用,因此Linux的NE2000驅動程式也不支持即插即用。 解決方案:使用網路卡所附的DOS配置盤取消PnP,並為該網路卡設定一個指定的I/O位址和IRQ。在/etc/conf.modules裡增加這樣的一行options ne io=0xNNN,這裡0xNNN是你為網路卡設定的16進制I/O位址。(假設你使用的是模組化驅動程式;否則,在啟動時使用一個ether=0,0xNNN,eth0參數。你也可以進入BIOS/CMOS設定,把IRQ從PnP改為Legacy-ISA。如果你需要為相容其它的操作系統而保留PnP設定,那麼你可以看一下isapnptools包。使用man isapnp看看它是否已經安裝在你的系統上了。如果沒有,瀏覽一下下面的連接: ISA PNP Tools 問題:在啟動檢測時NE*000驅動程式報告「not found (no reset ack)」。 原因:這跟上面所說的改動有關。在證實8390處於所檢測的I/O位址之後,進行重新設定。在網路卡完成重新設定後,應當通知重新設定完成。你的網路卡沒有通知,所以驅動程式認為不存在NE網路卡。 解決方案:你可以在啟動時使用一個未被使用的mem_end16進制值0xbad,告訴驅動程式你有一個壞網路卡。在使用0xbad撤消時你必須為網路卡提供一個非零的I/O位址。例如,在0x340的網路卡不回應重新設定,則使用如下方法: LILO: linux ether=0,0x340,0,0xbad,eth0 這樣,即使你的網路卡不回應重新設定,網路卡檢測還能繼續下去。如果你是以模組方式使用驅動程式,那麼可以像提供I/O位址一樣提供選項bad=0xbad。 問題:NE*000網路卡使機器在第一次網路訪問時當機。 原因:這個問題從早期的1.1.57內核到現在都出現過,而且只在有限的幾種軟體配置的相容網路卡上出現。看來是需要用某些特殊的方法來啟始化它們。 解決方案:有幾個人報告在熱啟動(即loadlin或Ctrl-Alt-Del)Linux之前,執行提供的DOS軟體配置程序或提供的DOS驅動程式可以使網路卡工作。這表明這些卡需要以某種特殊的方式啟始化,與當前的Linux驅動程式稍有區別。 問題:在0x360的NE*000乙太網卡沒有檢測到。 原因:你的NE2000網路卡在I/O空間佔據了0x20個字元,使它與0x378處的並列阜發生衝突。其它可能的設備是0x370處的第二個軟碟控制器(如果有的話),以及0x376--0x377處的第二個IDE控制器。如果該口已被其它驅動程式註冊,內核將不再進去行檢測。 解決方案:把你的網路卡移到0x280, 0x340, 0x320一類的位址,或者在編譯時不支持並行列印機。 問題:每次列印時網路都中斷連線(NE2000)。 原因:與上一個問題相同,但你的內核比較老,不支持對重疊I/O區域的檢查。使用如上的解決方案,有空時獲取一個新的內核。 問題:沒檢測到0xNNN: 00 00 C5 ... 處的NE*000乙太網卡。(非法標識yy zz) 原因:首先,你是否在位址0xNNN處有一個NE1000或NE2000網路卡?如果有,報告的硬體位址是否像一個合法位址?如果是的話,那麼你的NE*000相容網路卡很差勁。所有的 NE*000相容網路卡都假定網路卡上的SA PROM的第14和15字元為0x57。而你的網路卡不是這樣 -- 它的值為「yy zz」。 解決方案:有兩種解決方法。最簡單的方法就是如上所述的「no reset ack」 解決方案,使用一個0xbad的mem_end值。這樣在提供一個非零的I/O位址時就可以忽略標識檢查。此方法無需重新編譯內核。 第二種方法(對黑客)需要修改驅動程式,並重新編譯內核(或模組)。在驅動程式(/usr/src/linux/drivers/net/ne.c)的42行有一個「Hall of Shame」列表。這個表是用來檢測那些差勁的相容網路卡的。例如,DFI網路卡在PROM的前三個字元使用「DFI」,而不是像要求的那樣在第14和15字元使用0x57。 問題:機器在啟動時出現「8390...」或「WD....」資訊後當機。拔掉NE2000就好了。 解決方案:把你的NE2000位址改為0x340一類的位址。此外,你可以在和「ether=」參數一起使用「reserve=」啟動參數,保護網路卡不受其它設備驅動程式檢測的影響。 原因:你的NE2000相容網路卡相容性不好。一個啟動的NE2000是個無底洞,會使其它的驅動程式陷在其空間內進行自動檢測。把NE2000改到一個不常用的位址就可以從其它的自動檢測中消除這一陷阱,機器也就可以啟動了。 問題:機器啟動時在進行SCSI檢測時當機。 原因:這個問題跟上面的一樣,改變乙太網卡的位址,或使用reserve/ether啟動參數。 問題:機器啟動時在進行音效卡檢測時當機。 原因:不可能,實際上是發生在靜默方式的SCSI檢測程序中,與上面的問題一樣。 問題:啟動時檢測不到NE2000 - 根本就沒有啟動資訊。 解決方案:因為造成檢測不到的原因很多,所以沒有「神奇的解決方案」。下面列出了可能有所說明 的一些措施。 1) 構建一個只包含需要的設備驅動程式的內核。證實你確實是從新內核啟動的。忘記執行lilo等會使你從老的內核啟動。(仔細觀察啟動時報告的構建時間/日期。)聽起來很明顯,但我們以前都犯過這個錯。通過檢查System.map文件裡ne_probe一類的名稱,確定驅動程式已包含在新的內核裡。 2) 仔細觀察啟動資訊。看看它是否提及正在進行諸如「NE*000 probe at 0xNNN: not found (blah blah)」一類的ne2k檢測,或者就是靜悄悄地失敗了。這裡的區別很大。使用dmesg|more在登入後瀏覽啟動資訊,或者在啟動完成顯示登入提示號時使用Shift-PgUp捲回螢幕。 3) 啟動後,執行cat /proc/ioports,證實網路卡要求的全部I/O空間是空的。如果網路卡在0x300,那麼ne2k驅動程式要求的空間為0x300-0x31f。如果其它設備的驅動程式註冊了其中的一個口,就不會對該位址進行檢測,而是靜悄悄地檢測下一個要檢測的位址。一般的情況是lp驅動程式保留了0x378,或者第二個IDE通道保留了0x376,這就使ne驅動程式停止檢測0x360-0x380。 4) 與上面一樣執行cat /proc/interrupts。確定沒有其它設備註冊了你為乙太網卡設定的中斷。這種情況下,檢測可以進行,乙太網卡驅動程式會在啟動時大聲抱怨無法得到所要求的IRQ中斷線。 5) 如果你還為驅動程式靜悄悄地失敗而苦惱,那麼編輯並給檢測增加一些printk()。比如,對於ne2k,你可以在linux/drivers/net/ne.c中增加/刪除某些行(用 「+」或「-」表示),如下所顯示: -------------------------------------------------------------------------------- int reg0 = inb_p(ioaddr); + printk("NE2k probe - now checking %x\n",ioaddr); - if (reg0 == 0xFF) + if (reg0 == 0xFF) { + printk("NE2k probe - got 0xFF (vacant I/O port)\n"); return ENODEV; + } -------------------------------------------------------------------------------- 那麼它就會輸出檢查的每一個口位址資訊,你可以看到你的網路卡位址是否被檢測了。 6) 你還可以從Don的ftp站點(在howto中也提及了)獲取ne2k的診斷程序,看看你在啟動進入Linux後能否用它檢測你的網路卡。使用「-p 0xNNN」選項告訴它在哪裡尋找你的網路卡。(預設情況下只檢測0x300,與啟動時的探測不同,不會檢測其它的位址。)在找到網路卡時的輸出如下: -------------------------------------------------------------------------------- Checking the ethercard at 0x300. Register 0x0d (0x30d) is 00 Passed initial NE2000 probe, value 00. 8390 registers: 0a 00 00 00 63 00 00 00 01 00 30 01 00 00 00 00 SA PROM 0: 00 00 00 00 c0 c0 b0 b0 05 05 65 65 05 05 20 20 SA PROM 0x10: 00 00 07 07 0d 0d 01 01 14 14 02 02 57 57 57 57 NE2000 found at 0x300, using start page 0x40 and end page 0x80. -------------------------------------------------------------------------------- 你的註冊值和PROM值可能會不一樣。注意,對16比特網路卡,所有PROM值都增加一倍,乙太網卡位址(00:00:c0:b0:05:65)出現在第一行,加倍後的0x57標識出現在PROM的結尾。 在0x300處沒有安裝網路卡時的輸出如下: -------------------------------------------------------------------------------- Checking the ethercard at 0x300. Register 0x0d (0x30d) is ff Failed initial NE2000 probe, value ff. 8390 registers: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff SA PROM 0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff SA PROM 0x10: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff Invalid signature found, wordlength 2. -------------------------------------------------------------------------------- 出現值0xff的原因是在讀取空I/O口時返回的就是該值。如果在檢測的區域內有其它硬體,你可以看到一些非0xff的值。 7) 嘗試在執行提供的DOS驅動程式或配置程序之後,從DOS啟動軟碟(通過loadlin)熱啟動進入Linux。這可能會進行一些額外的(即非標準的)「魔法」來啟始化網路卡。 8) 試一下Russ Nelson的ne2000.com包驅動程式,看它能否看見你的網路卡 -- 如果還不行,事情就不大妙了。例如: A:> ne2000 0x60 10 0x300 所用參數為軟體中斷向量、硬體IRQ和I/O位址。你可以從任意的msdos存檔中的pktdrv11.zip裡找到它 -- 現在的版本大概是11以上了。 5 SMC Ultra/EtherEZ和WD80*3網路卡的問題 問題:你得到了如下資訊: eth0: bogus packet size: 65531, status=0xff, nxpg=0xff 原因:是共享記憶體的問題。 解決方案:最普遍的原因是配置的PCI機器沒有映射到ISA記憶體設備裡。因此你讀到的是PC的RAM(全都是0xff值),而不是存放接收資料包資料的網路卡上的RAM。 另一個容易解決的典型問題是板卡衝突,在此區域有緩衝或「shadow ROM」,或者你的ISA總線執行速度高於8Mhz。乙太網卡上的記憶體失效的數目也令人驚奇,所以如果你的乙太網卡有診斷程序的話,執行一下。 問題:SMC EtherEZ在非共享記憶體(PIO)模式下不工作。 原因:老版本的Ultra驅動程式只支持共享記憶體模式下的操作。 解決方案:版本2.0以上的內核所附驅動程式就支持可編程I/O模式的操作。昇級到v2.0以上版本。 問題:老的wd8003或可跳線的wd8013總是得到錯誤的IRQ。 原因:老的wd8003網路卡或可跳線的wd8013相容卡沒有驅動程式可以從中讀取設定的IRQ的EEPROM。如果驅動程式無法讀到IRQ,就嘗試用auto-IRQ發現它。若auto-IRQ返回0,那麼驅動程式就給8比特網路卡分配IRQ 5,或者為16比特網路卡分配IRQ 16。 解決方案: 使auto-IRQ程式碼無效,並在你的模組配置文件(對於內建的驅動程式則通過啟動參數)告訴內核你把網路卡跳成了什麼IRQ。 問題:SMC Ultra網路卡被檢測成了wd8013,但IRQ和共享記憶體位址是錯的。 原因:Ultra網路卡看起來跟wd8013很相像,如果內核裡沒有Ultra驅動程式,wd驅動程式就會把ultra誤認為wd8013。ultra檢測在wd之前,所以一般不會出問題。ultra在EEPROM儲存的IRQ和記憶體位址與wd8013儲存的位置不同,所以報告的值是假的。 解決方案:只保留需要的驅動程式重新編譯內核。如果你在同一台電腦上同時使用wd和ultra網路卡,並使用模組,那麼首先載入ultra模組就行了。 6 3Com網路卡的問題 問題:3c503選項了IRQ N,但其它設備也需要IRQ N。(比如CD ROM驅動程式、 modem等。)可以不編譯進內核就解決這個問題嗎? 解決方案:3c503驅動程式按照順序{5, 9/2, 3, 4}檢測空閒的IRQ線,從中找到一個未被使用的IRQ。在網路卡被ifconfig操作配置時選項中斷IRQ。 如果你使用的是模組化的驅動程式,可以用模組參數設定各種情況,包括中斷IRQ的值。 下面的語句選項IRQ9、基址0x300、和if_port #1(外部收發器)。 io=0x300 irq=9 xcvr=1 如果驅動程式被編譯進了內核,你還可以通過LILO在啟動時傳遞參數來設定同樣的值。 LILO: linux ether=9,0x300,0,1,eth0 下面的語句選項IRQ3、檢測基址、和預設if_port #0(外部收發器)。 LILO: linux ether=3,0,0,0,eth0 問題:3c503: configured interrupt X invalid, will use autoIRQ. 原因:3c503網路卡只能使用中斷IRQ{5, 2/9, 3, 4}中的一個(這些是網路卡所能連接的中斷線。)如果你使用一個不在其中的IRQ值,就會得到如上的提示。 一般情況下,沒必要為3c503指定中斷值。3c503會在ifconfig配置時使用autoIRQ,並從IRQ{5, 2/9, 3, 4}中選項一個。 解決方案:使用上述的合法IRQ值,或者不指定IRQ以啟用autoIRQ。 問題:提供的3c503驅動程式無法使用AUI(粗纜乙太網)連接阜。怎樣才能不使用預設的細纜乙太網連接阜而選項AUI連接阜? 解決方案:3c503的AUI連接阜對於內建驅動程式可以在啟動時選項,對於模組化驅動程式可以在插入模組時選項。這一選項會覆蓋未使用的dev->rmem_start變數的低比特位,所以啟動參數: LILO: linux ether=0,0,0,1,eth0 對內建在內核的驅動程式起作用。 要在載入模組時指定AUI連接阜,只需把xcvr=1附加在模組選項包含你的I/O和IRQ值的那一行就行了。。 7 非特定網路卡的FAQs Linux與ISA的即插即用乙太網卡 要獲得最佳效果(問題最少),推薦使用隨網路卡附的程序(通常是DOS程序)取消PnP機制,並給網路卡設定一個類BIOS的I/O位址和IRQ。 確定你使用的I/O位址在啟動時被驅動程式檢測到,如果使用模組,則在/etc/conf.modules中使用io=選項提供位址。你也可以進入BIOS/CMOS設定,把IRQ從PnP改為Legacy-ISA(如果你的電腦有此選項的話)。 注意,執行關於DOS的配置程序一般並不需要安裝DOS。 可以用DOS軟碟啟動,然後從提供的軟碟上執行它們就可以了。你可以自由地下載OpenDOS和FreeDOS。 如果需要使用PnP以與其它操作系統相容,你就得每次啟動時都使用Linux的isapnptools包配置網路卡。你還需要確定為網路卡選項的I/O位址被驅動程式檢測到,或用io=選項提供I/O位址。 啟動時沒有檢測到乙太網卡 出現這個問題的一般原因是人們使用的內核不支持特定的網路卡。對於模組化的內核,這一般說明要求的模組尚未被載入,或者需要用模組選項指定其I/O位址。 如果你使用的是模組化的內核,就像大多數用Linux發行版安裝的那樣,試著用一下該發行版的配置工具來選項網路卡所用模組。 對於ISA網路卡一個較好的主意是,確定網路卡的I/O位址,如果配置工具要求選項則把它作為一個選項(如io=0x340)加進去。如果沒有配置工具,那麼你需要在/etc/conf.modules裡增加正確的模組名稱(及選項)-- 閱讀man modprobe以瞭解更多的細節。 如果你使用的發行版套件裡的預編譯內核,那麼檢視我的文件以確定你安裝的是哪一種內核,以及是否支持你所用的網路卡。 如果不支持的話,要麼試著找一個支持你網路卡的內核,要麼自己產生一個內核。 只保留所需的驅動程式產生自己的內核是個聰明的主意,因為這會減小內核大小(為應用程式保留寶貴的RAM!),減少打擾敏感硬體的設備檢測數目。產生內核並不像聽起來那麼複雜。你只需要對一些有關你想要哪些驅動程式的問題回答是或不是,其它的事都由程序完成。 另一個主要原因是其它的設備佔用了網路卡所需的部分I/O空間。大多數網路卡在I/O空間裡佔用了16或32個字元。 如果你的網路卡設在0x300並要求32個字元,那麼驅動程式就要求0x300-0x31f。如果某個其它設備驅動程式註冊了哪怕其中一個連接阜,驅動程式就不會對該位址進行檢測,而是靜悄悄地進入下一個檢測位址。所以,在啟動之後,執行一下cat /proc/ioports以確定網路卡要求的全部I/O空間都是空的。 還有一個問題就是網路卡跳到的I/O位址不是預設檢測的位址。每個驅動程式的檢測位址列表可以很容易地在驅動程式源碼中的文本註釋裡找到。 即使網路卡設定的I/O位址不在檢測位址列表上,你也可以在啟動時用ether=指令提供(對內建驅動程式),參見傳遞乙太網參數...。模組化的驅動程式可以在/etc/conf.modules裡使用io=選項指定一個非預設檢測的位址。 ifconfig報告了錯誤的網路卡I/O位址 這不可能。你只是理解錯誤。 這不是一個Bug,而且報告的數字是正確的。這只出現在某些關於8390的網路卡上(如wd80x3、smc-ultra等),實際的8390晶片位於第一個給定I/O連接阜加上一個偏移量處。此偏移量儲存在dev->base_addr裡,也就是ifconfig報告的值。如果你想看到網路卡使用的全部連接阜,試一下cat /proc/ioports以得到想要的數字。 PCI機器探測到了網路卡,但驅動程式檢測失敗。 某些PCI的BIOS在上電時沒有啟用所有的PCI卡,特別是在使用了「PNP OS」的BIOS選項情況下。 這一特性是為了支持當前依然使用某些真實模式驅動程式的Windows版本。或者禁用該選項,或者昇級到一個可以啟用被禁用網路卡的新驅動程式。 PCI機器裡的共享記憶體ISA網路卡不工作(0xffff) 這常表現為顯示讀出大量0xffff值。除非你正確地設定了PCI ROM BIOS/CMOS SETUP配置,任何類型的共享記憶體網路卡都不會在PCI電腦上工作。你必須把網路卡所用記憶體區域設定為可以從ISA總線訪問共享記憶體。 如果你不知道哪些設定有用,那麼詢問你的供應商或者當地的電腦大拿。 對於AMI BIOS,在「Plug and Play」部分有一個「ISA Shared Memory Size」和「ISA Shared Memory Base」的設定。 對於類似wd8013和SMC Ultra的網路卡,把共享記憶體的大小從預設的禁用改為16kB,並把基址改為網路卡的共享記憶體位址。 網路卡看來在傳送資料,但沒有收到過資料。 執行cat /proc/interrupts。這樣產生的列表會顯示網路卡產生的所有中斷事件的既時數目。 如果為0或在試突使用網路卡時沒有增加,那麼可能是與電腦安裝的其它設備發生物理中斷衝突(無論其它的設備是否安裝/提供了驅動程式)。把其中一個設備的IRQ改為未使用的IRQ。 異步傳輸模式(ATM)支持 Werner Almesberger在進行Linux的ATM的支持工作。他使用的是Efficient Networks的ENI155p板(Efficient Networks)和Zeitnet的ZN1221板(Zeitnet)。 Werner說ENI155p的驅動程式已經很穩定了,而ZN1221的驅動程式還沒有完成。 去下面的連接檢視一下最新的進展: Linux ATM Support 吉比特乙太網支持 Linux支持吉比特乙太網嗎? 是的,目前至少已經有了兩個驅動程式。在v2.0和v2.2內核裡有一個Packet Engines G-NIC PCI吉比特乙太網橋接器的驅動程式。驅動程式的更多細節、支持和更新可訪問: http://cesdis.gsfc.nasa.gov/linux/dr...yellowfin.html v2.2內核提供的acenic.c驅動程式可用於Alteon的AceNIC吉比特乙太網卡和其它如3Com的3c985一類的關於Tigon的網路卡。這個驅動程式還可以用於NetGear的GA620,但還需要證實。 FDDI支持 Linux支持FDDI嗎? 是的。Larry Stefani為v2.0編寫了Digital的DEFEA(FDDI EISA)和DEFPA(FDDI PCI)網路卡驅動程式。它被包含進v2.0.24內核。目前還沒有其它的網路卡被支持。 全雙工支持 全雙工能達到20MBps嗎?Linux支持嗎? Cameron Spitzer對全雙工10Base-T網路卡有如下論斷:「如果你連在全雙工交換HUB上,你的系統足夠快而且不做太多其它的工作,它會使你的網路在兩個方向上都保持忙碌。不存在什麼全雙工的10BASE-2或10BASE-5(細纜和粗纜)。全雙工是通過取消橋接器的碰撞檢測來達到的。這就是為什麼用同軸電纜實現不了全雙工;LAN無法以全雙工方式運轉。 10BASE-T(RJ45接頭)使用不同的線進行傳送和接收,所以二者可能同時進行。交換HUB處理碰撞問題。信號速率是10Mbps。」 所以,你只能以10Mbps速率接收或傳送資料,無法期望得到兩倍的效能提高。對於是否支持,取決於網路卡和可能的驅動程式。有些網路卡可以自動協商,有些需要驅動程式支持,還有的需要用戶在網路卡的EEPROM配置中設定選項。只有那些認真的用戶會注意到全雙工與半雙工模式間的差別。 SMP電腦上的Linux乙太網卡 如果你有錢買多處理器(MP)的電腦,那麼最好買一個好點兒的乙太網卡。對v2.0內核這還不是個問題,但對v2.2就成問題了。大多數老式的非智能(如ISA總線的PIO和共享記憶體設計)網路卡在設計時根本沒考慮多處理器套用。簡單地說就是買一個現代設計的智能網路卡,並確定有能夠處理多處理器操作的驅動程式。(注意這裡的「現代設計」 - PCI-NE2000就是在現代總線上有10多年歷史的老式設計。)在驅動程式的源碼裡搜尋spin_lock可以很好地說明該驅動程式是否能夠處理多處理器操作。下面詳細解釋了為何要為多處理器套用購買好的網路卡(以及不買會出現什麼問題)。 在v2.0內核,在任意時刻只有一個處理器允許進入「內核態」(即改變內核資料或執行設備驅動程式)。所以從網路卡(及相關驅動程式)的角度來看,這與單處理器操作沒有什麼不同,所以不會出問題。(這也是得到一個可以工作的Linux多處理器版本的最簡單的辦法 -- 使用一個大鎖使得一次只有一個處理器處於內核狀態。這樣你就知道不可能有兩個處理器同時要修改同一資料!) 在任意時刻只有一個處理器允許進入內核態的不利之處在於只有執行自我控制和密集計算的程序時才會獲得多處理器的優越性。如果程序進行了大量諸如向磁牒或網路讀/寫資料的I/O操作,在處於內核的那個處理器努力執行所有的設備驅動程式以滿足I/O請求的同時,其它的處理器都必須等待自己的I/O請求被處理完成。這樣內核就成為了瓶頸,由於只有一個處理器執行在內核態,多處理器機器的效能在I/O工作重、單鎖的情況下迅速降級到接近單處理器的水準。 很明顯這與理想情況相差太遠(尤其是對於文件/WWW伺服器、路由器等),v2.2的內核就使用了粒度更小的鎖——也就是說同時可以有多個處理器進入內核。不再是對整個內核使用一個大鎖,而是使用許多較小的鎖保護關鍵資料,防止同時被多個處理器控制——例如,一個處理器可以執行網路卡驅動程式,同時另一個處理器可以執行磁牒驅動器的驅動程式。 好的,這樣就有問題了:更小的鎖定就意味著可以有一個處理器試突通過乙太網驅動程式傳送資料,同時另一個處理器試突訪問同一個驅動程式/網路卡來做別的事情(比如通過cat /proc/net/dev得到網路卡統計資料)。哎呦——你的網路卡正在通過網線發資料,你又要用它來收資料。網路卡被同時要求做兩件事(或更多),會弄糊塗的,所以有可能在處理程序中網路卡使你的機器當機。 因此,為單處理器寫的驅動程式不再適用——它需要更新控制對網路卡訪問的鎖,使得網路卡的接收、傳送和操作配置資料這三種工作以網路卡穩定操作所要求的程度串行化起來。沒有更新為使用穩定多處理器操作的鎖的驅動程式在輕的網路負載下可能看起來會正常工作,但在兩個(或更多)處理器試突同時進行多個工作時就會造成當機,或至少表現出奇怪的行為,這就是問題。 更新後的意識到多處理器的乙太網驅動程式將要求一個驅動程式範圍的鎖,使得內核進入驅動程式的訪問入口被限制為一次一個。這樣,工作就被串行化,而對硬體的處理就如同在單處理器下一樣,也就一定應當穩定。使用驅動程式範圍的鎖的不利之處在於它類似於對整個內核加鎖(但規模較小)對效能的影響——也就是說,一次只可以有一個處理器處理網路卡。[技術提示:如果增加的鎖是irqsave類型的而且被持有較長時間,對效能的影響還包括增加了中斷延遲。] 這裡可以進行的改進有兩處。可以嘗試減少獲得與釋放鎖之間所用的時間,或者在驅動程式內部實現更為細化的鎖(比如滿足網路卡需求的前提下,把整個驅動程式的鎖替換為若干保護同時訪問若干敏感暫存器或設定的鎖)。 但是,對於老式的非智能網路卡而言,在設計時根本就沒有考慮過多處理器的套用,這樣的改進可能無法實現。更糟的是非智能網路卡一般要求處理器在網路卡和記憶體之間傳送資料,所以在最壞的情況下,每當在ISA總線傳送1.5kB資料包時,鎖都被一直保持著。 現代的智能網路卡一般無需處理器的說明 就可以直接在網路卡和記憶體之間傳遞網路資料。這是個很大的改進,因為只需要在處理器通知網路卡使用哪一塊記憶體儲存下一個網路資料包的那一小段時間持有鎖。現代的網路卡在設計時同樣也不要求對整個驅動程式使用一個大鎖。 Alpha/AXP的PCI板上的Linux乙太網卡 對於v2.0,只有3c509、depca、de4x5、pcnet32和所有8390驅動程式(wd、smc-ultra、ne、3c503等等)是編寫成「結構無關」的,所以它們可以執行在關於DEC的Alpha CPU系統上。其它一些從Donald的WWW主頁上下載的更新過的PCI驅動程式也可以工作,因為它們也是按照結構無關的思想編寫的。 注意,使驅動程式與結構無關所需要進行的改動並不很複雜。只需要如下進行: --把所有與jiffies有關的值都乘以HZ/100,得到Alpha使用的不同的HZ值。(即timeout=2;變成timeout=2*HZ/100;) --把所有I/O記憶體(從640k到1MB)的游標引用替換為相應的readb() writeb() readl() writel()使用,如下例所顯示。 -------------------------------------------------------------------------------- - int *mem_base = (int *)dev->mem_start; - mem_base[0] = 0xba5eba5e; + unsigned long mem_base = dev->mem_start; + writel(0xba5eba5e, mem_base); -------------------------------------------------------------------------------- --把所有使用I/O記憶體作為源或目的位址的memcpy()使用替換為相應的memcpy_fromio()或者memcpy_toio()使用。 以結構無關的方式處理記憶體訪問的細節在近期的內核所附的文件linux/Documentation/IO-mapping.txt中進行了說明。 SUN/Sparc硬體上的Linux乙太網卡 要得到最新的Sparc資訊,可以訪問以下URL: Linux Sparc 注意,有些Sparc的乙太網硬體從主機獲得其MAC位址,因此可能會有多個接頭具有相同的MAC位址。如果想在同一個網路上使用多個接頭,可以使用ifconfig的hw選項以分配唯一的MAC位址。 把PCI驅動程式移植到Sparc平台上與上面提到的AXP平台相似。可能的差異出在endian上,因為Sparc是big endian,而AXP和ix86是little endian。 其它硬體上的Linux乙太網卡 還有一些其它硬體平台可以執行Linux,比如Atari/Amiga(m68k)。就像Sparc一樣,最好是訪問每個Linux支持的平台主頁,以瞭解當前都支持哪些硬體。(歡迎提供這樣的站點連接——把它們發給我!) 不使用Hub連接10/100BaseT 可以不使用Hub連接關於10/100BaseT(RJ45)的系統嗎? 如果不使用額外的設備或機械裝置,可以很容易地連接兩台這樣的機器,但不可能再多。參閱雙絞線——解釋了如何做到這一點。而且你不可能簡單地交叉幾根線或其它什麼就弄出一個Hub,不複製Hub也無法正確完成衝突信號。 SIOCSIFxxx: No such device 在啟動時出現了一大堆「SIOCSIFxxx: No such device」資訊,後面還有一條「SIOCADDRT: Network is unreachable」,怎麼回事? 你的乙太網設備在啟動/插入模組時沒有被檢測到,當ifconfig和route執行時,它們沒有可用的設備。使用dmesg | more來瀏覽啟動資訊,看看有沒有檢測乙太網卡的資訊。 SIOCSFFLAGS: Try again 在執行「ifconfig」時出現「SIOCSFFLAGS: Try again」——怎麼回事? 某些其它的設備使用了乙太網卡想用的IRQ,所以乙太網卡無法使用該IRQ。你不必重新啟動來解決這個問題,因為某些設備只是在需要時才獲取IRQ,在完成後就釋放了。例如某些音效卡、串列阜、軟碟驅動器等。你可以鍵入cat /proc/interrupts來看看哪些中斷正在被使用。絕大多數Linux乙太網卡驅動程式只有在用「ifconfig」開啟時才獲取IRQ。如果你能讓其它設備「放開」所需的IRQ中斷線,那麼你就可以用ifconfig來「再試一下」了。 使用「ifconfig」得到的連接為UNSPEC,而硬體位址是00:00:00:00:00:00 在不帶參數執行ifconfig時,報告說連接為UNSPEC(而不是10Mbs乙太網),而且硬體位址都是零。 這是因為執行的「ifconfig」程序版本比內核的版本高。在與老版本的內核一起執行時,新版本的ifconfig無法報告這些特性。你可以昇級內核,或者「降級」ifconfig,或者乾脆不理會這個錯誤。內核知道硬體位址,所以即使ifconfig無法讀出它也沒有關係。 如果使用的ifconfig程序比使用的內核舊很多的話,也會出現一些奇怪的資訊。 大量的RX和TX錯誤 在不帶參數執行ifconfig時,報告大量的接收和傳送資料包錯誤。但看起來工作正常——怎麼回事? 再看一遍。報告是說RX packets big number 停頓 errors 0 停頓 dropped 0 停頓 overrun 0。所以你看到的那個大數字是機器接收和傳送的資料包總數。如果還覺得不可思議,鍵入cat /proc/net/dev試試。 /dev/下乙太網卡的入口 /dev/eth0像是個到/dev/xxx的連接。這樣對嗎? 與你聽過的正好相反,/dev/*下的文件沒被使用。你可以刪除掉任何/dev/wd0, /dev/ne0以及類似的入口。 Linux與「trailers」 在「ifconfig」網路卡時,需要禁止trailers嗎? 不能禁止trailers,而且也沒必要。「trailers」是避免在網路層複製資料的工具。其想法是使用一個大小為「H」的類BIOS大小的頭,把可變大小的頭資訊放在包的尾部,並把所有包定位在頁開始之前的「H」字元。這只是個好想法,在實際中工作得並不好。如果有人建議使用「-trailers」,那不過是找個替罪羊罷了。這對解決問題沒有任何意義,但如果問題真的自行解決了,那麼他就可以吹噓自己的神奇本領了。 訪問原始乙太網設備 在Linux下怎樣不通過TCP/IP之類的東西訪問原始的乙太網設備? -------------------------------------------------------------------------------- int s=socket(AF_INET,SOCK_PACKET,htons(ETH_P_ALL)); -------------------------------------------------------------------------------- 這樣就可以得到一個接收所有傳輸協定類型的socket。對它執行recvfrom()使用,它就會用sa_family裡的設備類型和sa_data陣列裡的設備名來填充sockaddr。我不知道是誰最早在Linux裡使用SOCK_PACKET,但它確實是個非常好的東西。你也可以通過sendto()使用傳送原始資料包。當然,在這樣做時你必須擁有root的權限。 |
__________________ |
|
送花文章: 3,
|