Gentoo Linux在MacBook Pro配置Wifi¶
备注
broadcom-sta
私有驱动非常难以安装,对内核互斥选项很多,实际上 ebuild
的维护者也说这个驱动已经不再维护,建议直接购买内核 brcmfmac
驱动支持的兼容无线网卡 BCM943602CS
,在二手市场上只需要20美金。
我准备最后再折腾一下 broadcom-sta 私有驱动安装 最终通过回退 wpa_supplicant 版本2.8 解决无线网卡无流量问题 非常
ugly
,我准备改为采用兼容无线网卡避免新版本内核的退化目前最有希望的方案是参考 Broadcom Wireless Drivers ,该文档是最新的 5.16.11 内核实践,提供了很多修复异常报错的方法
我目前实在没有精力来折腾,所以准备购买Linux兼容的无线网卡来绕过这个问题 为了使用闭源broadcom-sta导致很多新内核特性无法使用实在觉得得不偿失 ,这个闭源驱动从2015年以后就没有更新,所以在最新的内核中需要很多hack才能使用,代价很大
MacBook Pro 15" Late 2013 我在淘宝上花50元换一块 BCM943602CS蓝牙无线模块 省的以后再折腾这种私有驱动了
MacBook Air 13" Early 2014 找不到内置兼容的无线网卡模块,太古老低端设备,我通过购买外接USB无线网卡来解决
Broadcom WiFi¶
早期MacBook Air 11" 2011版¶
我曾经使用过MacBook Air 11" 2011版,这款笔记本使用的是Broadcom B43xx系列,是可以使用 b43-firmware
驱动的,装 b43
驱动即可:
echo "sys-firmware/b43-firmware" >> /etc/portage/package.accept_keywords
echo "sys-firmware/b43-firmware Broadcom" >> /etc/portage/package.license
emerge --ask b43-firmware
Broadcom BCM4360¶
到 MacBook Pro 15" Late 2013 以及我另外一台 MacBook Air 13" Early 2014 ,采用是 Broadcom BCM4360 。这款无线芯片对开源支持不佳,参考 Linux wireless b43文档 可以看到 b43
驱动不支持BCM4360,建议使用 wl
驱动 broadcom-sta
也就是需要使用闭源的Broadcom驱动( Apple Macbook Pro Retina - Closed source Broadcom driver )
# lspci -k
...
03:00.0 Network controller: Broadcom Inc. and subsidiaries BCM4360 802.11ac Wireless Network Adapter (rev 03)
Subsystem: Apple Inc. BCM4360 802.11ac Wireless Network Adapter
Kernel driver in use: bcma-pci-bridge
Kernel modules: bcma
...
内核¶
IEEE 802.11¶
至少需要激活 cfg80211
(CONFIG_CFG80211) 和 mac80211
(CONFIG_MAC80211)
[*] Networking support --->
[*] Wireless --->
<M> cfg80211 - wireless configuration API
[ ] nl80211 testmode command
[ ] enable developer warnings
[ ] cfg80211 certification onus
[*] enable powersave by default
[*] cfg80211 DebugFS entries # 文档没有要求,我选择激活
[ ] support CRDA
[ ] cfg80211 wireless extensions compatibility
<M> Generic IEEE 802.11 Networking Stack (mac80211)
[*] Minstrel
[*] Minstrel 802.11n support
[ ] Minstrel 802.11ac support
Default rate control algorithm (Minstrel) --->
[*] Enable mac80211 mesh networking support # 文档没有要求,但我这个功能有时候有用
-*- Enable LED triggers
-*- Export mac80211 internals in DebugFS
[ ] Trace all mac80211 debug messages
[ ] Select mac80211 debugging features ----
备注
由于需要加载firmware,所以 wireless configuration API (CONFIG_CFG80211) 需要配置成模块方式而不是直接buildin
备注
对于私有驱动, 似乎 需要关闭 mac80211
(CONFIG_MAC80211)
WEXT¶
cfg80211 wireless extensions compatibility
选项( WEXT
)可以支持传统的 wireless-tools
和 iwconfig
:
[*] Networking support --->
[*] Wireless --->
[*] cfg80211 wireless extensions compatibility
备注
我在 Kernel 6.1.12 未找到这个配置项
设备驱动¶
注意,建议将驱动编译为内核模块,因为WiFi驱动通常需要firmware,只有作为模块加载时才能使用firmware:
Device Drivers --->
[*] Network device support --->
[*] Wireless LAN --->
Select the driver for your Wifi network device, e.g.:
<M> Broadcom 43xx wireless support (mac80211 stack) (b43)
[M] Support for 802.11n (N-PHY) devices
[M] Support for low-power (LP-PHY) devices
[M] Support for HT-PHY (high throughput) devices
<M> Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi)
<M> Intel Wireless WiFi DVM Firmware support
<M> Intel Wireless WiFi MVM Firmware support
<M> Intel Wireless WiFi 4965AGN (iwl4965)
<M> Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)
<M> Ralink driver support --->
<M> Ralink rt27xx/rt28xx/rt30xx (USB) support (rt2800usb)
-*- Cryptographic API --->
Accelerated Cryptographic Algorithms for CPU (x86) --->
<*> Ciphers: AES, modes: ECB, CBC, CTS, CTR, XTR, XTS, GCM (AES-NI)
备注
b43
可以在内核源码中激活模块方式编译,但是Broadcom4360需要私有驱动 net-wireless/broadcom-sta 没有编译选项
对于安装私有驱动,上述设备驱动我全关闭了
但是参考 Closed source Broadcom driver 采用激活Intel PRO/Wireless 2100网卡驱动来输出内核的 LIB80211
Device Drivers
-> Network device support
-> Wireless LAN
-> <*> Intel PRO/Wireless 2100 Network Connection
LED支持¶
笔记本内置WiFi没有LED,可忽略
Device Drivers --->
[*] LED Support --->
<*> LED Class Support
[*] Networking support --->
[*] Wireless --->
[*] Enable LED triggers
Firmware¶
根据 gentoo linux wiki: WiFi 文档,除了内核模块编译支持之外,WiFi芯片还需要对应firmware:
WiFi设备 |
驱动 |
Firmware |
说明 |
---|---|---|---|
Broadcom 43xx 无线芯片 |
|
可用于 Aircrack-ng ,如果bcm43xx设备被该驱动支持则通常是最好的选择 |
|
Broadcom PCIe和SDIO/USB设备 |
缺乏节能,LED支持以及一些其他功能 |
||
Broadcom 43xx 无线芯片 |
|
私有驱动,没有AP或监控模式,可以支持 |
快速起步: Broadcom BCM4360驱动和Firmware¶
备注
上文的絮絮叨叨,实际上你要快速解决问题的话,只有一个步骤: 见这里
综上所述,对于 Broadcom BCM4360 实际上就只有安装私有驱动和firmware了,几乎连内核驱动模块都省了:
安装
wl
驱动和firmware:
emerge --ask net-wireless/broadcom-sta
备注
net-wireless/broadcom-sta
同时包含了驱动和firmware
broadcom-sta
编译时会检查当前内核编译配置,如果有冲突选项会提示,按提示调整内核编译配置,例如我遇到以下内核配置需要关闭:
X86_INTEL_LPSS #位于 "Processor type and features ==> Intel Low Power Subsystem Support"
PREEMPT_RCU 不能设置为 Preemptible Kernel 的 Preemption Model #位于General setup ==> RCU Subsystem
经验总结¶
实际上最好的内核参数校验(是否满足
wl
正常运行)就是安装net-wireless/broadcom-sta
输出信息将输出信息项和
/usr/src/linux/.config
进行对比就知道内核配置有哪些不能满足闭源wl
驱动的运行条件
genkernel
内核安装 broadcom-sta
¶
安装
wl
驱动和firmware:
emerge --ask net-wireless/broadcom-sta
提示错误显示
net-wireless/broadcom-sta
已经被masked
:
!!! All ebuilds that could satisfy "net-wireless/broadcom-sta" have been masked.
!!! One of the following masked packages is required to complete your request:
- net-wireless/broadcom-sta-6.30.223.271-r7::gentoo (masked by: ~amd64 keyword)
这里软件被屏蔽的原因是 ~amd64
关键字,有两种方式解决,
方法一: 在 Gentoo make.conf 中配置接受测试版本:
ACCEPT_KEYWORDS="~amd64"
方法二(建议): 在 /etc/portage/package.accept_keywords
中添加你想安装的被mask的关键字:
#直接使用 /etc/portage/package.accept_keywords
#echo "net-wireless/broadcom-sta" >> /etc/portage/package.accept_keywords
#或者 /etc/portage/package.accept_keywords 目录下分别配置针对不同应用的配置
#这里举例为fcitx5配置 /etc/portage/package.accept_keywords/fcitx5
app-i18n/fcitx ~amd64
x11-libs/xcb-imdkit ~amd64
app-i18n/fcitx-chinese-addons ~amd64
app-i18n/fcitx-rime ~amd64
app-i18n/rime-data ~amd64
app-i18n/libime ~amd64
app-i18n/fcitx-qt ~amd64
app-i18n/fcitx-gtk ~amd64
app-i18n/fcitx-configtool ~amd64
dev-qt/qtcore ~amd64
# dev-libs/boost-1.84.0 required by fcitx-chinese-addons (~amd64)
dev-libs/boost ~amd64
当初次完成 在MacBook Pro上安装Gentoo Linux 采用通用发行版内核时,会提示如下信息:
* Messages for package net-wireless/broadcom-sta-6.30.223.271-r7:
* B43: If you insist on building this, you must blacklist it!
* BCMA: If you insist on building this, you must blacklist it!
* SSB: If you insist on building this, you must blacklist it!
* X86_INTEL_LPSS: Please disable it. The module does not work with it enabled.
* MAC80211: If you insist on building this, you must blacklist it!
* LIB80211_CRYPT_TKIP: You will need this for WPA.
* PREEMPT_RCU: Please do not set the Preemption Model to "Preemptible Kernel"; choose something else.
按照提示,需要配置 blocklist
屏蔽冲突内核模块 也就是配置 /etc/modprobe.d/blacklist.conf
如下:
blacklist b43
blacklist bcma
blacklist sbb
blacklist mac80211
警告
必须在操作系统启动时屏蔽掉上述冲突的内核模块,否则即使加载了 wl
模块,也看不到对应的网卡
移除冲突内核模块,加载
wl
内核模块:
depmod –a
rmmod b43
rmmod ssb
rmmod wl
modprobe wl
需要重新编译内核(并且每次升级内核都需要重新安装一次
net-wireless/broadcom-sta
并重新编译内核):
genkernel all
重启系统后,如果正确加载了
wl
内核模块,那么可以看到一块新出现的无线网卡wlp3s0
PREEMPT_RCU
冲突¶
我在最新的 6.1.12 内核安装 broadcom-sta
遇到报错:
PREEMPT_RCU: Please do not set the Preemption Model to "Preemptible Kernel"; choose something else.
这个问题在 emerge broadcom-sta fails (6.1.12 kernel) due to PREEMPT_RCU 有解决建议:
PREEMPT_RCU
不能直接修改(确实,我在配置选项中没有找到)在
General setup
中 当选择以下preemption models
时PREEMPT_RCU
会自动选择:Preemptible Kernel (Low-Latency Desktop) # 位于 General setup => Preemption Model
Fully Preemptible Kernel (Real-Time) (this might not be available on all CPU architectures)
在
General setup
中如果激活PREEMPT_DYNAMIC
就会自动选择
果然,原来我选择激活了 Gneeral setup => Preemption behaviour defined on boot
,这个选项就是 PREEMPT_DYNAMIC=y
,就是这个选项导致。真是这个选项激活导致了 PREEMPT_RCU
出现,我取消这个配置就可以了
配置 使用wpa_supplicant连接无线网络¶
和 Ubuntu Linux 配置 使用wpa_supplicant连接无线网络 或者 arch linux使用wpa_supplicant连接无线网络 类似,采用 wpa_supplicant
可以轻松配置无线连接:
检查无线网络:
rfkill list
输出显示当前状态,可以看到无线网络没有屏蔽:
0: hci0: Bluetooth
Soft blocked: no
Hard blocked: no
1: phy0: Wireless LAN
Soft blocked: no
Hard blocked: no
2: brcmwl-0: Wireless LAN
Soft blocked: no
Hard blocked: no
创建初始配置:
wpa_passphrase your-ESSID your-passphrase | sudo tee /etc/wpa_supplicant/wpa_supplicant.conf
sudo chmod 600 /etc/wpa_supplicant/wpa_supplicant.conf
通过 OpenRC 启动
wpa_supplicant
服务:
rc-update add wpa_supplicant default
rc-service wpa_supplicant start
异常排查¶
警告
我折腾了很久 wlp3s0
无线网卡无数据流量的问题,最初以为是内核编译问题,但是实际上最终解决的方法是将 wpa_supplicant
回退到旧版本 2.8
解决。非常坑
wlp3s0
无线网卡没有任何数据包进出(观察ifconfig
输出显示 RX/TX 包都是0)
通过前台执行命令 wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant.conf -i wlp3s0
可以看到输出了错误信息:
Successfully initialized wpa_supplicant
wlp3s0: CTRL-EVENT-SCAN-FAILED ret=-22 retry=1
wlp3s0: CTRL-EVENT-SCAN-FAILED ret=-22 retry=1
...
参考 gentoo linux wiki: WiFi 提到,当操作系统启动时, dmesg
或 journalctl 中应该有对应的firmware probe,则我现在检查 dmesg -T | grep -i firmware
输出:
[Sat Dec 30 20:14:24 2023] Spectre V2 : Enabling Restricted Speculation for firmware calls
[Sat Dec 30 20:14:24 2023] ACPI: [Firmware Bug]: BIOS _OSI(Linux) query ignored
[Sat Dec 30 20:14:24 2023] acpi PNP0A08:00: [Firmware Info]: MMCONFIG for domain 0000 [bus 00-9b] only partially covers this bridge
[Sat Dec 30 20:14:30 2023] Loading firmware: regulatory.db
[Sat Dec 30 20:14:30 2023] Loading firmware: regulatory.db.p7s
IPW2100
¶
参考 Apple Macbook Pro Retina (early 2013)#Wireless 其中提到闭源Broadcom驱动需要内核中输出 LIB80211
,这个配置是通过将 Intel PRO/Wireless 2100 Network Connection
直接编译进内核(不是模块)来实现的。不过,需要注意这个 Intel Pro/Wireless 2100 Network Connection
默认是编译为模块,因为它依赖的内核部分是模块形式导致,需要仔细调整,强制为直接编译进内核:
Device Drivers
-> Network device support
-> Wireless LAN
-> <*> Intel PRO/Wireless 2100 Network Connection
这里有一个模块依赖关系:
IPW2100 (m) => CFG80211 (m) => RFKILL (m)
Networking support --->
Wireless --->
<*> cfg80211 - wireless configuration API
< > Generic IEEE 802.11 Networking Stack (mac80211)
RF switch subsystem support --->
<*> GPIO RFKILL driver
Device Drivers --->
Network device support --->
Wireless LAN --->
[*] Intel devices
<*> Intel PRO/Wireless 2100 Network Connection
最终解决方法是前文的 经验总结 : 对比 net-wireless/broadcom-sta
安装后的输出信息 和 /usr/src/linux/.config
,调整内核配置。 也就是 grep XXX /usr/src/linux/.config
,我发现我的错误在于依然包含了冲突配置:
CONFIG_SSB=m
CONFIG_X86_INTEL_LPSS=y <= Intel Low Power Subsystem Support
CONFIG_PREEMPT_RCU=y
PREEMPT_RCU
¶
备注
Broadcom Wireless Drivers 文档提到 ERROR: PREEMPT_RCU
可以忽略,原因不明
这个 PREEMPT_RCU
非常难找,在 make menuconfig
中,通过 /PREEMPT_RCU
找不到入口。参考 How to disable CONFIG_PREEMPT_RCU in 5.14 kernel ,这个配置在 3.14 内核没有激活,到 5.14 内核默认激活
根据 make menuconfig
搜索 /PREEMPT_RCU
可以看到提示这个选项在 kernel/rcu/Kconfig:19
提供: 所以查看源码中 /usr/src/linux/kernel/rcu/Kconfig
# SPDX-License-Identifier: GPL-2.0-only
#
# RCU-related configuration options
#
menu "RCU Subsystem"
config TREE_RCU
bool
default y if SMP
# Dynticks-idle tracking
select CONTEXT_TRACKING_IDLE
help
This option selects the RCU implementation that is
designed for very large SMP system with hundreds or
thousands of CPUs. It also scales down nicely to
smaller systems.
config PREEMPT_RCU
bool
default y if PREEMPTION
select TREE_RCU
help
This option selects the RCU implementation that is
designed for very large SMP systems with hundreds or
thousands of CPUs, but for which real-time response
is also required. It also scales down nicely to
smaller systems.
Select this option if you are unsure.
上述 Kconfig
可以看出选择的链路:
SMP
选择了CONTEXT_TRACKING_IDLE
导致TREE_RCU
为Y
TREE_RCU
选择之后就会导致PREEMPT_RCU
为Y
但是,我还是没有找到可以调整的入口,看起来在最新的Kernel 这个配置是固化的?
警告
太折腾了,我最终还是没有解决在最新的 Kernel 6.1.67 上支持 BCM4360 网卡的私有驱动 broadcom-sta (wl)的安装,太累了,放弃... 突然找到了解决方案,最后再试一下
我理解关闭内核 RCU PREEMPT_RCU
对性能是有影响的,无法充分发挥最新内核的特性。加上实在太折腾了,我放弃继续安装 broadcom-sta
,准备更换无线网卡硬件,采用内核原生开源驱动。
或许早期内核版本能够使用这个网卡驱动?
备注
我学习和整理了内核的 RCU概览 知识点,算是为这次无线网卡折腾画个句号。
最终的解决方法¶
根据 Broadcom Wireless Drivers 文档经验,原来最新版本的 wpa_supplicant
是无法配合 broadcom-sta
驱动工作的,需要回退到 2019 年的 wpa_supplicant-2.8
版本
mkdir ~/compile
cd compile
wget https://w1.fi/releases/wpa_supplicant-2.8.tar.gz
tar -xvf wpa_supplicant-2.8.tar.gz
cd wpa_supplicant-2.8
需要修订 wpa_supplicant
编译配置,所以修改源代码 ./wpa_supplicant/.config
如下:
CONFIG_BACKEND=file
CONFIG_CTRL_IFACE=y
CONFIG_DEBUG_FILE=y
CONFIG_DEBUG_SYSLOG=y
CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
CONFIG_DRIVER_NL80211=y
CONFIG_DRIVER_WEXT=y
CONFIG_DRIVER_WIRED=y
CONFIG_EAP_GTC=y
CONFIG_EAP_LEAP=y
CONFIG_EAP_MD5=y
CONFIG_EAP_MSCHAPV2=y
CONFIG_EAP_OTP=y
CONFIG_EAP_PEAP=y
CONFIG_EAP_TLS=y
CONFIG_EAP_TTLS=y
CONFIG_IEEE8021X_EAPOL=y
CONFIG_IPV6=y
CONFIG_LIBNL32=y
CONFIG_PEERKEY=y
CONFIG_PKCS12=y
CONFIG_READLINE=y
CONFIG_SMARTCARD=y
CONFIG_WPS=y
CFLAGS += -I/usr/include/libnl3
删除掉系统已经安装的
wpa_supplicant
并清理:
sudo emerge --deselect net-wireless/wpa_supplicant
sudo emerge --depclean
最后完成编译安装:
cd wpa_supplicant
make
sudo make install
果然, 使用旧版wpa_supplicant 就能够正常发起通讯,此时无线网卡已经显示有数据流量。
接下来 wpa_supplicant
和上文相同,不再重复
其他问题¶
旧版 wpa_supplicant
在连接 802.1x和EAP 报错:
...
wlp3s0: CTRL-EVENT-EAP-PEER-ALT depth=0 EMAIL: XXXX
OpenSSL: EVP_DigestInit_ex failed: error:0308010C:digital envelope routines::unsupported
...
这个报错 error:0308010C:digital envelope routines::unsupported
在 Node.js Atlas version 17 中常见,原因是不支持 TLS 导致。我感觉我回退到旧版本的 wpa_supplicant
应该也是存在这个异常问题的,不过我没有再折腾解决这个问题。(参考 Error: error:0308010c:digital envelope routines::unsupported [Node Error Solved] )