以 Broadcom Corporation BCM4311, BCM4312, BCM4313, BCM4321, BCM4322, BCM43224, BCM43225, BCM43227 和 BCM43228 為基礎的無線網絡卡

<!> CentOS 對這些晶片組並沒有原生的支援。

這頁的英文版本現時由 Miloš Blažević 維護。

注意:自驅動程式 5.100.82.38 於 2010 年 12 月發行至現有的最新版本(5.100.82.112),暫時仍未有數據確定這些驅動程式在 CentOS 5 上對聲稱支援的無線晶片組是否有效。因此,假若 ELRepo 的 kmod-wl 頁無法助你設定無線上網,你可考慮採用另一個方法,就是從這裡這裡或付出小量金錢從這裡下載舊版驅動程式,然後按照以下指南進行編譯。另外,煩請回饋你對 Broadcom 無線晶片的經驗,好讓此指南能保持更新及不斷改善。

註:基於這個 Broadcam 驅動程式的極度限制性條款,ELRepo 軟件庫的開發者放棄以 rpm 套件來提供它 —— 因此這份文件被建立的目的是要提供一個全面的驅動程式安裝說明。

註:本作者至今只測試了 Broadcom 的 BCM4311 及 BCM4312 晶片組。

若要安裝以 Broadcom BCM4311、BCM4312、BCM4313、BCM4321 或 BCM4322 為基礎的無線網絡卡,請遵照以下的步驟:

第 1 步:辨認無線網絡晶片及安裝時依賴的套件


首先,請確定你是位「擁有 Broadcom BCM43xx 無線網絡卡的幸運兒」:

[user@host ~]$ /sbin/lspci | grep Broadcom
0b:00.0 Network controller: Broadcom Corporation BCM4312 802.11a/b/g (rev 01)

辨認完無線網絡晶片型號之後,請確定你不會欠缺編譯及安裝時所需的套件:

[root@host]# yum install kernel-headers kernel-devel gcc

當然,假若你要為 Xen 內核(kernel-xen)編譯驅動程式,你必須安裝 kernel-xen-devel 而不是 kernel-devel。

第 2 步:下載並解壓 Broadcom 驅動程式的壓縮檔

請從 Broadcom 的官方網站下載 Broadcom BCM43xx 的 linux 驅動程式壓縮檔(此驅動程式已無效 —— 請參閱本頁頂部的警告)到你的機器並將它解壓到 /usr/local/src/hybrid-wl,請隨你所需將這個目錄的擁有者改為無特權的用戶:

[root@host ~]# mkdir -p /usr/local/src/hybrid-wl
[root@host hybrid-wl]# cd /usr/local/src/hybrid-wl
[root@host hybrid-wl]# tar xvfz /path/to/the/tarball/hybrid-portsrc-x86_64-v5.10.91.9.3.tar.gz(下載檔的名稱)
[root@host hybrid-wl]# chown -R someuser.somegroup /usr/local/src/hybrid-wl 

註:為甚麼不隨便將它解壓到一個位置並保留預設的擁有者?
原因是上面的做法會把驅動模塊的源代碼保留在系統上 —— 在你放置它們的位置 —— 好讓你可以隨時按需要建立驅動程式(譬如:你將內核升了級 —— 因為驅動模塊永遠根據某個內核來編譯),還有,就是你可以用無特權的用戶來編譯!

第 3 步:編譯 Broadcom 驅動模塊


驅動模塊可以這樣編譯:

[user@host hybrid-wl]$ make -C /lib/modules/`uname -r`/build/ M=`pwd`

請留意引號(也就反引號)。

現在你很可能會獲得一個錯誤信息,而不是一個編譯好的驅動模塊(實際上,本作者仍未遇過這個信息以外的情況)。這則信息的內容大致上是:

