news 2026/9/21 15:10:36

Ubuntu 20.04离线安装Realtek b852无线网卡驱动全攻略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ubuntu 20.04离线安装Realtek b852无线网卡驱动全攻略

1. 一块网卡引发的折腾:为什么离线装驱动比想象中麻烦

Realtek b852 这块无线网卡,最近两年在不少轻薄本和迷你主机上出现得挺频繁。它本身是 RTL8852BE 系列的衍生型号,支持 Wi-Fi 6 和蓝牙 5.2,纸面参数不差。但问题在于,Ubuntu 20.04 自带的 5.4 内核里,rtw89 驱动还处于非常早期的阶段,压根认不出这块卡。你装完系统打开网络设置,会发现"Wi-Fi"那一栏直接是灰的,连"未发现适配器"都懒得提示你。

更麻烦的是,很多人的使用场景是离线环境。比如公司内网的开发机、实验室里不接外网的工控主机、或者你手头只有一台能上网的机器但目标机器在另一个房间。这时候你没法直接apt install,也没法git clone,所有依赖都得靠 U 盘或者内网共享一点点搬过去。而 Linux 驱动编译这件事,最恶心的恰恰就是依赖链——你缺一个libelf-dev,编译就报错;你补上libelf-dev,它又告诉你pkg-config版本不对。一环扣一环,像拆炸弹。

这篇内容就是把我自己在 Ubuntu 20.04 上离线搞定 b852 驱动的完整过程拆开讲。包括怎么在联网机器上把依赖包一次性下全、怎么判断内核头文件版本是否匹配、编译报错时怎么顺着日志找到真正缺的东西、以及装完之后怎么验证驱动真的在工作而不是"看起来在工作"。适合两类人看:一类是手里有 b852 网卡但被离线环境卡住的运维或开发,另一类是想搞明白 Linux 驱动离线安装这套方法论的人——因为换成 aic8800 或者其他网卡,思路是一样的。

先说一个反直觉的结论:离线装驱动最难的不是编译本身,而是"你不知道自己缺什么"。联网环境下apt会自动帮你算依赖,离线环境下这个"算"的过程得你自己来。所以整篇的核心逻辑就是:先在联网机器上模拟出完整的依赖集合,再把这个集合搬到离线机器上复现。

2. 动手之前先把账算清楚:b852 的驱动来源与内核匹配逻辑

2.1 为什么不能用 Ubuntu 自带的驱动

Ubuntu 20.04 默认内核是 5.4.0-xx-generic。这个内核里的rtw89模块,只覆盖了 RTL8852AE 的早期版本,对 b852 这种后续修订版支持极差。你就算手动modprobe rtw89pci,大概率也是加载失败或者加载了但扫不到任何 AP。Realtek 官方在 GitHub 上维护了一个rtw89的独立仓库,里面的代码比内核主线新不少,b852 的支持就是在这个仓库里补进去的。

所以路线很明确:放弃内核自带模块,用 Realtek 官方仓库的源码自己编译。这就引出了第一个关键判断——你的内核版本和驱动源码的兼容性。

2.2 内核头文件版本必须和运行内核严格一致

编译内核模块,/lib/modules/$(uname -r)/build这个路径必须指向当前运行内核对应的头文件。很多人离线装的时候,从别的机器拷了一堆linux-headers-5.4.0-150过来,结果自己机器跑的是5.4.0-135,编译直接报"找不到 build 目录"或者更隐蔽的"结构体成员偏移不匹配"。

查当前内核版本:

uname -r

假设输出是5.4.0-135-generic,那你需要的头文件包就是linux-headers-5.4.0-135-genericlinux-headers-5.4.0-135(后者是通用部分)。这两个包在联网机器上用apt download拿下来,注意不要用apt install,因为 install 会顺带装一堆你不需要的东西,而且离线机器上也没法 install。

提示:如果你不确定离线机器当前跑的是哪个内核,可以在它上面执行uname -r记下来,再去联网机器下载对应版本。千万别想当然地认为"都是 20.04 所以内核一样",20.04 的小版本更新会升级内核,135 和 150 之间头文件是不通用的。

2.3 驱动源码的获取与版本选择

