ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Ubuntu离线安装RTL8852BE驱动:从依赖到DKMS完整指南

Ubuntu离线安装RTL8852BE驱动:从依赖到DKMS完整指南 前几天给一台闲置笔记本装 Ubuntu 20.04系统装完了网卡却变成了一块废铁。lspci里清清楚楚写着Realtek Semiconductor Co., Ltd. Device b852也就是很常见的 RTL8852BE Wi-Fi 6 网卡可 Ubuntu 20.04 默认的 5.4 内核压根不认识它。更要命的是这台机器没有有线网口想联网装驱动又必须先有网直接陷入先有鸡还是先有蛋的死局。这篇文章把我这次离线装 b852 驱动的完整过程写下来包括依赖包怎么获取、dkms 怎么注册、Secure Boot 和固件缺失这几个大坑怎么跳给正在折腾同样网卡的朋友一份能直接照着抄的作业。不管你是刚接触 Linux 的新手还是第一次碰 Realtek 离线驱动的老手这篇都能帮你省下至少半天排查时间。1. 先别急着编译搞清楚 b852 的芯片身份和驱动来源1.1 用 lspci 一句话锁定网卡型号很多朋友拿到一张不认的网卡第一反应是去网上搜Ubuntu 无线网卡驱动结果下载了一堆不知道能不能用的东西。我的习惯是先在终端里执行lspci -nn | grep -i network输出大概是这样的02:00.0 Network controller [0280]: Realtek Semiconductor Co., Ltd. Device [10ec:b852]10ec是 Realtek 的厂商 IDb852是设备 ID。拿这个设备 ID 去查资料就非常明确了它是 RTL8852BEWi-Fi 6 标准的 PCIe 无线网卡联想 IdeaPad、戴尔 Inspiron、HP Pavilion 这些中端笔记本上出镜率很高。这里有个细节要提醒lspci 显示的是Device b852而不是RTL8852BE这种通俗名字。这是很正常的因为设备 ID 才是内核和驱动真正用来匹配硬件的依据。不要看到 b852 就觉得是某个未知杂牌它就是 RTL8852BE 的 PCIe 版本编号。后面编译驱动、查固件文件全部要围绕这个 ID 展开。RTL8852BE 还有几个近亲兄弟比如 RTL8852AE 是另一个接口版本RTL8852CE 是更新的型号它们的设备 ID 各不相同固件文件也不通用。如果你不确认型号就随便拿一个仓库来编译大概率会在加载模块时报unknown symbol或者固件加载失败。所以第一步花三十秒跑一条命令后面所有工作都不会白做。1.2 为什么 Ubuntu 20.04 默认内核不认账Ubuntu 20.04 发布时用的是 5.4 内核那时候 Realtek 的 Wi-Fi 6 网卡驱动还是一片空白。内核社区到 5.12 版本才第一次合入rtw89驱动最初的版本只支持 RTL8852AERTL8852BE 被正式支持又晚了好几个版本。所以你在 5.4 内核下看不到无线网卡ip link里没有任何 wlan 接口nmcli dev status里只有一个 ethernet这些现象都是预期内的。有一个例外情况如果你装 Ubuntu 20.04 时选了安装 HWE 内核也就是 Hardware Enablement 内核uname -r会显示 5.15 甚至更高。新内核里可能已经自带了rtw89_8852be模块直接执行modprobe rtw89_8852be就可能生效。不过我实测下来HWE 内核本身也会带来头文件版本不匹配的坑而且如果你用的是个纯离线环境还是会卡在依赖获取上。所以无论旧内核新内核把离线依赖准备这一关踏踏实实做好才是最稳的路线。1.3 能驱动 b852 的三条路径我为什么选它目前社区能驱动 RTL8852BE 的方案大概有三条方案模块名维护状态我的推荐度内核主线自带 rtw89rtw89_8852be持续合入首选lwfinger/rtw89 GitHub 仓库rtw89_8852be更新频繁支持旧内核离线安装首选HRex39/rtl8852be 老仓库8852be更新较慢内核兼容性有限备用内核主线自带驱动是最理想的但 Ubuntu 20.04 默认 5.4 内核没法直接享受。lwfinger 的 rtw89 仓库是社区里维护质量比较高的源码里带了固件文件和 DKMS 脚本编译安装的路径很完整这也是我最后实际采用的方案。HRex39 那个老仓库在更早的时候救过不少人但在新内核上会出现 API 不兼容的编译报错所以只把它当成备胎。2. 离线环境的物资准备把所有依赖包提前囤齐2.1 源码包的选择与获取先讲驱动源码。如果你在能上网的机器上直接访问 GitHub 的 lwfinger/rtw89 仓库把主分支打包下载成 zip 文件或者用 git clone 拉下来。源码包大概几兆字节里面包含了驱动源码、固件目录和一个 DKMS 安装脚本。这里有个很关键的经验不要在目标离线的 Ubuntu 机器上直接git clone因为大多数离线环境根本没有 git 和网络。你要把源码包放在 U 盘或移动硬盘里再带过去。U 盘文件系统建议用 FAT32 或 exFAT避免 NTFS 在某些 Linux 环境下需要额外安装 ntfs-3g 才能读写。虽然 20.04 默认已经能读 NTFS但 FAT32 是最省心的。如果你用的是 rtw89 仓库需要在有网机器上确认源码树里是否包含firmware/rtw8852b_fw.bin这个文件。我在实际下载的版本里是有的安装脚本会把它复制到/lib/firmware/rtw89/目录。如果没有这个文件后面加载模块时就会报固件缺失那又要多折腾一轮。2.2 编译链依赖清单比想象中更费心驱动源码编译需要一套完整的工具链和内核头文件。我把这次用到的依赖包整理成了一张表你在准备阶段可以直接照抄软件包作用离线安装方式必须性build-essentialgcc、g、make 等编译工具dpkg -i 安装 deb必须linux-headers-$(uname -r)与当前内核匹配的头文件dpkg -i 安装 deb必须dkms注册驱动模块内核升级后自动重新编译dpkg -i 安装 deb强烈建议bc内核编译脚本需要的计算器工具dpkg -i 安装 deb必须flex、bison内核模块的语法分析器dpkg -i 安装 deb常见必须pkg-config编译时获取库信息dpkg -i 安装 deb视版本而定很多教程只提 build-essential 和 linux-headers结果编译到一半报flex: command not found或者bc: command not found。对于 rtw89 仓库的代码flex、bison、bc 这几个工具基本绕不开。所以我的建议是干脆一次性全备齐别抱着省事的心态缺一个小工具就能卡住整个编译流程。2.3 用 apt 打包下载 deb 依赖的正确姿势在有网络的 Ubuntu 20.04 机器上准备依赖包的方式有两种我个人推荐第二种。第一种是直接执行apt download 包名但它只会下载你指定的那一个包不会自动下载依赖。如果你需要 20 个关联包手写命令会非常痛苦。第二种是我实际用的方法利用apt install --download-onlymkdir -p ~/offline-packages cd ~/offline-packages sudo apt update sudo apt install --download-only build-essential dkms bc flex bison pkg-config # 再回过头来把具体版本的内核头文件下载下来 apt download linux-headers-$(uname -r)执行完之后所有下载好的 deb 文件都在/var/cache/apt/archives/目录里。把它们复制到 U 盘mkdir -p ~/offline-packages sudo cp /var/cache/apt/archives/*.deb ~/offline-packages/需要注意一个问题uname -r是当前这台有网机器的内核版本如果你是在另一台机器上给目标机准备依赖不能直接照搬。你必须先知道目标机的内核版本号然后手动指定apt download linux-headers-5.4.0-26-generic linux-headers-5.4.0-26这里的5.4.0-26是目标机uname -r的输出。版本号对不上编译出的模块根本无法加载。2.4 传输文件的几种实用方案依赖包装好之后怎么把它弄到离线的目标机器上也有讲究。最简单的是 U 盘拷贝但我在实际操作中发现如果你手头有一台可以开网络的临时设备比如手机开 USB 网络共享那目标机器就能短暂联网此时直接用scp从局域网另一台机器拉取 deb 包会快得多。手机 USB 网络共享这个技巧值得单独说一下。很多安卓手机通过 USB 线连上电脑后在设置里打开USB 网络共享Ubuntu 就能自动识别出一个有线网络接口目标机立刻就能访问互联网。这个方法不依赖任何网卡驱动因为 RNDIS 协议在 Ubuntu 20.04 里是原生支持的。如果你的网络环境允许这是解决离线死局的最高效手段如果彻底没有外部网络那 U 盘方案就是兜底。3. 把地基打好内核头文件与工具链的离线安装3.1 版本匹配是头等大事在目标机器上首先要确认内核版本。执行uname -r假如输出是5.4.0-26-generic那么你需要的头文件包就是linux-headers-5.4.0-26-generic和linux-headers-5.4.0-26。这两个 deb 通常配套安装缺一不可。如果只装了linux-headers-5.4.0-26-generic而没装公共头文件目录编译时一样会报找不到linux/version.h这类错误。判断头文件是否已安装可以看目录ls /usr/src/正常情况下会出现linux-headers-5.4.0-26-generic这样的文件夹。如果目录里空空如也或者只有linux-headers-5.4.0-26没有-generic后缀的那部分都说明头文件不完整重装一遍最省事。3.2 按顺序 dpkg 安装依赖错误怎么处理把 U 盘里的 deb 包目录挂载到目标机后我习惯先不急着dpkg -i *.deb一把梭因为如果 deb 包的加载顺序不对dpkg 会抱怨依赖不满足。虽然很多情况下 apt 会自动解析但在离线环境里dpkg -i不会处理依赖关系。我的做法是先安装 linux-headers 相关的包cd 你的deb目录 sudo dpkg -i linux-headers-5.4.0-26_*.deb sudo dpkg -i linux-headers-5.4.0-26-generic_*.deb然后再安装工具链和辅助工具sudo dpkg -i build-essential_*.deb dkms_*.deb bc_*.deb flex_*.deb bison_*.deb pkg-config_*.deb如果中途报依赖缺失比如gcc-9-base没装上不要慌。去 deb 目录里找对应的包先把它装上然后再重新执行一次 dpkg 命令。所有 deb 都在同一个目录下时最简单的方式是sudo dpkg -i *.deb这个命令会自动重试安装目录里所有未安装的包你只需要多执行两次等它不再报错为止。这也是离线安装 deb 的一个通用经验不要期待一次成功多跑几遍直到 dpkg 把所有依赖关系都理顺。3.3 验证编译环境是否可用依赖装完一定要主动验证一下而不是直接去编译驱动。我的验证命令如下gcc --version make --version dkms --version ls /usr/src/linux-headers-$(uname -r)如果 gcc 能输出版本号/usr/src 下也有对应的头文件目录那编译环境就基本到位了。这里还有一个容易忽略的点gcc版本需要与内核头文件期望的版本兼容。Ubuntu 20.04 官方源里的 gcc-9 搭配 5.4 内核是没有问题的。如果你为了编译其他东西装了 gcc-12某些内核模块可能会因编译器版本过新而告警但一般不影响最终结果。4. 编译并安装驱动从源码到 modprobe 的完整动作4.1 解压源码先看 README把 rtw89 源码包传到目标机后我建议先解压然后打开 README 或 INSTALL 文件看一看。lwfinger 的 rtw89 仓库会在文档里写明当前支持的内核范围、编译命令和 DKMS 安装方式。这个动作花不了两分钟但能避免你因为仓库分支不同而用了错误的安装方式。tar -zxvf rtw89-master.tar.gz cd rtw89-master4.2 编译安装的完整命令流程在源码目录里依次执行make -j$(nproc)-j$(nproc)会让 make 根据 CPU 核心数并行编译速度快不少如果你的机器只有两个核心建议直接用make避免内存不足。编译完成后看到rtw89_8852be.ko这样的.ko模块文件说明编译成功。然后执行安装sudo make install这个命令会把模块复制到/lib/modules/$(uname -r)/kernel/drivers/net/wireless/realtek/rtw89/目录如果固件文件存在也会一并复制到/lib/firmware/rtw89/。最后刷新模块依赖并加载sudo depmod -a sudo modprobe rtw89_8852be如果你没有报错终端会安静地回到提示符。这时执行lsmod | grep rtw89能看到rtw89_8852be和rtw89_core等模块列表基本就成功了。4.3 通过 DKMS 注册让驱动在内核升级后依然存活直接make install有一个隐患你以后只要升级内核新内核目录下的驱动模块目录是全新的之前手动安装的.ko文件不会自动过去无线网卡又会消失。解决这个问题的方法就是 DKMS。lwfinger/rtw89 仓库里提供了 DKMS 集成脚本最简单的方式是sudo make dkms_install或者手动用 dkms 命令注册sudo dkms add . sudo dkms build rtw89/1.0 sudo dkms install rtw89/1.0这里的1.0是 dkms.conf 里定义的版本号以你仓库里的实际内容为准。注册完成后以后每次内核升级dkms 都会自动为新内核重新编译这个模块省去你重复make install的麻烦。我在实际体验中非常推荐这一步尤其是经常追新内核的用户。4.4 加载后的验证动作模块加载成功并不代表网卡一定可用还要确认网络层是否识别到了设备ip link iwconfig nmcli device status如果能看到wlan0或类似名称的无线接口且 NetworkManager 把它标记为 disconnected/available那说明驱动已经完全工作剩下就是通过图形界面或命令行连接 WiFi 了。nmcli device wifi list能列出附近的无线网络nmcli device wifi connect SSID password 密码可以直接命令行连上。5. 装完依然连不上按这条链路排查最容易出问题的地方5.1 Secure Boot 导致模块被签名验证拦截这是我在多台机器上遇到的最常见障碍。如果你的笔记本出厂开启了 Secure Boot而内核配置了模块签名验证那么modprobe rtw89_8852be时可能会出现modprobe: ERROR: could not insert rtw89_8852be: Operation not permitted或者在 dmesg 里看到Lockdown: modprobe: unsigned module loading is restricted; see man kernel_lockdown.7最直接的解决办法是进 BIOS 关闭 Secure Boot。不同品牌路径不一样联想笔记本一般是开机按 F2 进入 Setup在 Security 菜单里找到 Secure Boot 选项设为 Disabled 保存退出。关闭后再次modprobe一般就能正常加载。我这里不讨论 MOK 签名流程因为它比较复杂对新手不友好如果你的机器不允许关闭 Secure Boot再考虑用内核的mokutil做签名导入但那是另一个话题了。5.2 固件文件缺失dmesg 会明确告诉你模块加载成功但网卡不工作先看内核日志sudo dmesg | grep rtw89如果出现rtw89_8852be: Direct firmware load for rtw89/rtw8852b_fw.bin failed with error -2那就说明驱动模块找到了但固件缺失。解决办法是把rtw8852b_fw.bin文件放到/lib/firmware/rtw89/目录下。这个文件可以从 linux-firmware 仓库获取也可以直接从 lwfinger/rtw89 源码包的 firmware 目录里复制。放好之后执行sudo modprobe -r rtw89_8852be sudo modprobe rtw89_8852be再查 dmesg固件加载错误应该消失。这里要特别注意不同芯片对应的固件文件后缀不同8852BE 对应的是rtw8852b_fw.bin别拿成 8852A 的文件否则会一直报同样的错误。5.3 与内核自带驱动或旧驱动的冲突如果你之前用 HRex39 的旧仓库装过8852be模块后来又换 rtw89两个驱动会同时存在并争抢同一个设备。这种情况下建议把旧驱动列入黑名单。黑名单文件的路径是/etc/modprobe.d/blacklist.conf在末尾加一行blacklist 8852be然后重新生成模块依赖并重启网络服务sudo update-initramfs -u sudo modprobe -r 8852be sudo modprobe rtw89_8852be另一个冲突来源是内核自带的rtw88驱动。5.4 内核的 rtw88 还不支持 b852 设备所以你一般不会遇到但如果你后来把内核升级到较高版本rtw88_8852be可能已经存在。此时同样用黑名单把它禁掉确保 rtw89 优先加载即可。5.4 信号列表为空或者连不上rfkill 和网络管理器驱动正常、固件正常也能看到 wlan0但扫描不到任何 Wi-Fi 信号这时先检查是不是无线网卡被软件禁用了rfkill list如果某项显示Soft blocked: yes或Hard blocked: yes执行rfkill unblock all硬件开关和功能键比如 FnF2也可能把无线网卡关掉Ubuntu 里常常不显示明显的提示。另一个常见原因是 NetworkManager 没有接管这个新出现的无线设备。你可以通过nmcli device set wlan0 managed yes让 NetworkManager 管理它然后再用图形界面连接。把这几项检查完整绝大多数装完看不到信号的问题都能定位到具体原因。6. 一点经验总结这次踩坑之后我沉淀下来的通用离线装驱动流程回到文章开头那个死局这次成功解决之后我复盘出的一套通用流程以后再遇到其他离线网卡或者离线装内核模块的场景基本都能套用首先离线机器先想尽一切办法拿到临时网络无论是手机 USB 共享还是借一个免驱的 USB 无线网卡。只要有一次联网机会就立刻把编译链、内核头文件、dkms 以及目标驱动源码全部囤到本地。其次如果实在没有网络就用另一台同版本、同架构的机器把 deb 包下载好靠 U 盘拷贝进去。关键点在于内核头文件版本必须和uname -r严格一致这是最容易翻车的地方。依赖安装顺序上也形成了一个固定套路先头文件再工具链再辅助工具最后驱动源码编译。遇到依赖错误不要慌把dpkg -i *.deb多跑两遍直到输出清清爽爽。驱动装上后不要急着高兴把lsmod、dmesg、rfkill、nmcli四个命令挨个过一遍基本就能覆盖绝大多数问题。如果你正在折腾的也是 Realtek b852 网卡我的建议很明确优先走 rtw89 仓库加 DKMS 注册这条路不要浪费时间在来路不明的所谓一键安装脚本上。把上面每一步走完你的 Ubuntu 20.04 就会在离线状态下彻底认识这块网卡。后续即使系统升级内核驱动也能自动跟着重编译再不用重复今天这一步。
返回列表