make: Entering directory `/usr/src/kernels/2.6.18-164.el5-x86_64'
  LD      /tmp/hybrid/hybrid/hybrid/built-in.o
  CC [M]  /tmp/hybrid/hybrid/hybrid/src/wl/sys/wl_linux.o
In file included from /tmp/hybrid/hybrid/hybrid/src/wl/sys/wl_linux.c:20:
/tmp/hybrid/hybrid/hybrid/src/include/typedefs.h:70: error: conflicting types for ‘bool’
include/linux/types.h:36: error: previous declaration of ‘bool’ was here
make[1]: *** [/tmp/hybrid/hybrid/hybrid/src/wl/sys/wl_linux.o] Error 1
make: *** [_module_/tmp/hybrid/hybrid/hybrid] Error 2
make: Leaving directory `/usr/src/kernels/2.6.18-164.el5-x86_64'

正如你所見,typedefs.h 這個檔案的第 70 行出了一個問題。要解決它,請將第 70 行的代碼改為註釋,好讓它變成:

/*
#ifndef TYPEDEF_BOOL
typedef  unsigned char  bool;
#endif
*/

你亦可以透過在標頭檔加入以下內容(勿論這一行是否已經存在)來簡單地解決這個問題:

#define TYPEDEF_BOOL

現在,請嘗試再次編譯驅動模塊:

[user@host hybrid-wl]$ make -C /lib/modules/`uname -r`/build/ M=`pwd`

編譯器的輸出大致上是這樣:

make: Entering directory `/usr/src/kernels/2.6.18-164.el5-x86_64'
  CC [M]  /tmp/hybrid/hybrid/hybrid/src/wl/sys/wl_linux.o
  CC [M]  /tmp/hybrid/hybrid/hybrid/src/wl/sys/wl_iw.o
  CC [M]  /tmp/hybrid/hybrid/hybrid/src/shared/linux_osl.o
  LD [M]  /tmp/hybrid/hybrid/hybrid/wl.o
  Building modules, stage 2.
  MODPOST
  CC      /tmp/hybrid/hybrid/hybrid/wl.mod.o
  LD [M]  /tmp/hybrid/hybrid/hybrid/wl.ko
make: Leaving directory `/usr/src/kernels/2.6.18-164.el5-x86_64'

一旦這個模塊被建成,你便可以移除不必要的符號:

[user@host hybrid-wl]$ strip --strip-debug wl.ko

你會發現驅動模塊的檔案大小會明顯地縮小(由 2.2MB 降至 1.5MB)。而且,你的驅動模塊仍能正常運作 ;)

第 4 步上:將驅動模塊載入內核中

當你成功地編譯了驅動模塊後,你便可以將它載入內核中,並設定在開機時自動載入這個驅動程式(要這樣做,你必須利用 root 的權限)。當然,做這一切之先,你必須從內核移除現在的無線驅動模塊(假如有的話):

[root@host ~]# rmmod bcm43xx
[root@host ~]# rmmod b43
[root@host ~]# rmmod b43legacy
[root@host ~]# rmmod ndiswrapper

現在我們載入驅動模塊:

[root@host hybrid-wl]# insmod wl.ko

假如這一步失敗了(有不少這樣的報告,但是作者本身還沒有遇到過這類問題),並伴有如下提示信息:

insmod: error inserting 'wl.ko': -1 Unknown symbol in module

首先嘗試建立模塊依賴:

[root@host ~]# depmod `uname -r`

然後載入驅動模塊:

[root@host hybrid-wl]# modprobe wl.ko

假若模塊的載入再次失敗,請嘗試先以手動方式插入 ieee802.11_crypt_tkip 這個依賴性模塊,然後才繼續載入 wl 這個驅動模塊:

[root@host hybrid-wl]# modprobe ieee80211_crypt_tkip
[root@host hybrid-wl]# modprobe wl

假如你在無線驅動程式以外沒有應用 ndiswrapper 這個內核模塊,你可以移除它,但這並非必需的。

第 4 步下:在開機時將驅動模塊載入內核中

首先,請將驅動模塊的檔案複製到一個可以讓內核找到它的地方:

[root@host hybrid-wl]# cp -vi /usr/local/src/hybrid-wl/wl.ko /lib/modules/`uname -r`/extra/ 