Realtek 的 rtw89 仓库地址是https://github.com/lwfinger/rtw89,这是社区维护的镜像,更新比较及时。下载的时候建议直接下 zip 包而不是git clone,因为离线机器上没有 git,你 clone 下来还得把.git目录删掉,反而麻烦。

选分支的时候注意:仓库的main分支对应较新内核,如果你坚持用 5.4 内核,可能需要往回找 commit。我实测下来,2023 年中的某个 commit 对 5.4 兼容性最好。具体做法是在联网机器上git log看一下提交记录,找那种 commit message 里提到"support kernel 5.4"或者时间点在 2023 年 6 月前后的。

把源码 zip 和头文件 deb 包一起放进 U 盘,离线机器的准备工作就算完成了一半。

3. 联网机器上的依赖打包:把 apt 的活手动干一遍

3.1 用 apt-rdepends 把依赖树挖到底

离线装驱动最怕的就是"装一个缺一个"。解决办法是在联网机器上先把依赖树完整展开。装个apt-rdepends

sudo apt install apt-rdepends

然后对编译驱动需要的基础包做递归依赖查询:

apt-rdepends build-essential libelf-dev dwarves flex bison | grep -v "^ " | sort -u

这条命令会列出所有直接和间接依赖的包名。注意grep -v "^ "是过滤掉缩进的依赖关系行,只保留包名。输出会有几十个,别嫌多,全下下来。

3.2 批量下载 deb 包的实操脚本

手动一个个apt download太蠢了,写个循环:

mkdir -p ~/offline-driver/pkgs cd ~/offline-driver/pkgs for pkg in $(apt-rdepends build-essential libelf-dev dwarves flex bison | grep -v "^ " | sort -u); do apt download $pkg 2>/dev/null done

这里2>/dev/null是为了忽略那些虚拟包(比如libc-dev这种由其他包提供的)的报错。下完之后ls看一下,应该有一两百个 deb 文件。

但这里有个坑:apt download只下当前架构的包。如果你的联网机器是 x86_64,离线机器也是 x86_64,那没问题。如果架构不同(比如联网机器是 ARM 的树莓派),得加--arch参数指定。

3.3 别忘了 linux-headers 和驱动源码

除了编译工具链,头文件包单独下:

apt download linux-headers-$(uname -r) linux-headers-$(uname -r | sed 's/-generic//')

注意第二条命令是下通用头文件包,比如linux-headers-5.4.0-135。这两个包名字很像,但内容不同,都要下。

驱动源码从 GitHub 下载 zip:

wget https://github.com/lwfinger/rtw89/archive/refs/heads/main.zip -O rtw89-main.zip

如果你确定了要用某个特定 commit,就在浏览器里找到那个 commit 页面,点"Download ZIP"。

3.4 打包与校验

把所有东西塞进一个目录,打个 tar 包:

cd ~/offline-driver tar czvf driver-offline.tar.gz pkgs/ rtw89-main.zip

打包完算个 md5,拷到 U 盘之后再算一次,确保传输过程没出错:

md5sum driver-offline.tar.gz

这个习惯看着多余,但我确实遇到过 U 盘静默损坏导致 deb 包解压失败的情况,查了半天才发现是文件本身坏了。

4. 离线机器上的安装:顺序错了就前功尽弃

4.1 先装依赖,再解压源码,最后编译

到了离线机器上,把 tar 包解开:

tar xzvf driver-offline.tar.gz cd offline-driver

装 deb 包的时候,不要用dpkg -i *.deb一把梭。因为 deb 之间有依赖顺序,dpkg 不解决依赖,顺序错了就报错。正确做法是:

