
1. 为什么这套老组合至今还有人折腾Intel 5300 这张网卡在二手市场上大概几十块钱就能淘到但它在无线感知圈子里算是个神卡级别的存在。原因很直接它的固件支持把每根天线的信道状态信息CSIChannel State Information以原始数据的形式吐出来配合开源工具就能拿到子载波级别的幅度和相位。做室内定位、手势识别、呼吸检测这类研究没有比它更便宜且资料更全的硬件了。问题是这套东西的黄金搭档是 Ubuntu 14.04。这个系统发布于 2014 年内核是 3.13 系列很多现在的常规操作在它上面会翻车。更麻烦的是CSI Tools 这个工具链本身已经很久没更新了官方文档写得比较粗很多步骤默认你已经踩过一遍坑。我前后在三台不同配置的机器上装过这套环境每次都会遇到不一样的问题有的是内核版本对不上有的是驱动编译报错还有一次是网卡被系统自带的驱动抢先接管了怎么都出不来 CSI 数据。这篇内容就是把这几次安装过程中真正卡住人的地方整理出来。我会从硬件确认、系统准备、驱动替换、工具编译到最终验证把每一步的意图和容易出错的细节都讲清楚。如果你手头正好有一块 5300 和一台装着 Ubuntu 14.04 的旧机器照着走应该能省下不少查资料的时间。即使你用的是其他版本的 Ubuntu里面的排查思路也有参考价值。2. 动手之前先把硬件和系统底细摸清楚2.1 确认你手里的是不是真正的 5300Intel 5300 有几个容易混淆的型号。你需要的是Intel Ultimate N WiFi Link 5300通常是半高 Mini PCIe 接口上面印着 5300 字样有三根天线接口。有些商家会把 5100 或者 5350 当成 5300 卖这两款虽然外观接近但 5100 只有两根天线5350 的固件行为也不一样拿不到完整的三天线 CSI。插上机器之后先用命令确认一下lspci | grep -i network正常应该看到类似这样的输出03:00.0 Network controller: Intel Corporation Ultimate N WiFi Link 5300如果显示的是 5100 或者 5350那后面的步骤虽然大体相同但 CSI 的维度会对不上采集出来的数据只有两根天线的分量。这一点在写论文或者做实验记录的时候特别重要别等到数据分析阶段才发现少了一路。2.2 Ubuntu 14.04 的版本选择有讲究Ubuntu 14.04 有桌面版和服务器版还有 14.04.1 到 14.04.6 这几个小版本。我建议用14.04.5 的桌面版原因是这个版本的内核是 3.13.0-XX 系列和 CSI Tools 官方推荐的 3.13 内核匹配度最高。如果你用的是 14.04.1内核可能更老有些编译依赖会对不上用 14.04.6 的话内核又偏新驱动源码可能需要打补丁。装系统的时候有一个细节不要勾选安装第三方软件和下载更新。这两个选项会在安装过程中把内核升到更新的版本等你装完系统一看内核已经不是 3.13 了。我第二次装的时候就吃了这个亏装完发现内核是 3.19驱动编译直接报错最后只能重装。装完之后先确认内核版本uname -r理想输出是3.13.0-XX-generic。如果不对要么重装要么手动降级内核后者更麻烦不如重来。2.3 关闭系统自带的网卡驱动接管这一步是很多人第一次装的时候最容易忽略的。Ubuntu 启动之后会自动加载iwlwifi驱动这个驱动虽然能让网卡正常上网但它不会把 CSI 数据暴露出来。你需要把它换掉换成 CSI Tools 提供的修改版驱动。但在换之前得先确认当前是哪个驱动在管这块卡lsmod | grep iwl如果看到iwlwifi和iwldvm都在列表里说明系统驱动已经接管了。这时候直接去编译新驱动会冲突必须先卸载sudo modprobe -r iwldvm sudo modprobe -r iwlwifi卸载之后再确认一次确保列表里没有 iwl 相关的模块。如果卸载报错说模块正在使用可能是网络管理器还在占用先把网络断开或者停掉网络管理器sudo service network-manager stop注意停掉网络管理器之后你就没法上网了所以这一步之前先把需要的包都下载好或者准备好离线安装包。3. 驱动替换整个流程里最容易翻车的一环3.1 获取正确的驱动源码CSI Tools 的驱动源码来自一个修改过的iwlwifi版本核心改动是增加了一个调试接口让用户态程序可以通过 netlink 拿到 CSI 数据。这个源码包通常随 CSI Tools 一起发布文件名类似iwlwifi-5300-3.13.0.tgz或者带日期后缀的版本。拿到源码之后解压到一个工作目录比如~/csi/mkdir -p ~/csi cd ~/csi tar -xzf iwlwifi-5300-*.tgz解压出来通常是一个iwlwifi-5300-3.13.0这样的目录。进去之后先看一眼Makefile确认里面的内核路径指向的是你当前系统的/lib/modules/$(uname -r)/build。有些版本的 Makefile 写死了路径需要手动改。3.2 编译前的依赖检查编译内核模块需要内核头文件和编译工具链。Ubuntu 14.04 默认可能没装全先补上sudo apt-get update sudo apt-get install build-essential linux-headers-$(uname -r) git这里有个坑如果你的系统之前更新过linux-headers-$(uname -r)可能找不到对应的包因为软件源里只有最新内核的头文件。解决办法是去/usr/src/下面看看有没有现成的头文件目录ls /usr/src/如果有linux-headers-3.13.0-XX-generic这样的目录说明头文件已经在了不需要再装。如果没有那就得从 Ubuntu 的旧版本归档里手动下载对应的 deb 包安装。3.3 编译和安装驱动依赖齐了之后就可以编译了cd ~/csi/iwlwifi-5300-3.13.0 make clean make编译过程大概需要一两分钟。如果报错最常见的原因是内核版本不匹配错误信息里会出现implicit declaration of function或者unknown symbol之类的字样。这时候要检查你的内核版本和驱动源码支持的版本是否一致。编译成功之后会生成iwlwifi.ko、iwldvm.ko、iwlwifi-5300.ko这几个模块文件。安装的方式有两种一种是直接insmod另一种是make install然后modprobe。我推荐后者因为make install会把模块放到/lib/modules/$(uname -r)/kernel/drivers/net/wireless/iwlwifi/下面并且更新模块依赖关系重启之后也能自动加载。sudo make install sudo depmod -a3.4 加载新驱动并验证安装完成之后加载新驱动sudo modprobe iwlwifi然后确认加载的是新编译的版本lsmod | grep iwl dmesg | tail -30dmesg里应该能看到类似iwlwifi 0000:03:00.0: loaded firmware version的日志说明驱动已经接管了网卡。如果看到的是iwlwifi加载失败或者固件版本不对那可能是固件文件的问题。Intel 5300 需要的固件文件是iwlwifi-5000-5.ucode放在/lib/firmware/下面。如果系统里没有需要从 Intel 的官方固件仓库或者 CSI Tools 的包里找一份放进去。固件版本不对的话驱动会加载失败dmesg里会明确提示firmware file not found或者firmware version mismatch。4. CSI Tools 的编译与配置细节4.1 工具链的组成和各自作用CSI Tools 不是一个单一程序而是一组工具的集合。核心的几个组件包括工具名称作用log_to_file把 CSI 数据从内核接口读到用户态并写入文件read_bf_file解析二进制 CSI 文件转成可读格式parse_csi从原始数据中提取幅度和相位信息netlink相关工具配置网卡参数比如信道、带宽、天线模式编译这些工具需要先装好依赖库主要是libnl和libpcapsudo apt-get install libnl-3-dev libnl-genl-3-dev libpcap-dev4.2 编译过程中的常见报错进入 CSI Tools 的源码目录通常是~/csi/csitool/或者类似的名字然后执行make这里最常见的报错是找不到libnl的头文件错误信息类似fatal error: netlink/netlink.h: No such file or directory。这是因为libnl的头文件路径没有被正确引用。解决办法是在 Makefile 里加上 include 路径CFLAGS -I/usr/include/libnl3另一个常见问题是log_to_file编译时提示undefined reference to nl_connect之类的链接错误这是因为链接顺序不对。把-lnl-3 -lnl-genl-3放到编译命令的最后面通常能解决。4.3 配置网卡进入监听模式工具编译好之后需要把网卡配置成能采集 CSI 的状态。这一步涉及几个参数信道CSI 数据是在特定信道上采集的通常选一个干扰少的信道比如 64 或者 1005GHz 频段。带宽5300 支持 20MHz 和 40MHz40MHz 能拿到更多子载波但数据量也翻倍。天线模式三根天线可以全开也可以只开其中两根取决于你的实验需求。配置命令大致是这样的sudo ifconfig wlan0 down sudo iwconfig wlan0 mode monitor sudo iwconfig wlan0 channel 64 sudo ifconfig wlan0 up注意wlan0是你的网卡接口名不同机器可能不一样用ifconfig -a确认一下。另外进入监听模式之后网卡就不能正常上网了这是正常的。4.4 采集 CSI 数据并验证配置好之后就可以开始采集了。先启动一个发送端持续发送数据包然后在接收端运行sudo ./log_to_file data.dat这个命令会把 CSI 数据写入data.dat文件。采集几十秒之后按 CtrlC 停止然后用解析工具看看数据是否正常./read_bf_file data.dat | head -50如果能看到类似CSI data: 30 subcarriers, 3 antennas这样的输出说明采集成功了。如果输出是空的或者报错那就要回头检查驱动是否真的加载了、网卡是否在监听模式、发送端是否在正常工作。5. 那些文档里不会写的踩坑记录5.1 网卡被系统驱动抢回去的问题这个坑我遇到过一次现象是驱动明明编译安装好了dmesg也显示加载成功但过一会儿 CSI 数据就断了。查了半天发现是系统在某个时刻自动加载了iwlwifi的原始版本把修改版覆盖掉了。原因是 Ubuntu 的udev规则会在检测到网卡时自动加载驱动而它加载的是/lib/modules/下面系统自带的那个版本。解决办法是把修改版的驱动优先级提高或者直接把系统自带的驱动模块重命名让它找不到。具体操作是找到系统自带的iwlwifi.kofind /lib/modules/$(uname -r) -name iwlwifi.ko然后把它改名备份sudo mv iwlwifi.ko iwlwifi.ko.bak sudo depmod -a这样系统再想加载的时候就只能找到你编译的那个版本了。5.2 固件版本不匹配导致的诡异现象有一次驱动加载成功网卡也能进入监听模式但采集到的 CSI 数据全是零。排查了很久才发现是固件版本的问题。Intel 5300 有多个固件版本不同版本对 CSI 的支持程度不一样。有些老固件虽然能让网卡工作但不会把 CSI 数据传给驱动。确认固件版本的方法是看dmesg里的输出dmesg | grep -i firmware正常应该看到iwlwifi 0000:03:00.0: loaded firmware version 5.4.1.1这样的信息。如果版本号低于 5建议换一个更新的固件文件。固件文件可以从 Intel 的 Linux 固件仓库找到文件名是iwlwifi-5000-5.ucode。5.3 编译内核模块时的内存不足这个问题比较少见但在虚拟机上装的时候遇到过。编译iwlwifi驱动需要大概 1GB 左右的内存如果你的虚拟机只分配了 512MB编译到一半会报Killed或者out of memory。解决办法是给虚拟机加内存或者加一个 swap 分区sudo fallocate -l 2G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile5.4 采集频率和丢包的关系CSI 数据的采集频率受限于发送端的发包速率。如果你用ping做发送端默认一秒一个包采集到的 CSI 数据会非常稀疏。做呼吸检测这类需要连续波形的应用发包速率至少要 50Hz 以上。提高发包速率的方法是用iperf或者专门的发包工具把发送间隔调到 10ms 甚至更短。但要注意发包太快会导致网卡缓冲区溢出出现丢包。实测下来100Hz 左右的速率在 5300 上比较稳定再高就容易丢。6. 完整命令脚本与一键复现思路6.1 从零开始的完整命令序列把前面的步骤串起来整个流程大概是这样的# 1. 确认硬件 lspci | grep -i network # 2. 确认内核版本 uname -r # 3. 安装依赖 sudo apt-get update sudo apt-get install build-essential linux-headers-$(uname -r) git libnl-3-dev libnl-genl-3-dev libpcap-dev # 4. 卸载系统驱动 sudo service network-manager stop sudo modprobe -r iwldvm sudo modprobe -r iwlwifi # 5. 编译并安装修改版驱动 cd ~/csi/iwlwifi-5300-3.13.0 make clean make sudo make install sudo depmod -a # 6. 备份系统自带驱动防止被抢回去 sudo find /lib/modules/$(uname -r) -name iwlwifi.ko -exec mv {} {}.bak \; sudo depmod -a # 7. 加载新驱动 sudo modprobe iwlwifi dmesg | tail -20 # 8. 编译 CSI Tools cd ~/csi/csitool make # 9. 配置网卡 sudo ifconfig wlan0 down sudo iwconfig wlan0 mode monitor sudo iwconfig wlan0 channel 64 sudo ifconfig wlan0 up # 10. 采集数据 sudo ./log_to_file data.dat6.2 脚本化时需要注意的交互点如果你想把这个流程写成一个自动化的 shell 脚本有几个地方需要处理modprobe -r可能会因为模块正在使用而失败脚本里要加|| true或者先停掉网络管理器。make的返回值要检查编译失败就别往下走了。网卡接口名不一定是wlan0脚本里最好用iwconfig或者ip link动态获取。一个简单的检查逻辑WLAN$(iwconfig 2/dev/null | grep -o ^[a-zA-Z0-9]* | head -1) if [ -z $WLAN ]; then echo 没有找到无线网卡接口 exit 1 fi6.3 验证安装是否成功的三个标志装完之后怎么确认一切正常看这三个地方lsmod | grep iwlwifi显示的模块路径是/lib/modules/$(uname -r)/kernel/drivers/net/wireless/iwlwifi/iwlwifi.ko而不是updates/或者extra/下面的。dmesg里有loaded firmware version且版本号大于等于 5。log_to_file运行几秒后生成的文件大小不为零且read_bf_file能解析出子载波数量。这三个都满足基本就可以开始做实验了。如果有一个不对按前面的排查思路往回找。7. 关于这套老环境的几点个人体会这套环境我用了大概两年最大的感受是版本匹配比什么都重要。内核版本、驱动版本、固件版本、工具版本这四个东西只要有一个对不上就可能出现各种奇怪的现象。所以每次重装系统之后第一件事就是把版本号全部确认一遍别急着往下走。另一个体会是别在物理机上直接折腾。我建议先用虚拟机装一遍把流程跑通确认所有命令都能正常执行之后再在物理机上操作。虚拟机的好处是快照方便搞砸了直接回滚不用重装系统。但要注意虚拟机需要把 USB 或者 PCIe 网卡直通进去否则虚拟机里看不到 5300。最后说一个实际使用中的小技巧采集 CSI 数据的时候把发送端和接收端的天线都竖起来保持同一极化方向。5300 的三根天线如果方向不一致采集到的相位信息会有额外的偏差后期处理起来很麻烦。这个细节在文档里不会写但做实验的时候影响挺大。如果你现在还在用这套组合做研究或者正准备入坑希望这些踩坑记录能帮你少走点弯路。这套东西虽然老但胜在便宜且数据质量够用对于预算有限的学生或者个人研究者来说仍然是个不错的选择。