失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > CentOS7 Broadcom无线网卡驱动安装

CentOS7 Broadcom无线网卡驱动安装

时间:2019-11-07 15:07:11

相关推荐

CentOS7 Broadcom无线网卡驱动安装

为什么80%的码农都做不了架构师?>>>

一台使用多年的联想G450笔记本,在退休之际,还可以用来研究一下Linux,于是装上了CentOS7,但安装后发现竟然无法使用WiFi,搜索一圈之后,才知道机器自带的博通(Broadcom)无线网卡的Linux驱动是需要自己安装的。于是,就这个安装的过程,竟然耗费了我1天的时间,所以记录在这里。

网上也有不少的文章,但是安装到一半,总是出现这种错那种错,后来看到CentOS官方论坛上有一篇关于如何在CentOS环境中安装Broadcom无线网卡驱动的WiKi,这篇文章极大的帮助了我,并最终伴我安装成功(事实证明,还是官方文档靠谱)。本文和原文会有大部分重复的内容,但这里旨在记录我自己安装的整个过程。

CentOS版本:

[user@host ~]$ uname -aLinux host 3.10.0-514.21.2.el7.x86_64 #1 SMP Tue Jun 20 12:24:47 UTC x86_64 x86_64 x86_64 GNU/Linux

第 1 步:辨认无线网络芯片及安装时依赖的组件

确定无线网卡型号,我这里是BCM4312:

[user@host ~]$ lspci | grep Broadcom04:00.0 Network controller: Broadcom Limited BCM4312 802.11b/g LP-PHY (rev 01)07:00.0 Ethernet controller: Broadcom Limited NetLink BCM5906M Fast Ethernet PCI Express (rev 02)

安装网卡驱动时必要的软件:

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

第 2 步:下载并解压 Broadcom 驱动程序的压缩档

从博通官方网站上搜索网卡型号bcm4312:

从搜索结果中选择对应的驱动程序源代码,它是一个压缩包,名字叫Linux® STA 64-bit driver(我安装的CentOS是64位的):

为什么只提供了源代码呢?上方的搜索结果中是这样描述的:All Linux. operating-system-specific code is provided in source form,making it possible to retarget to different kernel versions and fix operating system related issues.

接下来,按照官方步骤,将它解压到 /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 xvzf /path/to/the/tarball/hybrid-v35_64-nodebug-pcoem-6_30_223_271.tar.gz[root@host hybrid-wl]# chown -R user.user /usr/local/src/hybrid-wl

编译前(解压后)的文件列表:

接下来,官方把第三步分为上和下两个小步骤,而且两个步骤有交叉的地方,也就是读到这里,感觉不太理解,所以这里我把EL6和EL7的步骤分开。

第 3 步 a:编译 Broadcom 驱动模块 (EL6)

【说明,由于我安装的系统是EL7的,所以本步骤没有经过测试,因此无截图】

SETP1.编译驱动模块:

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

参数-C:make命令的参数,指定编译的目录;参数M:驱动程序的Makefile文件需要的参数

编译现有的驱动程序(6.30.223.271 版)时,你差不多肯定会获得一个错误信息,这则信息的内容随着内核和操作系统版本而变化,但是在 CentOS 6 上它大致上是:

make: Entering directory `/usr/src/kernels/2.6.32-573.7.1.el6.x86_64'CFG80211 API is prefered for this kernel versionUsing CFG80211 APILD /usr/local/src/hybrid-wl/built-in.oCC [M] /usr/local/src/hybrid-wl/src/shared/linux_osl.oCC [M] /usr/local/src/hybrid-wl/src/wl/sys/wl_linux.oCC [M] /usr/local/src/hybrid-wl/src/wl/sys/wl_iw.oCC [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:: 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:: 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 1make: *** [_module_/usr/local/src/hybrid-wl] Error 2make: Leaving directory `/usr/src/kernels/2.6.32-573.7.1.el6.x86_64'

在 EL6 上,驱动程序由于wl_cfg80211_hybrid.c内检查内核版本的 if-then-else 句式而不能编译。

STEP2.我们须要执行下列的 sed 替换指令来进行修正:

[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

STEP3.我们还须要在编译驱动程序前应用wl-kmod-fix-ioctl-handling.patch这个修正。请将它下载至 /usr/local/src 然后执行下列指令来修正驱动程序的源代码:

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

STEP4.用上述命令再次编译驱动模块,编译器的输出应该类似这样:

make: Entering directory `/usr/src/kernels/2.6.32-573.7.1.el6.x86_64'CFG80211 API is prefered for this kernel versionUsing CFG80211 APILD /usr/local/src/hybrid-wl/built-in.oCC [M] /usr/local/src/hybrid-wl/src/shared/linux_osl.oCC [M] /usr/local/src/hybrid-wl/src/wl/sys/wl_linux.oCC [M] /usr/local/src/hybrid-wl/src/wl/sys/wl_iw.oCC [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 typeLD [M] /usr/local/src/hybrid-wl/wl.oBuilding modules, stage 2.CFG80211 API is prefered for this kernel versionUsing CFG80211 APIMODPOST 1 modulesCC /usr/local/src/hybrid-wl/wl.mod.oLD [M] /usr/local/src/hybrid-wl/wl.ko.unsignedNO SIGN [M] /usr/local/src/hybrid-wl/wl.komake: Leaving directory `/usr/src/kernels/2.6.32-573.7.1.el6.x86_64'

STEP5.一旦这个模块被建成,你便可以删除不必要的符号:

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

第 3 步 b:编译 Broadcom 驱动模块 (EL7)

STEP1.编译命令(和3a的STEP1相同):

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

结果证明:这里这两个参数都无需传入,只需要一个make命令即可,见下方截图,因为Makefile文件中会有默认值。

同样,直接编译肯定会失败,在我的机器上,Error的信息如下:

STEP2.查看linux的release版本:

[user@host hybrid-wl]$ lsb_release -a

在EL7上,这里有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

STEP3.如果是EL7.3(我这里就是,否则跳过这一步),则需要下载补丁包:wl-kmod-kernel_4.7_IEEE80211_BAND_to_NL80211_BAND.patch(还是放在/usr/local/src中。这个文件的链接官方文档没有给出,是我根据步骤3a拼接上去的),并使用如下命令修改:

[user@host hybrid-wl]$ patch -p1 < ../wl-kmod-kernel_4.7_IEEE80211_BAND_to_NL80211_BAND.patchpatching file src/wl/sys/wl_cfg80211_hybrid.c

STEP4.根据不同的发行版本,执行不同的替换脚本:

EL 7.0 的内核(即 kernel-3.10.0-123.X)不须以上任何指令,EL 7.1 的内核(即 kernel-3.10.0-229.X)须要前两个指令,EL 7.2 的内核(即 kernel-3.10.0-327.X)须要前四个指令,EL 7.3 的内核(即 kernel-3.10.0-514.X)须要执行全部六个 sed 指令

我这里是EL7.3,所以把6条set命令全部执行。

总结:EL6中,是先执行sed替换,后执行patch替换;EL7中,是先执行patch替换(如果需要),再执行sed替换。

STEP5.再次编译,以下编译成功的日志:

编译成功后,文件列表:

STEP6.此时,你便可以删除不必要的符号,这样可以将文件wl.ko的体积缩小,但却不影响功能:

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

-----------------后续步骤和官方文档一致-------------------

第 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 内核模块,你可将它删除 —— 但这并非必须的。

第 5 步:在开机时将驱动模块装入内核中

你仍须额外数个步骤才能在开机时自动装入模块。首先,编辑/etc/modprobe.d/blacklist这个文件并加入以下内容:

blacklist bcm43xxblacklist b43blacklist b43legacyblacklist bcmablacklist brcmsmacblacklist ssbblacklist ndiswrapper

通过这样做,你可以防止这些模块在开机时被装入内核中,与wl模块产生冲突。另外,若要在开机时装入wl模块,请创建/编辑/etc/sysconfig/modules/kmod-wl.modules并把以下内容剪贴到其中:

#!/bin/bashfor M in lib80211 cfg80211 wl; domodprobe $M &>/dev/nulldone

现在你的驱动应该在每次开机时都会被装入(当然除了在你安装了新内核之后,到时你必须依照以上步骤将它重新编译)。

最后,上效果图:

网络设置页面:

------------------安装过程完-----------------

其实,在安装步骤(3b)的一开始,我也遇到过以下错误:

KBUILD_NOPEDANTIC=1 make -C /lib/modules/`uname -r`/build M=`pwd`make: *** /lib/modules/3.10.0-514.21.2.el7.x86_64/build: 没有那个文件或目录。 停止。

这个错误也老是出现(导致我去搜索了好多资料,然而无济于事):

KBUILD_NOPEDANTIC=1 make -C /lib/modules/`uname -r`/build M=`pwd`make: *** /lib/modules/3.10.0-514.21.2.el7.x86_64/build: 没有指明目标并且找不到makefile。停止。

出现这两个问题的根本原因是由于我的机器刚安装完CentOS,当时是无网络状态下安装的,CentOS-repo也没更新,所以有很多配置没完成,软件也没有更新。

解决办法:更新CentOS-repo地址,重启电脑,执行更新,20分钟后更新完成,再次编译,这两个错误就消失了。

可以通过以下命令更新CentOS-repo地址:

cd /etc/yum.repos.d/ --进入yum配置文件目录sudo mv CentOS-Base.repo CentOS-Base.repo.bak --备份配置文件sudo wget /.help/CentOS6-Base-163.repo --下载163的配置sudo mv CentOS6-Base-163.repo CentOS-Base.repo --重命名sudo yum update --更新

参考资料:

/zh/HowTos/Laptops/Wireless/Broadcom

/image-text/config//0723/3339.html

如果觉得《CentOS7 Broadcom无线网卡驱动安装》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。