這樣做是為了與其它已經/將會從 kmod 套件安裝的外置模塊(例如:fuse、ntfs-3g、等)保持一貫性。

按著,請執行:

[root@host ~]# depmod $(uname -r)

以便能建立一個模塊的互賴性清單。

編輯 /etc/modprobe.d/blacklist 這個檔案並加入以下內容:

blacklist bcm43xx
blacklist ndiswrapper
blacklist b43
blacklist b43legacy

透過這樣做,你可以避免這些模塊在開機時被載入內核中。此外,假如你在 /etc/modprobe.conf 內有一行是指定無線介面的驅動程式,例如:

alias eth1 bcm43xx
alias eth1 b43
alias eth1 b43legacy

請將這行註釋掉:

#alias eth1 bcm43xx
#alias eth1 b43
#alias eth1 b43legacy

並為你的無線網絡卡加入新的驅動程式別名:

alias eth1 wl

這一切都假設你的無線網絡介面設備檔是 eth1。

現在,請編輯 /etc/modprobe.d/modprobe.conf.dist 這個檔案並加入以下內容(某些情況下,以下內容或許不是必須的):

alias ieee80211_crypt_tkip ieee80211_crypt_tkip
alias eth1 wl

現在你的驅動應該在每次開機時都會被載入(當然除了在你安裝了新內核之後,到時你必須依照以上步驟將它重新編譯)。

注意: 這個驅動程式無法跨越內核升級(意即當你更新內核後用新內核開機,你必須重做以上步驟)。正因為這個原因,你要將壓縮檔的內容放置在 /usr/local/src/hybrid-wl 內,並更改目錄及內容的擁有者。

註:成功安裝驅動程式後,無線上網的新手經常會匯報 Error for wireless request "Set Encode" (8B2A): SET failed on device... 等問題。最簡便的解決方法就是 設置 NetworkManager 常駐服務替代 network 常駐服務來管理你的網絡連線。

附錄 A:在 CentOS 5.6 上編譯(最新的?)驅動

顯然,對最新發布的驅動來說,并不僅僅存在功能上的問題。衕時,另一個 ' 編譯時' 問題在 CentOS 5.6 上也浮現出來,首先註釋掉廣為人知的 TYPEDEF_BOOL 部分,開始我們的編譯過程:

[milos@host hybrid-new]$ make -C /lib/modules/2.6.18-238.5.1.el5/build M=`pwd`
make: Entering directory `/usr/src/kernels/2.6.18-238.5.1.el5-x86_64'
  LD /tmp/hybrid-new/built-in.o
  CC [M] /tmp/hybrid-new/src/shared/linux_osl.o
In file included from /tmp/hybrid-new/src/shared/linux_osl.c:17:
/tmp/hybrid-new/src/include/typedefs.h:86: error: conflicting types for ‘bool’
include/linux/types.h:36: error: previous declaration of ‘bool’ was here
In file included from /tmp/hybrid-new/src/shared/linux_osl.c:19:
/tmp/hybrid-new/src/include/linuxver.h:88: error: redefinition of typedef ‘work_func_t’
include/linux/workqueue.h:22: error: previous declaration of ‘work_func_t’ was here
make[1]: *** [/tmp/hybrid-new/src/shared/linux_osl.o] Error 1
make: *** [_module_/tmp/hybrid-new] Error 2
make: Leaving directory `/usr/src/kernels/2.6.18-238.5.1.el5-x86_64'

註釋掉 /usr/local/src/hybrid/src/include/linuxver.h 檔案中有問題的第 88 行:

typedef void (*work_func_t)(void *work);

就可以輕鬆解決這個問題。

移除了上文提到的行之後,驅動的編譯很順利。坦誠的講,我至今還沒有嘗試編譯過更早版本的驅動,這也是我現在提出這個問題的根本原因。

Translation of revision 19

zh-tw/HowTos/Laptops/Wireless/Broadcom (last edited 2011-11-10 14:24:46 by TimothyLee)