Linux CSI Tool Monitor模式搭建与数据采集指南

发布时间:2026/10/6 3:36:10
Linux CSI Tool Monitor模式搭建与数据采集指南 1. 项目背景与核心思路玩算法的人常听到CSI tool但大多数教程都停在“下载编译”这一步。真正在Linux下把CSI tool跑起来并且用Monitor模式持续稳定抓数据才算是入了Wi-Fi感知的门。这篇帖子我准备按自己的踩坑顺序把Linux 802.11n CSI tool的Monitor模式从环境搭建到数据格式完整梳理一遍让后来的人少走弯路。CSI tool全称是Linux 802.11n CSI Tool最早由华盛顿大学的Daniel Halperin团队开源核心功能是从特定无线网卡的固件里直接导出信道状态信息Channel State Information。这套工具的价值在于CSI能反映出多径传播、物体散射、人体遮挡等物理层信息比RSSI详细得多室内定位、人体活动识别、无源感知这些方向都会用到它。很多第一次接触的人以为装上无线网卡打开Wireshark抓包就算完事了其实完全不是这样。CSI tool要求的是另类工作链路打内核补丁、替换驱动模块、设置Monitor模式然后从驱动层把CSI数据寄存器里的东西读出来。我觉得有必要先说清楚一件事这套方案里的Monitor模式不是可有可无的选项而是前置条件。普通managed模式下网卡要先和AP完成关联内核协议栈会参与管理帧和处理过滤CSI tool的补丁代码会被重重拦截。只有切到Monitor模式网卡才不关心是否连接AP才能自由指定监听信道并把接收到的物理层信息暴露给用户态工具。所以这篇博文的核心就是怎么用一套修改过的无线网卡驱动在Linux下顺利进入Monitor模式然后通过CSI tool拿到稳定的CSI数据流。适合正在搞Wi-Fi感知、需要自己采集物理层数据或者想复现CSI相关论文的工程师和研究生参考。1.1 CSI tool 到底能抓出什么数据先做个直观对比RSSI只是一个信号强度标量描述的是整体能量的高低而CSI是OFDM子载波级别的信道估计结果。802.11n在20MHz带宽下可以划分出多个子载波CSI tool能提取其中30个子载波的复数值也就是每个子载波都有一组包含幅度和相位的复数幅度对应衰减相位对应传播延迟和相位偏移。这些信息放在一起就能体现无线信号在空间中的具体传播状态。实际使用中最直观的例子是人体走动。你坐在固定位置对面放一个发射端当有人从中间走过时不同子载波上的CSI幅度变化完全不同有些子载波衰减明显有些反而增强这种频率选择性的变化就是多径效应的体现。再往后做机器学习分类时这些30维子载波数据就是最原始的特征。如果直接用RSSI整个人经过时只是整体信号上下抖动信息量差太多。需要说明的是CSI tool的“30个子载波”是一个硬件级别的限制。Intel 5300无线网卡在802.11n模式下内部基带处理会固定上报30组CSI参数这是固件决定的不是软件配置能改的。后面有人用Atheros网卡实现了更多子载波的提取但复杂度直接上升一个量级。所以对绝大多数入门项目Intel 5300 CSI tool是成本最低的路线。1.2 为什么Monitor模式是刚需有些朋友会问我就在客厅放一个路由器笔记本电脑连上Wi-Fi然后运行CSI tool能拿到CSI吗答案是大概率拿不到或者数据不持续。原因是managed模式下网卡的工作被内核网络协议栈接管驱动程序收到的帧都是已经经过硬件过滤和上层处理的CSI相关状态信息不一定会被保留而且网卡会跟随AP的信道和带宽变化你没法指定监听某个信道。Monitor模式则把网卡变成一个纯被动监听器。它不再发送连接请求也不关心是否有关联关系只是把所有从天线接收到的无线帧连同物理层信息一起交给驱动和上层工具。CSI tool正是利用这一点在Monitor模式下可以被动捕获同一信道上任意设备发送的帧并且每次接收都能拿到帧对应的CSI。在主动感知场景里即使发射端只是一个普通的AP或者开发板只要它在持续发包监听端就能持续输出CSI数据。这里还要避免一个误区Monitor模式不等于可以切换到任意Wi-Fi频段。802.11n CSI tool支持的还是传统网卡能力2.4GHz和5GHz都可以工作但不同信道的频率差异会影响CSI的相位变化后续做算法时要统一信道否则采集到的数据没法横向比较。这也是我在4.1里建议固定信道的原因。2. 环境准备与工具链搭建CSI tool不是那种“装个App就能用”的软件。它依赖特定网卡、特定Linux内核版本、补丁后的驱动模块三者匹配才跑得起来。我自己第一次接触时随便找了台Ubuntu 20.04笔记本插上一块Wi-Fi 6网卡折腾了一晚上才发现根本不支持。后来老老实实搭了一台旧硬件环境才顺利跑通。2.1 硬件选型Intel 5300为什么是不二之选目前CSI tool支持最成熟、资料最多、踩坑案例也最少的是Intel 5300系列无线网卡。这是一款2008年左右发布的802.11a/b/g/n无线网卡常见的是半高Mini PCIe接口三个天线接口无线芯片组为Intel 5300 AGN。因为当年的笔记本差不多都配这块卡二手市场很便宜外接转接板也能插到台式机主板上。网上偶尔能看到有人用Intel 5100或Atheros AR9380做CSI提取但Intel 5100只有两根天线CSI数据里的空间流和天线信息会少一些Atheros方案需要额外魔改固件而且社区工具链分散很容易掉进编译地狱。所以我个人建议第一套环境老老实实选择Intel 5300理由很简单CSI tool官网文档就是基于这块卡写的patch、示例代码、已知问题都是配套的。另外要注意天线。Intel 5300最高支持3x3 MIMO三根天线分别对应三个接收链路。如果你只有一根天线也能采集但空间信息就只剩一条流了很多关于多天线和到达角的研究就做不了。建议尽量配齐三根天线接口是U.FL/IPEX需要接转接线引到外壳上否则信号会很差。2.2 操作系统版本与内核补丁匹配操作系统方面Ubuntu 12.04到14.04这一段最省心因为CSI tool的补丁包里有针对2.6.32到3.13左右内核的补丁文件。如果你机器上跑的是Ubuntu 18.04以后的内核驱动框架变化很大需要自己手工移植补丁这对内核模块编译不熟的人来说几乎是灾难。我当时的操作是找一块闲置的旧笔记本安装Ubuntu 16.04 64位系统内核版本4.4还是4.15记不太清了后来干脆降到4.2内核。这里给大家一个更稳的做法直接用Ubuntu 14.04.6 LTS的iso安装安装后内核版本是3.13.0CSI tool官方patch里有对应的3.13 patch省去自己改Makefile的烦恼。如果你打算用虚拟机需要注意一点CSI tool需要直接操作PCIe无线网卡虚拟机默认的USB设备直通和PCI直通支持不稳定最好用物理机。别以为VirtualBox里插个USB无线网卡就能模拟我试过驱动都加载不了。真的要用虚拟机也得用支持PCI直通的VMware Workstation并且宿主机的CPU/IOMMU设置得当否则采集频繁掉数据。2.3 安装依赖与打补丁的顺序整个环境搭建的前提是有一个能联网的Linux系统。基础的编译工具链必须先装好sudo apt-get update sudo apt-get install -y gcc make patch git bc libncurses-dev接下来需要准备Linux内核源码。建议直接下载与当前内核版本一模一样的源码包。比如系统内核是3.13.0-24那就下载linux-3.13.tar.xz不要用linux-3.13.8之类的近似版本。内核源码的完整路径一般放在/usr/src/linux下也可以用软链接指到实际目录。CSI tool的源码从官方GitHub仓库拉取git clone https://github.com/dhalperi/linux-80211n-csitool.git仓库里的patches/目录保存着各内核版本对应的补丁。这个补丁的实质是修改mac80211和iwlwifi驱动代码让它把CSI数据从固件中读出来并写入到netlink或debugfs。打补丁的步骤大致这样cd /usr/src/linux patch -p1 /path/to/linux-80211n-csitool/patches/3.13/csitool-80211n-3.13.patch打补丁成功后如果之前配置过内核最好执行一次make oldconfig让新代码声明的选项生效然后开始编译make -j$(nproc) sudo make modules_install这一步比较耗时取决于机器性能可能十几分钟到一小时。编译完不要急着重启先用ls /lib/modules/$(uname -r)/kernel/drivers/net/wireless/iwlwifi/确认新的iwlwifi.ko已经生成再进行模块替换。否则你重启后可能又加载了系统自带的老驱动。3. 实操编译CSI tool并进入Monitor模式很多人卡住的地方不在编译而在编译后怎么把系统换成新驱动以及如何让网卡稳定停在Monitor模式。我把自己验证过的步骤全部列出来顺序很重要乱的话很容易遇到“mode无法设置”或“模块版本magic mismatch”。3.1 编译用户态工具的全流程内核补丁只是底层支持真正从网卡读取CSI还要依赖CSI tool的用户态程序。这部分编译简单很多cd /path/to/linux-80211n-csitool make编译完成后会生成csi_tool可执行文件。此外仓库里还有一个用于记录数据的小工具log_to_file它实际上是个Python脚本sudo python log_to_file.py /tmp/csi.dat用户态工具需要root权限因为它要访问debugfs和netlink接口。如果/sys/kernel/debug为空先挂载debugfssudo mount -t debugfs none /sys/kernel/debug挂载后可以用ls /sys/kernel/debug/看到iwlwifi或ieee80211下面的CSI相关节点。如果没有这些节点说明补丁没生效回到编译步骤重新检查补丁路径。3.2 替换iwlwifi驱动模块的正确姿势模块替换是整个流程里最容易出错的一步。由于内核可能已经加载了自带的iwlwifi模块需要先卸载再加载新模块。顺序如下sudo rmmod iwlwifi sudo modprobe mac80211 sudo insmod /path/to/your/new/iwlwifi.ko注意insmod和modprobe的区别这里用insmod指定绝对路径确保加载的是我们刚编译的模块。加载后检查dmesg | tail -n 30正常的输出会出现iwlwifi相关日志并且最下方可能会有CSI功能注册成功的提示。如果出现version magic错误说明你用的模块和当前运行内核不匹配老老实实换回一致的内核源码重新编译。还有一个细节部分发行版开启了内核模块签名验证直接insmod会报Required key not available。解决办法是在编译内核时关闭CONFIG_MODULE_SIG或者在启动参数里加入module.sig_enforce0。这块建议一开始就确认省得后面折磨人。3.3 用iw和iwconfig配置Monitor模式模块加载成功后先把无线网卡从NetworkManager手里抢过来否则它会自动把网卡拨回managed模式sudo systemctl stop NetworkManager sudo ip link set wlan0 down sudo iw dev wlan0 set type monitor sudo ip link set wlan0 up如果这里提示command failed: Operation not supported多半是驱动补丁没有真正生效或者网卡本身不支持monitor模式。Intel 5300本身是支持的所以优先怀疑驱动版本不对。老一点的工具也可以直接这样切换sudo iwconfig wlan0 mode Monitor但我建议别混用iw和iwconfig容易产生状态不一致。无论用哪种切完之后都要验证一下sudo iwconfig wlan0输出里出现Mode:Monitor就说明成功了。再看一下iw wlan0 info里面的type monitor也应该是正确的。此时还可以用iw dev wlan0 set channel 6 HT20固定信道保证后续采集不会跳频。我还遇到过一个很隐蔽的问题网卡切到Monitor模式后用ifconfig wlan0可能看不到IP地址这是正常的别慌。Monitor模式是物理层监听不需要IP协议栈参与甚至可以把IP设为0.0.0.0。只要iwconfig能显示Mode:Monitor就可以继续下一步。4. 数据采集与格式解析要点环境全部跑通后采集数据才是真正进入正题。但我发现很多人第一次采集时都会遇到同一个尴尬命令行有输出了但打开二进制文件一头雾水不知道里面的CSI怎么解出来。所以我这一节既讲采集命令也把二进制格式讲透。4.1 从Monitor模式持续采集CSI数据发射端和接收端要区分开。接收端就是我们插了Intel 5300的Linux机器运行CSI tool发射端可以是任何能发送无线流量的设备比如手机、路由器或者另一台电脑。为了稳定触发CSI记录我一般用iperf打流在发射端运行iperf -s -u -i 1接收端这边先固定信道再开启监听sudo iw dev wlan0 set channel 36 HT20 sudo python log_to_file.py /tmp/csi_room_walk.dat然后让发射端持续发送UDP包接收端就能在Monitor模式下捕获数据帧并保存CSI。如果没有iperf也可以在接收端持续ping发射端但不保证每个包都能触发驱动层的CSI回调所以最好用UDP打流。采集时长和文件大小的关系取决于发包速率。如果发射端每秒发1000个包接收端日志里每秒差不多有1000条CSI记录每条记录加上头信息大概100字节左右一分钟就是6MB。这个速度完全能接受但要注意不要写到网络挂载盘上磁盘IO抖动会导致丢记录。有人会问接收端自己不发送任何数据只靠被动监听能拿到CSI吗可以。只要发射端在同一个信道上发包接收端网卡的天线就会接收这些帧硬件完成信道估计后把CSI附加到帧信息里驱动层提取这段数据用户态就能读到。这就是Monitor模式的被动式感知能力。4.2 CSI数据格式的前几个字节到底写了什么log_to_file.py保存的是一个裸二进制文件每条CSI记录的结构其实是有固定格式的。根据CSI tool源码linux-80211n-csitool-supplementary里的结构体一条记录由csi_struct和紧随其后的CSI数据组成。字段大致如下字段类型说明packet_lengthu16当前记录的总长度typeu16记录类型CSI类型通常为0x01csi_countu32本轮扫描的CSI数量channelu16无线信道编号channel_typeu8带宽和扩展信道信息sent_cntu8发射端发送序号external_cntu8接收端计数器rateu8调制速率索引csi_data复数数组30个子载波的共轭复数值要注意的是文件里保存的顺序不是网卡在硬件中看到的原始顺序而是经过CSI tool处理后的规范化数组。读取时最好还是按源码里的read_csi_struct函数来解析。我提供一个简化的Python读取脚本能提取每条记录的CSI幅度矩阵import struct import numpy as np def read_csi_file(path): with open(path, rb) as f: data f.read() offset 0 csi_list [] while offset 3 len(data): plen struct.unpack_from(H, data, offset)[0] if plen 0: break cstype struct.unpack_from(H, data, offset 2)[0] # CSI记录类型通常为1 if cstype 1: csi_count struct.unpack_from(I, data, offset 4)[0] channel struct.unpack_from(H, data, offset 8)[0] ntx 3 nrx 3 # 30个子载波每个子载波有 ntx*nrx 个复数 nslices 30 * ntx * nrx # 每个复数为4字节有符号整数2字节实部2字节虚部 if offset plen len(data): raw np.frombuffer(data, dtypenp.int16, countnslices * 2, offsetoffset 12) csi_complex raw[0::2] 1j * raw[1::2] csi_matrix csi_complex.reshape(30, ntx, nrx) csi_list.append((channel, csi_matrix)) offset plen return csi_list代码里的ntx*nrx对应发射天线数和接收天线数。用Intel 5300且发射端也是三天线时ntx3, nrx3如果接收端只有两根天线就要改成2。这个参数不对的话解出来的数据形状会乱。4.3 幅度和相位的物理含义与常见坑拿到CSI复数后最常用的两个量是幅度和相位。幅度是复数模长反映了信号经过信道后的衰减程度相位是复数的辐角反映了子载波的相对传播延迟和硬件相位偏移。计算方式很简单amp np.abs(csi_matrix) # 幅度 phase np.angle(csi_matrix) # 相位实测中幅度比相位更稳定尤其适合人体活动检测。因为相位受采样时钟偏移和频偏影响很大直接用会看到一堆锯齿状跳变需要做线性相位校正或者差分处理这属于另一个话题。这里有个最常见的坑忽略channel_type。如果设置的是HT40channel_type1表示次级信道在上方channel_type2表示在下方这个字段影响相位计算结果。很多人在2.4GHz下用HT40采集没记录channel_type后续分析相位时怎么都对齐不上最后只能重采。还有一个小建议采集时在日志里同时记下发射端发送间隔和接收端移动状态。我习惯在文件名里加入场景标签比如csi_static_36.dat、csi_walk_36.dat这样后面处理数据时不用靠猜测。5. 常见问题与排查记录整个流程从头到尾我踩过的坑比想象中多得多。这些问题一部分是环境问题一部分是使用习惯问题。这里整理成一个速查表并单独把几个高频问题展开说。5.1 典型问题速查表现象可能原因排查方法iwconfig wlan0无Mode字段驱动未正确加载dmesg查iwlwifi日志确认模块版本设置monitor模式时Operation not supported驱动补丁未生效或网卡不支持重打补丁换Intel 5300insmod报version magic错误模块与运行内核版本不一致用uname -r匹配源码版本重新编译挂载debugfs后没有CSI节点内核补丁中的配置未开启或未加载mac80211检查make menuconfig中的mac80211相关选项能进入monitor模式但log文件为空发射端不在同一信道或发包速率太低用iw dev wlan0 set channel固定信道iperf持续打流NetworkManager自动改回managed桌面服务未关闭systemctl stop NetworkManager5GHz信道监听不到数据信道号或带宽设置错误检查iw reg set国家码使用合法的信道号CSI幅度全是零或恒定天线接触不良或发射端功率过低重新插拔天线调整发射端位置5.2 编译时报错的解决办法编译内核模块时最经典的是头文件路径不对。如果你安装的是linux-source包源码默认放在/usr/src/linux-source-...需要在/lib/modules/$(uname -r)/build上做一个软链接指向源码目录sudo ln -s /usr/src/linux /lib/modules/$(uname -r)/build不然Makefile会抱怨找不到generated/uapi等路径。另一个坑是patch应用失败很可能是之前已经打过一遍补丁。这时候从官方源码重新解压一份再打补丁别在旧目录里硬改。patch时如果最后几个hunk失败通常是因为上下文里有空白差异可以用patch -p1 --fuzz5通融一下但打完最好认真读一下生成的文件确认关键改动确实进来了。5.3 采集过程中数据断流的定位技巧采集过程里最让人崩溃的是数据突然停了。我先看dmesg如果出现iwlwifi Tx FIFO is full或者Microcode SW error多半是发射端发包太猛网卡处理不过来。可以把发射端UDP速率调低比如iperf加-b 20M限制带宽。如果日志显示网卡信道自动切换那可能是你的无线网卡在monitor模式下自动扫描了相邻信道需要在驱动里禁用所有扫描行为或者用iw dev wlan0 set channel反复固定。我自己的习惯是把log_to_file和iperf同时在前台跑每5秒看一下文件大小ls -lh /tmp/csi_room_walk.dat如果文件大小稳步增长说明链路没问题。如果长时间不变优先检查发射端是否还在发包然后再看接收端是否掉线。不要一次开好几个抓包工具它们会抢占无线网卡导致CSI记录丢失。6. 从CSI采集到数据感知的扩展实践走到这一步你已经能从Monitor模式稳定拿到CSI数据了。但拿到只是开始怎样把数据用起来才是更值得关心的。我在这一节分享一些自己处理CSI数据时沉淀下来的思路提供一个极简可运行的分析链路并聊聊Monitor模式在这条链路里的贡献。6.1 一个最小可用的CSI幅度处理链路还是以上面的Python读取函数为基础假设读取出来的csi_list已经包含了(channel, csi_matrix)的元组。接下来我通常先做一步简单预处理提取三条接收天线上第1号子载波的幅度随时间的变化画在图上能直接看到明显的周期性波动。import numpy as np import matplotlib.pyplot as plt csi_list read_csi_file(/tmp/csi_walk_36.dat) amplitudes [] for _, csi in csi_list: # 取第1个子载波、发射天线0、接收天线0的幅度 amplitudes.append(np.abs(csi[0, 0, 0])) plt.figure(figsize(12, 4)) plt.plot(amplitudes) plt.xlabel(packet index) plt.ylabel(amplitude (dB?)) plt.title(CSI amplitude on subcarrier 1) plt.show()实际CSITool返回的复数幅度是一个量纲未标定的值直接看数值大小没有绝对意义比较相对变化才是对的。所以很多论文里会把幅度转换成dB比如20 * np.log10(amp)。下一步可以加一个短时滑动窗口的标准差来检测活动强度。人在静止时30个子载波的幅度方差很小人移动时反射路径不断变化标准差显著上升。如果数据里有这个特征说明采集链路完全正常之后就可以进一步做动作分类或者定位实验。6.2 同一个实验里Monitor模式带来的关键优势我把一个实际做过的小实验说一下。在室内同一位置用同一个Intel 5300网卡分别尝试managed模式和Monitor模式采集CSI。一开始我很天真想用手机连上路由器然后在笔记本上读取CSI。结果managed模式下网卡为了维持连接会周期性进行扫描信道会在2.4GHz和5GHz之间跳变CSI数据每隔几秒就断层。而且网卡协议栈会对不匹配的包做硬件过滤很多本应触发CSI的帧根本不会到达驱动。切到Monitor模式后问题基本消失。网卡不再主动扫描只要我固定信道和带宽从发射端打过来的UDP包就会连续被捕获CSI记录的包序号也连续了。后面做帧间相位差分时再也没有因为信道跳变出现很大的随机相位跳变。这说明Monitor模式不仅是“能采到数据”的底线更是“数据质量稳定”的前提。还有一点顺便提一下如果你后面想用这套系统做多径参数估计、AoA计算或者类似算法三根天线的相位关系极其重要。Monitor模式下三根天线的接收链路是并行工作的相位差和幅度差都来自真实的空间传播路径这给算法提供了可靠的物理基础。若在managed模式下工作网卡可能会启用节能模式或天线选择导致天线链路的切换算法结果自然不可信。6.3 后续扩展思路基础数据稳定后可以往三个方向扩展。一是离线分析采集一批数据后在PC上做动作识别这需要准备训练集和分类器不再依赖实时性二是实时处理把log_to_file替换成自己写的C程序通过netlink直接接收CSI数据并做特征提取再喂给分类模型三是多接收端同步用多个Intel 5300网卡分布在房间四角同步采集同一发射端的CSI做多角度定位或成像实验。每一次扩展都会踩到新的坑但最基础的那一步——用Monitor模式稳定采集CSI数据——始终是逃不掉的地基。我个人经验是先把环境固定下来用文档记录好内核版本、补丁版本、网卡型号和信道参数然后不要轻易更新驱动或系统否则常常会花一整天重新踩一遍已经踩平的坑。如果还有余力可以自己写一个自动初始化脚本把挂载debugfs、固定信道、启动log_to_file封装成一条命令对后续重复实验效率提升非常大。最后再分享一个我个人的小习惯采集之前先把接收端网卡的天线朝向固定记录房间布局并在文件头里写入场景说明。很多论文复现困难的根源就在数据采集时没留下足够的元信息等回头分析时根本不知道当时发射端放哪、人在哪里走动。把这些细节处理好比多跑几轮实验更有价值。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询