mdio-tool 简介:源码获取、编译安装、基本命令格式解析
咱们做嵌入式调试,最常打交道的就是 PHY 芯片了。驱动挂不上、link 起不来、协商模式不对……调 PHY 寄存器几乎是每天的家常便饭。这时候如果手边有把趁手的工具,效率能高不少。
mdio-tool 就是这么一个小工具。它不花哨,但很实用——直接通过 MDIO 总线读写 PHY 寄存器,省得你每次插网线、再跑一堆 ethtool 看半天。我个人习惯在移植新板子时,第一件事就是把 mdio-tool 装好,然后一个个读 PHY 的 ID 寄存器,确认硬件通了再碰驱动。
这一节咱们就把它搞到手,装好,再学会最基本的命令格式。
源码获取
mdio-tool 的代码在 GitHub 上有好几个版本,我个人用的是下面这个(长期维护,跟内核小版本兼容性比较好):
git clone https://github.com/wtarreau/mdio-tool.git
cd mdio-tool
为什么推荐这个版本?因为它对较新内核(4.x ~ 6.x)的 /sys/class/mdio_bus 接口适配得最好。我曾在某项目里用过另一个 fork,结果 5.10 内核下怎么都读不到寄存器,折腾了一下午才发现是路径硬编码的事——换个版本就解决了。
你拿到代码后,可以先看一眼 README,里面通常会说明依赖的内核配置选项(比如 CONFIG_MDIO_DEVICE、CONFIG_PHYLIB)。如果你的内核没开这些宏,那后面就算编译通过,运行时也会报 No such device。
uname -r 看一眼,再根据 README 的提示选择合适的 tag 或分支。编译安装
编译过程不复杂,但有几个坑。先装好编译依赖:
sudo apt install build-essential linux-headers-$(uname -r) # Debian/Ubuntu
sudo yum install gcc make kernel-devel # CentOS/RHEL
接着直接 make:
make
sudo make install # 默认装到 /usr/local/bin
如果只编译不安装,二进制在当前目录下,叫 mdio-tool。我个人习惯先用 ./mdio-tool -h 测试一下,确认可执行后再装到系统路径。
我曾经在一个嵌入式板子上编译时卡了很久,原因是内核头文件路径不对。交叉编译环境下,linux-headers 的路径跟本地机器不一样,你得手动指定 KERNEL_DIR:
make KERNEL_DIR=/path/to/your/kernel/build
否则编译时就报 linux/mdio.h: No such file or directory。嗯,这个头文件其实就在内核源码里,不是系统库。
KERNEL_DIR 指向的是已配置过的内核源码目录(且 include/generated/autoconf.h 存在)。否则 mdio-tool 可能缺少 CONFIG_ 宏定义,运行时会找不到 mdio 总线节点。基本命令格式解析
装好后,咱们来看看怎么用它。基本命令格式非常简洁:
mdio-tool [options] <phy_addr> <reg_addr> [value]
phy_addr:PHY 芯片的 MDIO 地址,通常是 0~31。这个地址由 PHY 芯片的硬件引脚(如 ADDR0~ADDR4)决定,也可能是片选后的映射地址。reg_addr:寄存器地址,范围 0~31(标准 IEEE 802.3 寄存器),或者 0~0x1F(扩展寄存器)。[value]:写操作时指定的值,16 位。如果省略该参数,则执行读操作。
常用选项如下表:
| 选项 | 说明 | 示例 |
|---|---|---|
-r |
读操作(默认模式,可省略) | mdio-tool -r 0 1 |
-w |
写操作 | mdio-tool -w 0 0 0x1140 |
-v |
详细输出,显示总线路径等信息 | mdio-tool -v -r 0 1 |
-b <bus> |
指定 MDIO 总线设备(默认查找第一个) | mdio-tool -b mdio@ffe24000 -r 4 2 |
-h |
显示帮助 | mdio-tool -h |
-w,写必须加 -w 且给出 value。不然工具会默默认为你想读,然后给你一堆 0xffff——你想想看,这要是写错了,PHY 配置就飞了。举个完整的读例子,读取 PHY 地址 2 的寄存器 0(BMCR,基本控制寄存器),看看当前是否处于软件复位状态:
mdio-tool -r 2 0
输出可能像 0x1140。如果你想把它软复位一下,写值 0x8000(bit15 置位):
mdio-tool -w 2 0 0x8000
之后再读一次,确认 bit15 是否自动清除了。正常情况下 PHY 复位完成后会清掉该位。
为什么建议用 -v 跑一次?因为它会打印出工具实际使用的 sysfs 路径,比如 /sys/class/mdio_bus/mdio@.../。我曾在 SPI 转 MDIO 的板子上用默认参数死活读不到东西,加 -v 一看才发现总线名称是 spi_mdio,不是 mdio@...,只能手动 -b 指定——差了一个字母,结果大不相同。
下面这张图帮你快速理解 mdio-tool 的数据流向:
-v 确认 sysfs 路径是否存在,再用示波器抓 MDC/MDIO 引脚看有没有波形。好了,工具拿到手、装好、基本命令也清楚了。下一小节咱们会深入 MDIO 的协议细节,但你可以先拿手边任意一块开发板,试读 PHY ID 寄存器(地址 2 和 3),看看芯片型号跟你硬件文档是否一致——调试的第一步,永远是确认通信是通的。