把 HackRF One 插到 Ubuntu 上,第一次打开 Gqrx 看到频谱图跳出来的那一刻,其实并没有想象中那么顺滑。我第一次搭这套环境时,卡在设备识别上整整一个晚上,最后发现只是内核模块没有正常加载,白折腾了几个小时。这篇文章把那次以及后来反复重装系统沉淀下来的步骤整理成一条线,给准备在 Ubuntu 上搭配 HackRF One、GNU Radio、Gqrx 的朋友一条可以照做的路径。
这套组合是软件无线电(SDR)入门到进阶都绕不开的基础环境:HackRF One 负责把射频信号采集下来交给电脑,GNU Radio 负责对采样数据做信号处理,Gqrx 则是一个现成的图形化接收工具,不用写代码就能先看到频谱、听到声音。三者的关系可以理解为硬件、框架、应用三个层次。适合业余无线电爱好者、通信相关专业的学生,也适合做协议分析、物联网设备调试的技术人员;对第一次在 Linux 下接触 SDR 的新手也友好,只要按着章节走基本能一次跑通。
1. 为什么是这三件套:理清 Ubuntu、HackRF One、GNU Radio 和 Gqrx 的分工
1.1 这套环境能做的事和典型的应用链路
在 SDR 链路里,天线进来的射频信号先经过 HackRF One 的射频前端和下变频,变成中频再数字化,最后通过 USB 接口送进电脑。电脑端拿到的是一串复数采样数据,也就是常说的 I/Q 数据,后续的滤波、解调、解码全都要在这串数据上完成。
GNU Radio 是处理这些 I/Q 数据的核心框架。它在 GNU Radio Companion(GRC)里提供了图形化连线界面,内置了大量信号处理模块,比如低通滤波、FFT、FM 解调、星座图等。你可以像搭积木一样把模块连接在一起,组成一条完整的信号处理链路。Gqrx 则是一个把这类链路打包好的应用,适合先看效果、再深入细节的使用方式。
举个具体例子:想听 FM 广播,用 Gqrx 直接输入频率就能出声;想在 GNU Radio 里做更复杂的处理,比如解码 POCSAG 寻呼机信号、分析汽车遥控钥匙的滚动码,就得用 GRC 自己搭链路或者写 Python 流图。这两种场景覆盖了绝大多数人的需求,所以两样都得装。
顺便提一句,这套环境在硬件上不只支持 HackRF One。只要装了 gr-osmosdr 相关组件,RTL-SDR、Airspy、USRP 这些设备也能一并识别,这也是我坚持用 GNU Radio 而不是某个厂商封闭工具链的原因。今天的环境搭建好了,后续换硬件、加设备,软件层面基本不用推倒重来。
1.2 Ubuntu 版本选择:22.04 LTS 和 24.04 LTS 怎么挑
关于 Ubuntu 版本,22.04 LTS 和 24.04 LTS 之间的选择其实没有太多纠结的必要。我实际测试下来,22.04 的 apt 仓库里 GNU Radio 版本是 3.10,Gqrx 的对应版本能稳定配合;24.04 仓库里的 GNU Radio 版本更新,对较新的内核和 Python 3.12 适配更好。两个版本在软件无线电社区里都有大量用户,遇到问题时在论坛搜索到的解决方案基本都能直接用。
如果一定要给建议:主机配置偏保守、希望装完就不折腾的人,选 22.04 LTS;手头硬件比较新,比如笔记本需要很新的内核才能驱动无线网卡或者显卡,那就选 24.04 LTS。本文的命令在两者上基本通用,只有个别依赖包名在新版里做了拆分,我会在对应位置标注出来。
还有一个容易忽略的点:如果你用的是 Ubuntu Server 或者精简版桌面,后续安装 GNU Radio 时会拉进来一大堆图形库,磁盘占用轻松超过 2 GB。建议安装前确认磁盘剩余空间,特别是用虚拟机或者小容量 EMMC 设备做实验的人。此外,如果是 Windows 用户通过虚拟机装 Ubuntu,注意把 USB 控制器设置为 USB 2.0 或 3.0 兼容模式,否则后面插上 HackRF 会随机掉线。
2. HackRF One 硬件接入:识别、驱动与固件处理,最容易翻车的一步
2.1 插上设备后,先确认内核有没有认出它
HackRF One 的 USB VID:PID 是1d50:6089。为什么特别强调这个?因为设备是否被内核正确识别,很多情况下用一句lsusb就能看出来。
lsusb正常状态下,输出里应该有一行类似这样的内容:
Bus 002 Device 003: ID 1d50:6089 Great Scott Gadgets HackRF One如果看到的是1d50:6089之外的其他 PID,或者设备名显示成HackRF的 bootloader 模式,说明设备停留在固件升级模式,或者上一次刷新固件失败。此时不要急着装驱动,先把 USB 线拔掉重插,或者按一下 HackRF One 侧面靠近 SMA 接口附近的复位按键。大多数情况重新枚举一次就能恢复。
还有一种看似诡异的情况:lsusb里能看到设备,但打开 Gqrx 或者运行hackrf_info时提示找不到设备。这个大概率是权限问题,和内核识别无关,我在后面一节单独说。
2.2 用户权限和 udev 规则:No devices found 的常见根源
Linux 下 USB 设备的访问权限由 udev 规则控制。HackRF 驱动已经在现代内核里自带,不需要额外编译模块,真正坑人的往往是普通用户没有权限访问 USB 设备节点。
最简单的解决办法是把当前用户加入plugdev组:
sudo usermod -a -G plugdev $USER执行完后注销重新登录,让组权限生效。接着运行:
hackrf_info如果输出里能看到固件版本号,比如Firmware Version: 2023.01.1,说明设备访问已经没问题了。如果还是提示No HackRF devices found,就需要手动加一条 udev 规则:
sudo tee /etc/udev/rules.d/99-hackrf.rules << 'EOF' SUBSYSTEM=="usb", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="6089", MODE="0666" EOF sudo udevadm control --reload-rules sudo udevadm trigger这条规则的意思是:当系统检测到 VID 为1d50、PID 为6089的 USB 设备时,把设备节点权限设置为0666,也就是所有用户都可读写。重新插拔 HackRF 后再运行hackrf_info验证。
这里有个细节值得说:为什么推荐先加plugdev组而不是直接写 udev 规则?因为很多 USB 设备厂商在 udev 规则里会同时指定多个 VID/PID,不同批次硬件可能固件升级模式和正常模式的 PID 不一样。加入plugdev组是通用做法,能覆盖更多设备。如果还不行,再写具体规则。
2.3 固件版本和 hackrf-tools:什么时候才需要动固件
通过 apt 安装的hackrf工具包已经包含了hackrf_info、hackrf_transfer、hackrf_spiflash等常用命令。安装命令如下:
sudo apt update sudo apt install hackrf这里特别注意:只有在hackrf_info输出里出现Firmware Version: 0.0.0或者No firmware之类的情况,才考虑刷固件。正常情况下不要随便升级固件,也不要用hackrf_spiflash去写入网上找来的镜像,固件刷写过程一旦断电,设备就会变成一块需要重新进 bootloader 恢复的砖头。
我见过不少朋友在环境搭建阶段就把 HackRF 刷砖了,原因就是看到 GitHub 上有新固件就手痒,结果刷的过程中 USB 线接触不良,前功尽弃。HackRF One 出厂固件对 Gqrx、GNU Radio 的支持已经很成熟,除非你的设备固件异常,否则可以用一句命令确认版本后就把它忘掉。
3. GNU Radio 安装的两种路径:二进制包和源码编译如何选
3.1 走 apt 安装:多数人应该选这条路
我见过很多教程上来就让用户编译安装 GNU Radio,理由是“源码安装更灵活、性能更好”。但说实话,90% 的人根本不需要这么做。Ubuntu 仓库里的 GNU Radio 版本虽然比官方最新版慢一点,但经过了大量稳定性测试,和系统自带的 Python、Boost 库版本都能对上,装完就能用。
在 Ubuntu 上通过 apt 安装:
sudo apt install gnuradio gr-osmosdrgr-osmosdr 这个包很关键,它是 GNU Radio 和 HackRF、RTL-SDR 等硬件之间的桥接层。没有它,GNU Radio 里的 Osmocom Source / Osmocom Sink 模块就找不到设备。安装完成后,可以在终端里输入gnuradio-companion启动图形化开发环境,或者输入python3 -c "import gnuradio; print(gnuradio.version)"检查 Python 绑定是否正常。
Ubuntu 24.04 上可能会出现一个情况:gnuradio包安装完后,Python 环境里from gnuradio import gr报错找不到模块。这通常是 Python 版本切换和 pip 安装路径不一致造成的。解决办法是先确认系统默认 Python 是哪个版本,再用dpkg -L gnuradio | grep gnuradio/gr查看库文件实际被安装到了哪个路径,确保PYTHONPATH指向正确位置。
3.2 源码编译:适合什么人和完整的流程
从源码编译 GNU Radio 主要适合两类人:一类是要修改 GNU Radio 框架内部代码的开发者,另一类是需要使用最新特性但 Ubuntu 仓库里版本太老的人。如果你只是想在 Gqrx 里看频谱、在 GRC 里搭链路,编译这条路完全不推荐,耗时太长而且容易在依赖环节卡住。
如果确定要编译,流程大致如下。先安装构建依赖:
sudo apt install git cmake g++ libboost-all-dev libgmp-dev swig python3-dev python3-numpy python3-mako libsdl1.2-dev liblog4cpp5-dev libfftw3-dev libvolk2-dev libsndfile1-dev然后克隆源码并构建:
git clone --recursive https://github.com/gnuradio/gnuradio.git cd gnuradio mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=Release -DPYTHON_EXECUTABLE=$(which python3) .. make -j$(nproc) sudo make install sudo ldconfig这里有个容易忽略的坑:GNU Radio 的默认安装前缀是/usr/local,而 apt 安装的包默认在/usr下。如果你之前用 apt 装过 GNU Radio,再编译安装会把两套文件混在一起,后续import gnuradio时到底用的是哪套版本完全看PYTHONPATH的顺序,排查起来非常痛苦。
所以我的建议很明确:先确定路线,再动手。要么纯 apt,要么纯源码。不要来回切换。
3.3 GNU Radio 装完后的最小验证
装完 GNU Radio 后,不要急着连硬件,先做一个不依赖硬件的验证。启动gnuradio-companion,新建一个流图,拖入一个 Signal Source、一个 Throttle、一个 QT GUI Frequency Sink,连接好后运行。
如果能看到一条平坦的频谱线,并且 Signal Source 的频率设置能在频谱图上对应出尖峰,说明 GNU Radio 的运行时、图形界面、FFT 模块都正常工作。这一步能把软件问题和硬件问题隔离开:后面接上 HackRF 不出信号时,至少可以确定不是 GNU Radio 本身的问题。
我还习惯在终端里跑一个小脚本验证 Python 环境:
python3 -c " from gnuradio import gr from gnuradio import blocks tb = gr.top_block() src = blocks.vector_source_f([1.0, 2.0, 3.0]) dst = blocks.vector_sink_f() tb.connect(src, dst) tb.run() print('GNU Radio OK') "输出GNU Radio OK就说明核心绑定没问题。这一步对于一个干净环境特别有用,能提前暴露 Python 路径混乱、库文件缺失等问题。
4. Gqrx 安装和首次配置:把硬件变成有声有色的接收机
4.1 安装 Gqrx 的几种方式和取舍
Gqrx 的 apt 包名是gqrx-sdr,安装很简单:
sudo apt install gqrx-sdr装完后在应用菜单里能找到 Gqrx,也可以直接在终端输入gqrx启动。不过 apt 仓库里的 Gqrx 版本通常和当前 Ubuntu 发行版绑定,比如 22.04 上是 2.15 系列,24.04 上则是更新的 2.17 系列。如果你需要更新的版本,可以考虑 Flatpak 版,但在我实际测试中,Flatpak 版需要额外配置权限,对普通用户来说 apt 版是省心之选。
还有一种情况需要注意:如果你在源码编译 GNU Radio 时用了更新的版本,apt 装的 Gqrx 又链接到了系统默认的那套 GNU Radio 库,两者版本不一致会导致 Gqrx 启动时崩溃。这也是我前面强调路线要统一的原因。如果你动了源码编译的念头,Gqrx 最好也一并从源码编译,或者直接用 Flatpak 隔离环境。
4.2 首次启动参数:采样率、增益和频率设置
首次启动 Gqrx 会弹出 I/O 设备配置窗口。设备列表里选择HackRF One,下面有一个采样率下拉框和一个输入控制选项。我的建议是:
| 参数 | 推荐值 | 说明 |
|---|---|---|
| 采样率 | 8 MHz 或 10 MHz | 能覆盖较宽的频谱范围,USB 带宽压力适中 |
| 带宽 | 与采样率一致 | Gqrx 会自动匹配接收带宽 |
| LNA 增益 | 8 dB 到 16 dB | 先从小增益开始,避免底噪被抬得太高 |
| VGA 增益 | 10 dB 到 20 dB | 根据实际信号强度调整 |
| 频率 | 填入本地强信号的频点 | 比如本地 FM 广播电台的频率 |
为什么采样率不建议拉到最高的 20 MHz?HackRF One 的 USB 接口是高速 USB 2.0,理论带宽大致能做到 20 MSPS,但实际跑到这么高以后,USB 传输很容易出现 overrun,表现为频谱图上出现断裂的横纹。8 MHz 到 10 MHz 是一个带宽足够、稳定性也好的范围。
增益这块我要多说一句。很多人第一次用 SDR,习惯把所有增益拉到最大,结果屏幕上全是雪花一样的噪点,以为设备坏了。实际上 LNA 增益过高会把放大器自身的噪声也一起放大,弱信号反而会被淹没。正确做法是从低增益开始,逐步往上调,直到频谱图上出现清晰可辨的信号峰值。
设置完成后,接上天线,把频率调到本地调频广播电台,比如 98.0 MHz 附近,应该能听到清晰的声音。如果只有噪声,先检查天线是否接好,再逐级调高增益。这个地方还有一个常见问题:Gqrx 默认的滤波带宽可能太窄或太宽,导致声音失真,可以在接收界面里选择 FM Mono 模式并调整带宽到 150 kHz 到 250 kHz 之间。
5. 完整验证与排错:从频谱图到回环测试的实测经验
5.1 先跑 Gqrx 看频谱,确认接收链路通不通
环境搭好后的第一步验证,我通常直接用 Gqrx 看频谱,而不是先跑 GNU Radio。因为 Gqrx 启动快、参数少,能把问题快速定位在硬件层面还是软件层面。
操作流程是:启动 Gqrx,选择 HackRF One,采样率 10 MHz,LNA 增益 10 dB,VGA 增益 10 dB,然后把中心频率调到本地信号较强的频段。如果屏幕中央出现明显的信号尖峰,说明整条接收链路正常。此时调节频谱图下方的频率滑杆,能实时看到不同频点的信号强度变化,这种感觉很直接,也是检验设备有没有在工作的最快方式。
如果屏幕上只有一条平直的噪底线,按以下顺序排查:
- 天线是否接好,接触不良会直接导致灵敏度严重下降。
- 是否在室内窗口位置,钢筋混凝土墙体对高频信号衰减很明显。
- 增益是否太低,试着把 LNA 增益提高到 20 dB 以上观察底噪变化。
- 是不是天线接头和 HackRF 的 SMA 口没有拧紧,HackRF One 的 SMA 连接器比较脆弱,拧的时候要用手托住接口部分。
5.2 用 GNU Radio 做回环自测的多种方案
Gqrx 能收到信号只能证明接收链路是通的,但发送链路是否正常还需要单独验证。这里说的“回环测试”,本质是让设备自己发射信号、再自己接收回来,验证 TX 和 RX 通路都工作正常。
HackRF One 是半双工设备,不能同时收发,所以回环测试要分两步做,或者用两个 HackRF 同时配合。先说最可靠的方案:准备两个 HackRF,用一根短的同轴线连接 A 设备的 TX 口和 B 设备的 RX 口,中间串一个 30 dB 衰减器防止接收端过载。在 GNU Radio Companion 里,A 设备用 Osmocom Sink 发射一个 1 kHz 正弦波,B 设备用 Osmocom Source 接收,接一个 QT GUI Frequency Sink。运行后如果 B 的频谱图在中心频率附近出现明显尖峰,说明两条设备的发射和接收链路都正常。
只有一个 HackRF 的情况下,可以用hackrf_transfer命令做一种简化的自测。先准备工作目录,生成一个简单的正弦波文件,再指定发射频率和增益,把信号从 TX 口输出。这里必须强调:如果没有任何射频许可证或者实验环境保障,不要把天线直接接到 TX 口发射,建议要么在 TX 口接 50 欧姆负载,要么串一个大衰减器后再接天线,避免对其他无线业务造成干扰。
hackrf_transfer -t sine_wave.iq -f 433920000 -s 2000000 -a 0 -g 20 -l 8参数含义分别是:-t指定要发送的文件,-f设置中心频率 433.92 MHz,-s设置采样率 2 MSPS,-a关闭额外放大,-g设置 TX 增益 20 dB,-l设置 LNA 增益 8 dB。至于检查发射是否正常,如果你手边正好有另一台 SDR 接收机,可以在旁边看频谱;没有的话,这个测试至少能确认设备有没有进入发射状态、USB 数据传输有没有报错。
5.3 我实际遇到的几个坑和对应的排查思路
最后把环境搭建过程中最常遇到的几个问题按“现象 - 原因 - 解决”列出来,这些都是我或者身边朋友真实踩过的。
现象一:hackrf_info 找不到设备,但 lsusb 能看到
原因通常是权限问题,或者设备停在了 bootloader 模式。先执行groups命令确认当前用户是否在plugdev组里,如果不在,按第 2.2 节的方法加入并注销重登。如果权限没问题,拔出 USB 重插,或者按一下 HackRF 的复位键。我在某个品牌 USB 3.0 hub 上遇到过识别不稳定,后来把 HackRF 直插主板 USB 口就解决了。
现象二:Gqrx 启动后频谱图刷不出,提示 overrun
overrun表示 USB 数据来不及传输,接收端丢包。优先把采样率从 20 MHz 降到 10 MHz 或 8 MHz。如果还不行,检查是不是通过 USB hub 连接的,尽量直插主板。另一个容易被忽略的原因是电脑 CPU 太老,频谱图计算和显示本身就需要占用不少 CPU,可以在 Gqrx 的设置里把 FFT 分辨率适当调低,比如从 4096 降到 2048,缓解计算压力。
现象三:GNU Radio 运行时提示找不到 Osmocom Source
说明 gr-osmosdr 没有正确安装,或者 GNU Radio 的模块路径里没有它。在 Ubuntu 上用sudo apt install gr-osmosdr安装后,在 Python 里执行from gnuradio import osmocom验证。如果还是找不到,用gnuradio-config-info --prefix查看当前 GNU Radio 前缀路径,再检查 gr-osmosdr 是否被安装到了同一个前缀下。
现象四:Gqrx 能启动但没声音
排除硬件问题后,大概率是音频输出设备选错了。Gqrx 的音频回放设备默认可能指向了某个不存在的声卡,在 Audio 设置里改成系统默认设备即可。另外,接收模式如果是 AM 或 SSB,解调出来的声音本来就不适合直接用扬声器听,先切到 FM Mono 模式测试最稳妥。
现象五:运行 GNU Radio 示例时崩溃,报错信息指向 libgnuradio
这个多半是系统里存在多套 GNU Radio 库文件,比如你用 pip 装过某些无线相关的 Python 包,或者源码编译和 apt 安装混用了。处理思路是彻底清理其中一套。我个人经验是保留 apt 版,把/usr/local/lib下 GNU Radio 相关文件全部删除,然后重新执行sudo ldconfig。
回环测试做完,Gqrx 频谱图能稳定显示、FM 广播声音清晰,这套环境基本就算搭建成功了。之后你可以顺着两个方向继续深入:一是用 GRC 搭一条 FM 解调链路,从底层理解正交采样和解调流程;二是给 HackRF 配上不同的天线,尝试分析 433 MHz 遥控器、315 MHz 胎压监测等常见无线信号。每一步遇到问题时,优先从“硬件、驱动、软件版本、参数设置”四个层面去定位,大多数问题都能在这里找到思路。