zoukankan      html  css  js  c++  java
  • 在centos7(EL7.3 即 kernel-3.10.0-514.X )上安装BCM4312无线网卡驱动要注意的问题

      我新装的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

  • 相关阅读:
    TP5报如下的错误 Indirect modification of overloaded element of thinkpaginatorCollection has no effect【转】
    PHPnumber_format()函数的使用
    蓝桥杯-PREV28-地宫取宝
    HihoCode-1053-居民迁移
    HihoCode-1323-回文字符串
    蓝桥杯-PREV3-带分数
    HDU-6312-Game
    HDU-6438-Buy and Resell
    CF-1117C-Magic Ship
    HDU-2802-F(N)
  • 原文地址:https://www.cnblogs.com/liangliu/p/6237487.html
Copyright © 2011-2022 走看看