歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> 學習Linux

在centos7(EL7.3 即 kernel-3.10.0-514.X )上安裝BCM4312無線網卡驅動要注意的問題,centos7bcm4312

在centos7(EL7.3 即 kernel-3.10.0-514.X )上安裝BCM4312無線網卡驅動要注意的問題,centos7bcm4312

在centos7(EL7.3 即 kernel-3.10.0-514.X )上安裝BCM4312無線網卡驅動要注意的問題,centos7bcm4312


  我新裝的centos7主機無法使用裡面自帶的網卡,查詢後發現網卡型號為BCM4312。我在看資料安裝的過程中遇到了些問題,糾結了好久,現在分享下要注意的點,為後來的遇到同樣問題的人提供點幫助。現在開始說正事:

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

第 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。需不需安裝,推薦看下:http://blog.sina.com.cn/s/blog_946b3ae20100yxdm.html

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

  請從Broadcom的官方網站(https://www.broadcom.com/)下載 Broadcom BCM43xx 的 linux 驅動程序壓縮檔到你的機器並將它解壓到 /usr/local/src/hybrid-wl,請隨你所需將這個目錄的擁有者改為無特權的用戶:(我下載的是hybrid-v35_64-nodebug-pcoem-6_30_223_271.tar.gz,把這個包放/usr/local/src/hybrid-wl這個目錄下,我以這個包寫的例子,你根據自己下的包來改動下面的語句。我選的無特權用戶為nobody。)

[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 /usr/local/src/hybrid-wl/hybrid-v35_64-nodebug-pcoem-6_30_223_271.tar.gz
[root@host hybrid-wl]# chown -R nobody.nobody /usr/local/src/hybrid-wl 

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

第 3 步上:編譯 Broadcom 驅動模塊 (在 EL6 和 EL7 上) 

  驅動模塊可以這樣編譯:

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

  請留意引號(即反引號),centos官方的文檔寫的是[user@host hybrid-wl]$ make -C /lib/modules/`uname -r`/build/ M=`pwd`,我照做了,就是通不過,後來發現M前面的/是不需要的,加個空格就行。

  編譯現有的驅動程序(6.30.223.271 版)時,你差不多肯定會獲得一個錯誤信息,而不是一個編譯好的驅動模塊

make: Entering directory `/usr/src/kernels/2.6.32-573.7.1.el6.x86_64'
CFG80211 API is prefered for this kernel version
Using CFG80211 API
  LD /usr/local/src/hybrid-wl/built-in.o
  CC [M] /usr/local/src/hybrid-wl/src/shared/linux_osl.o
  CC [M] /usr/local/src/hybrid-wl/src/wl/sys/wl_linux.o
  CC [M] /usr/local/src/hybrid-wl/src/wl/sys/wl_iw.o
  CC [M] /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.o
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:83: warning: ‘enum tx_power_setting’ declared inside parameter list
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:83: warning: its scope is only this definition or declaration, <snip>
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c: In function ‘wl_cfg80211_join_ibss’:
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:730: error: ‘struct cfg80211_ibss_params’ has no member named ‘channel’
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c: At top level:
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1096: warning: ‘enum tx_power_setting’ declared inside parameter list
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1096: error: parameter 2 (‘type’) has incomplete type
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c: In function ‘wl_cfg80211_set_tx_power’:
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1107: error: ‘TX_POWER_AUTOMATIC’ undeclared (first use in this <snip>
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1107: error: (Each undeclared identifier is reported only once
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1107: error: for each function it appears in.)
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1109: error: ‘TX_POWER_LIMITED’ undeclared (first use in this function)
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1115: error: ‘TX_POWER_FIXED’ undeclared (first use in this function)
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c: At top level:
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1774: warning: initialization from incompatible pointer type
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1779: warning: initialization from incompatible pointer type
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1780: warning: initialization from incompatible pointer type
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1781: warning: initialization from incompatible pointer type
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1782: warning: initialization from incompatible pointer type
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1783: warning: initialization from incompatible pointer type
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1784: warning: initialization from incompatible pointer type
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1789: warning: initialization from incompatible pointer type
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c: In function ‘wl_inform_single_bss’:
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1984: error: too few arguments to function <snip>
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2023: warning: passing argument 1 of ‘cfg80211_put_bss’ from <snip>
include/net/cfg80211.h:3380: note: expected ‘struct wiphy *’ but argument is of type ‘struct cfg80211_bss *’
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2023: error: too few arguments to function ‘cfg80211_put_bss’
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c: In function ‘wl_update_bss_info’:
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2276: error: ‘struct cfg80211_bss’ has no member named <snip>
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2277: error: ‘struct cfg80211_bss’ has no member named <snip>
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2283: warning: passing argument 1 of ‘cfg80211_put_bss’ from <snip>
include/net/cfg80211.h:3380: note: expected ‘struct wiphy *’ but argument is of type ‘struct cfg80211_bss *’
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2283: error: too few arguments to function ‘cfg80211_put_bss’
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c: In function ‘wl_bss_roaming_done’:
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2322: warning: passing argument 2 of ‘cfg80211_roamed’ from <snip>
include/net/cfg80211.h:3726: note: expected ‘struct ieee80211_channel *’ but argument is of type ‘u8 *’
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2322: warning: passing argument 4 of ‘cfg80211_roamed’ makes <snip>
include/net/cfg80211.h:3726: note: expected ‘const u8 *’ but argument is of type ‘s32’
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2322: warning: passing argument 5 of ‘cfg80211_roamed’ makes <snip>
include/net/cfg80211.h:3726: note: expected ‘size_t’ but argument is of type ‘u8 *’
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2322: warning: passing argument 6 of ‘cfg80211_roamed’ makes <snip>
include/net/cfg80211.h:3726: note: expected ‘const u8 *’ but argument is of type ‘s32’
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2322: error: too few arguments to function ‘cfg80211_roamed’
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c: In function ‘wl_update_wowl’:
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2791: warning: unused variable ‘wdev’
make[1]: *** [/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.o] Error 1
make: *** [_module_/usr/local/src/hybrid-wl] Error 2
make: Leaving directory `/usr/src/kernels/2.6.32-573.7.1.el6.x86_64'

  注意: 在 EL6 和 EL7 的步驟由此起有分別。如果是 EL6,你應該遵從第 3 步上;而 EL7 只須應用第 3 步上的修正及第 3 步下的 sed 指命,並按照此步驟(3 上)內的指示編譯它。即是說, EL7 要略過第3步上的 sed 指令。

  在 EL6 上,驅動程序由於 wl_cfg80211_hybrid.c 檔內檢查內核版本的 if-then-else 句式而不能編譯。我們須要執行下列的 sed 替換指令來進行修正: 

。這則信息的內容隨著內核和操作系統版本而變化,但是在 CentOS 6 上它大致上是:

 

[user@host hybrid-wl]$ sed -i 's/[ >][>=] KERNEL_VERSION(2, 6, 3.)/>= KERNEL_VERSION(2, 6, 32)/' src/wl/sys/wl_cfg80211_hybrid.c
[user@host hybrid-wl]$ sed -i 's/[ >][>=] KERNEL_VERSION(3, ., .)/>= KERNEL_VERSION(2, 6, 32)/' src/wl/sys/wl_cfg80211_hybrid.c
[user@host hybrid-wl]$ sed -i 's/[ >][>=] KERNEL_VERSION(3, 11, .)/>= KERNEL_VERSION(2, 6, 32)/' src/wl/sys/wl_cfg80211_hybrid.c
[user@host hybrid-wl]$ sed -i 's/< KERNEL_VERSION(3, 18, .)/< KERNEL_VERSION(2, 6, 30)/' src/wl/sys/wl_cfg80211_hybrid.c
[user@host hybrid-wl]$ sed -i 's/[ >][>=] KERNEL_VERSION(3, 15, .)/>= KERNEL_VERSION(2, 6, 32)/' src/wl/sys/wl_cfg80211_hybrid.c
[user@host hybrid-wl]$ sed -i 's/[ >][>=] KERNEL_VERSION(4, 0, 0)/>= KERNEL_VERSION(2, 6, 32)/' src/wl/sys/wl_cfg80211_hybrid.c
[user@host hybrid-wl]$ sed -i 's/< KERNEL_VERSION(4,2,0)/< KERNEL_VERSION(2, 6, 30)/' src/wl/sys/wl_cfg80211_hybrid.c

  不過,這些 'sed' 替換命令仍未能確保驅動程序可以正常編譯。我們還須要在編譯驅動程序前應用 wl-kmod-fix-ioctl-handling.patch 這個修正。請將它下載至 /usr/local/src 然後執行下列指令來修正驅動程序的源代碼:

[user@host hybrid-wl]$ patch -p1 < ../wl-kmod-fix-ioctl-handling.patch
patching file src/wl/sys/wl_cfg80211_hybrid.c
Hunk #1 succeeded at 1467 (offset 17 lines).
patching file src/wl/sys/wl_linux.c
Hunk #1 succeeded at 1659 (offset 8 lines).

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

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

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

make: Entering directory `/usr/src/kernels/2.6.32-573.7.1.el6.x86_64'
CFG80211 API is prefered for this kernel version
Using CFG80211 API
  LD /usr/local/src/hybrid-wl/built-in.o
  CC [M] /usr/local/src/hybrid-wl/src/shared/linux_osl.o
  CC [M] /usr/local/src/hybrid-wl/src/wl/sys/wl_linux.o
  CC [M] /usr/local/src/hybrid-wl/src/wl/sys/wl_iw.o
  CC [M] /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.o
/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1802: warning: initialization from incompatible pointer type
  LD [M] /usr/local/src/hybrid-wl/wl.o
  Building modules, stage 2.
CFG80211 API is prefered for this kernel version
Using CFG80211 API
  MODPOST 1 modules
  CC /usr/local/src/hybrid-wl/wl.mod.o
  LD [M] /usr/local/src/hybrid-wl/wl.ko.unsigned
  NO SIGN [M] /usr/local/src/hybrid-wl/wl.ko
make: Leaving directory `/usr/src/kernels/2.6.32-573.7.1.el6.x86_64'

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

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

  你會發現驅動模塊的文件尺寸會縮小(由 8.2MB 降至 7.2MB)。而且,你的驅動模塊仍能正常運作。

第 3 步下:編譯 Broadcom 驅動模塊 (EL7需要的部分細節,也是我要重點說的部分)

  許多中文資料都是這麼說的:

 

  寫完這上面4個sed,再make,

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

  就是通不過,後來找到centos WIKI 的英文原版資料才發現,中文翻譯的資料落後了,沒有及時跟新,中文資料只說到EL7.2的事,那EL7.3  即 kernel-3.10.0-514.X該怎麼寫呢?看英文怎麼說吧:

  EL7.3  即 kernel-3.10.0-514.X 需要6個sed:

[user@host hybrid-wl]$ sed -i 's/ >= KERNEL_VERSION(3, 11, 0)/ >= KERNEL_VERSION(3, 10, 0)/' src/wl/sys/wl_cfg80211_hybrid.c
[user@host hybrid-wl]$ sed -i 's/ >= KERNEL_VERSION(3, 15, 0)/ >= KERNEL_VERSION(3, 10, 0)/' src/wl/sys/wl_cfg80211_hybrid.c

[user@host hybrid-wl]$ sed -i 's/ < KERNEL_VERSION(3, 18, 0)/ < KERNEL_VERSION(3, 9, 0)/' src/wl/sys/wl_cfg80211_hybrid.c
[user@host hybrid-wl]$ sed -i 's/ >= KERNEL_VERSION(4, 0, 0)/ >= KERNEL_VERSION(3, 10, 0)/' src/wl/sys/wl_cfg80211_hybrid.c

[user@host hybrid-wl]$ sed -i 's/ < KERNEL_VERSION(4,2,0)/ < KERNEL_VERSION(3, 9, 0)/' src/wl/sys/wl_cfg80211_hybrid.c
[user@host hybrid-wl]$ sed -i 's/ >= KERNEL_VERSION(4, 7, 0)/ >= KERNEL_VERSION(3, 10, 0)/' src/wl/sys/wl_cfg80211_hybrid.c

  別急,EL7.3先得裝個補丁,再跑上面的6個sed,補丁 wl-kmod-kernel_4.7_IEEE80211_BAND_to_NL80211_BAND.patch ,把它下好放到/usr/local/src 目錄下,運行補丁:

[user@host hybrid-wl]$ patch -p1 < /usr/local/src/wl-kmod-kernel_4.7_IEEE80211_BAND_to_NL80211_BAND.patch
patching file src/wl/sys/wl_cfg80211_hybrid.c
Hunk #6 succeeded at 1911 (offset 3 lines).
Hunk #7 succeeded at 2040 (offset 3 lines).
Hunk #8 succeeded at 2160 (offset 3 lines).
Hunk #9 succeeded at 2298 (offset 3 lines).
Hunk #10 succeeded at 2941 (offset 3 lines).

  注意-p1中是數字1。打完了補丁,再輸6個sed,然後再make,

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

  以為就這樣成功了,並沒有,看:

  找了半天,終於發現上圖小紅框中與centos wiki的教程不同,就多了兩個空格,仔細看,小紅框上面和下面的括號裡面都有空格,唯獨這個括號裡面就沒有空格,找到問題了,我再試試,終於跑通了。如下圖:

  同時特別注意第3個和第5個sed中沒有等號,而且箭頭指向與其他sed也不同。

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

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

[root@host ~]# modprobe -r bcm43xx
[root@host ~]# modprobe -r b43
[root@host ~]# modprobe -r b43legacy
[root@host ~]# modprobe -r ssb
[root@host ~]# modprobe -r bcma
[root@host ~]# modprobe -r brcmsmac
[root@host ~]# modprobe -r ndiswrapper

  請將驅動模塊的文件復制到一個可以讓內核找到它的地方:

[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)

  以便能創建一個模塊的互賴性清單。現在我們裝入驅動模塊:

[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

  要是沒有錯誤信息,驅動程序已被裝入及隨時可用。假如你只有無線驅動程序應用 ndiswrapper 內核模塊,你可將它刪除 —— 但這並非必須的。

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

  你仍須額外數個步驟才能在開機時自動裝入模塊。首先,編輯 /etc/modprobe.d/blacklist.conf 這個文件並加入以下內容:

blacklist bcm43xx
blacklist b43
blacklist b43legacy
blacklist bcma
blacklist brcmsmac
blacklist ssb
blacklist ndiswrapper

  什麼?沒有找到/etc/modprobe.d/blacklist.conf那我們就自己寫一個(我用gedit寫的)取名叫作blacklist.conf,再放到那個目錄下就行了。

  通過這樣做,你可以防止這些模塊在開機時被裝入內核中,與 wl 模塊產生沖突。

  另外,若要在開機時裝入 wl 模塊,請創建或者編輯/etc/sysconfig/modules/kmod-wl.modules並把以下內容剪貼到其中:

#!/bin/bash

for M in lib80211 cfg80211 wl; do
    modprobe $M &>/dev/null
done

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

  操作完這些,我終於看到我的屏幕上出現了wifi的圖標:

  好,那我再連個網試試,非常開心,主機可以使用無線網卡上網了。

  最後唠叨一句,原版英文資料是最靠譜的。

參考資料1:https://wiki.centos.org/HowTos/Laptops/Wireless/Broadcom?action=show

http://xxxxxx/Linuxjc/1183950.html TechArticle

Copyright © Linux教程網 All Rights Reserved