sudo dpkg -i pkgs/*.deb

如果报依赖错误,再执行:

sudo dpkg -i pkgs/*.deb

对,就是再执行一遍。dpkg 第一次装的时候,有些包因为依赖没满足会配置失败,但包本身已经解压了。第二次执行时,之前解压的包就能满足依赖,配置就能成功。这个"跑两遍"的技巧在离线装 deb 时非常实用。

如果两遍之后还有报错,用:

sudo apt install -f --no-download

--no-download是关键,它让 apt 只用本地已有的 deb 包来修复依赖,不会尝试联网。

4.2 验证头文件路径是否正确

装完头文件后,检查这个路径:

ls -l /lib/modules/$(uname -r)/build

应该是一个指向/usr/src/linux-headers-$(uname -r)的软链接。如果这个链接不存在或者指向错误,手动建一个:

sudo ln -s /usr/src/linux-headers-$(uname -r) /lib/modules/$(uname -r)/build

这一步不做,后面make会直接报"找不到内核源码目录"。

4.3 编译 rtw89 驱动

解压驱动源码:

unzip rtw89-main.zip cd rtw89-main

先看一眼 Makefile 里的CONFIG_PLATFORM相关配置,确认没有硬编码的内核路径。然后:

make -j$(nproc)

-j$(nproc)是用满所有 CPU 核心并行编译,能快不少。编译过程大概一两分钟,如果报错,往下看第 5 章。

编译成功后:

sudo make install

这个命令会把编译好的.ko文件拷到/lib/modules/$(uname -r)/kernel/drivers/net/wireless/下面,并执行depmod

4.4 加载模块并验证

sudo modprobe rtw89pci

然后检查:

lsmod | grep rtw89

应该能看到rtw89pcirtw89_corertw89_8852be这几个模块。如果只有rtw89pci没有rtw89_8852be,说明固件没加载成功,检查/lib/firmware/rtw89/目录下有没有rtw8852b_fw.bin这个文件。驱动源码的firmware/目录里应该带了,手动拷过去:

sudo cp firmware/rtw8852b_fw.bin /lib/firmware/rtw89/

最后看网络接口:

ip link show

应该多出一个wlan0或者wlp2s0之类的接口。用nmcli device wifi list扫一下 AP,能扫到就说明驱动真的在工作了。

5. 编译报错排查:顺着日志找到真正缺的东西

5.1 "No such file or directory: linux/module.h"

这个报错 90% 是头文件路径不对。先确认/lib/modules/$(uname -r)/build存在且指向正确。如果路径没问题,那就是linux-headers包没装全,回去检查linux-headers-$(uname -r)linux-headers-$(uname -r | sed 's/-generic//')是不是都装了。

5.2 "ERROR: modpost: Module.symvers is missing"

这个报错说明内核头文件包里缺少Module.symvers文件。Ubuntu 的linux-headers包有时候确实不带这个文件,需要额外装linux-modules-$(uname -r)或者从/boot目录下找。如果实在找不到,可以在 Makefile 里加一行忽略符号版本检查:

KBUILD_MODPOST_WARN = 1

但这只是绕过,不是解决。更好的办法是从联网机器上把/usr/src/linux-headers-$(uname -r)/Module.symvers拷过来。

5.3 "unknown type name 'bool'" 之类的语法错误

这种报错通常是因为编译器版本和内核源码不匹配。Ubuntu 20.04 默认 gcc 是 9.x,如果驱动源码里用了 gcc 10+ 的语法特性,就会报这种错。解决办法是装gcc-9g++-9,然后在 Makefile 里指定:

CC = gcc-9

或者编译时传参:

make CC=gcc-9 -j$(nproc)

5.4 编译通过但 modprobe 报 "Invalid argument"

这个最隐蔽。编译没问题,模块也能insmod,但modprobe就是报错。原因通常是模块签名问题。Ubuntu 20.04 默认开启了 Secure Boot 的话,未签名的内核模块会被拒绝加载。检查:

mokutil --sb-state

如果输出SecureBoot enabled,你有两个选择:进 BIOS 关掉 Secure Boot,或者给模块签名。离线环境下签名很麻烦(需要生成密钥、导入 MOK),所以关 Secure Boot 是最省事的

5.5 驱动加载了但扫不到 AP

先看dmesg | grep rtw89的输出。如果看到firmware failed to load,就是固件文件没放对位置。如果看到rfkill相关字样,检查:

rfkill list

有时候无线被软阻塞了,sudo rfkill unblock wifi解一下就行。

6. 装完之后别急着走:稳定性验证与长期维护

6.1 跑个持续 ping 看会不会掉线

驱动刚装上能连不代表稳定。我习惯跑一个长 ping 测试:

ping -i 0.2 -c 3000 192.168.1.1 | tail -5

-i 0.2是 0.2 秒发一个包,3000 个包大概跑 10 分钟。看最后统计的丢包率,如果超过 1%,说明驱动或者固件有问题。b852 在早期驱动版本上确实有断流问题,换更新的 commit 能缓解。

6.2 内核升级后驱动会失效

这是离线装驱动最大的长期痛点。Ubuntu 20.04 的安全更新会升级内核,比如从 5.4.0-135 升到 5.4.0-150。升级后重启,新内核没有对应的头文件,也没有编译好的 rtw89 模块,Wi-Fi 又没了。

应对办法有两个:一是锁定内核版本,禁止自动升级:

sudo apt-mark hold linux-image-$(uname -r) linux-headers-$(uname -r)

二是每次内核升级后重新走一遍离线编译流程。前者省事但牺牲安全更新,后者麻烦但更稳妥。我个人的选择是锁定内核,因为这台机器在内网,安全更新的优先级没那么高。

6.3 把驱动加入 initramfs 避免开机加载失败

有时候模块编译好了,但开机时加载顺序不对,导致 Wi-Fi 起不来。把模块写进/etc/modules

echo "rtw89pci" | sudo tee -a /etc/modules

然后更新 initramfs:

sudo update-initramfs -u

这样开机时会尽早加载驱动,减少"开机后要等半分钟 Wi-Fi 才出来"的情况。

6.4 备份编译好的模块

编译一次不容易,把.ko文件备份出来:

mkdir -p ~/rtw89-backup cp /lib/modules/$(uname -r)/kernel/drivers/net/wireless/rtw89/*.ko ~/rtw89-backup/

下次如果只是模块被误删,直接拷回去depmod -a就行,不用重新编译。

7. 几个容易忽略的细节和我的实际体会

第一个细节是固件文件的权限/lib/firmware/rtw89/下的.bin文件权限应该是 644,如果从 U 盘拷过来变成 600,驱动加载时会报权限错误。sudo chmod 644 /lib/firmware/rtw89/*.bin一下就好。

第二个细节是蓝牙。b852 是 Wi-Fi 蓝牙二合一,Wi-Fi 驱动装好了,蓝牙可能还是不能用。蓝牙走的是 USB 接口,需要btusb模块和对应的固件。检查dmesg | grep -i blue,如果看到firmware not found,需要把rtl8852bu_fw.binrtl8852bu_config.bin放到/lib/firmware/rtl_bt/下面。这两个文件在驱动源码的firmware/目录里也有。

第三个细节是不要同时装多个版本的 rtw89。如果你之前尝试过从别的来源装驱动,先把旧的卸干净:

sudo modprobe -r rtw89pci rtw89_core rtw89_8852be sudo rm -rf /lib/modules/$(uname -r)/kernel/drivers/net/wireless/rtw89 sudo depmod -a

然后再装新的,否则模块版本冲突会导致各种诡异问题。

我自己在这块网卡上前前后后折腾了大概三个晚上。最开始想走捷径,直接从另一台同型号机器的/lib/modules目录把整个 wireless 文件夹拷过来,结果因为内核小版本差了两个数,模块加载直接 kernel panic。后来老老实实按"联网机下依赖、离线机编译"的流程走,一次就过了。所以我的建议是:别偷懒,依赖该下全就下全,头文件版本该对齐就对齐。离线环境没有 apt 帮你兜底,每一步都得自己确认。

另外,如果你手头有多个离线机器要装,可以把编译好的.ko文件和固件一起打包,只要目标机器内核版本完全一致,直接拷过去depmod -a就能用,不用每台都编译。这个办法在批量部署的时候能省不少时间。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/21 14:48:38

xmake单元测试实践:提升C/C++开发效率

1. 为什么选择xmake进行单元测试在C/C项目开发中,单元测试一直是个令人头疼的问题。传统做法要么依赖第三方框架(如Google Test),要么需要手动编写大量胶水代码。而xmake作为国产构建工具的后起之秀,其内置的测试框架让…

作者头像 李华
网站建设 2026/9/21 14:38:06

Intel HEX转BIN原理与生产级C#实现

1. 项目概述:为什么一个“hex转bin”工具值得花时间重做一遍在嵌入式开发、固件升级、硬件调试这些真实场景里,我几乎每天都要和.hex文件打交道——Keil编译完的输出、STM32CubeProgrammer导出的烧录镜像、甚至Proteus仿真时加载的程序映像,十…

作者头像 李华