news 2026/8/16 3:21:40

定制板多网口怎么做?我从 Switch、NIC、PHY 到 Linux 的一次实战梳理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
定制板多网口怎么做?我从 Switch、NIC、PHY 到 Linux 的一次实战梳理

📺B站 嵌入式孙老师:博主个人介绍
📘博主书籍-京东购买链接:Yocto项目实战教程
📘加博主微信,进技术交流群jerrydev


最近在梳理一套多网口 Ethernet 设计时,发现真正难的并不是“多接几个 RJ45”,而是很容易把NIC、MAC、PHY、Switch、MDI、SGMII,以及 Linux 里的 ethX混在一起。

刚开始看原理图时,我也有过几个很自然的疑问:

  • 一颗 Switch 扩出 4 个网口,Linux 会不会多出 4 个ethX
  • Switch 会不会给下面的设备分配 IP?
  • 网卡已经能在ifconfig里看到,为什么还是Link detected: no
  • PHY 的 MDI 到底是数字信号还是物理信号?
  • 两颗 PHY 都有 MDI,是不是直接连起来就行?
  • 硬件 Link 通了之后,DHCP 又应该由谁负责?

把这些问题逐个拆开以后,我对多网口设计的理解反而变得比较简单了:

Linux / Application │ TCP/IP │ NIC / MAC │ Uplink │ Switch ┌────┼────┐ │ │ │ PHY PHY PHY │ │ │ MDI MDI MDI │ │ │ Magnetics │ RJ45

这篇就沿着这条链,把我这次学习和排查过程中最容易混淆的地方整理一下。


1. 多网口设计,先把硬件角色分清楚

NIC:CPU 接入 Ethernet 的入口

NIC 全称Network Interface Controller,工程里直接理解成网卡就可以。

常见有两种:

SoC → PCIe → Ethernet NIC

或者:

SoC → USB3 → Ethernet NIC

这类设备被 Linux 驱动以后,通常会变成:

eth0 eth1 eth2

很多 PCIe / USB Ethernet NIC 内部其实已经包含:

NIC ┌───────────────┐ │ PCIe / USB │ │ ↓ │ │ MAC │ │ ↓ │ │ PHY │ └───────────────┘ ↓ MDI

所以NIC 和 PHY 不是一回事

NIC 是一套完整的网络接口设备,PHY 只是其中负责 Physical Layer 的一部分。


MAC:处理 Ethernet Frame

MAC 还是数字世界里的东西。

Application ↓ TCP / UDP ↓ IP ↓ Ethernet Frame ↓ MAC

MAC 主要处理:

MAC Address Ethernet Frame CRC TX / RX Queue Flow Control

它知道怎么收发 Ethernet Frame,但还没有真正开始驱动网线。


PHY:从数字 Ethernet 进入真正的物理层

PHY 才是真正的 Physical Layer Transceiver:

MAC │ │ Digital Ethernet ▼ PHY │ │ Physical Signal ▼ 传输介质

PHY 内部会完成:

Auto-Negotiation 编码 / 解码 调制 / 解调 均衡 时钟恢复 回波消除 模拟前端

所以后来我觉得,把 PHY 简单理解成“电平转换芯片”是不准确的。

它实际上实现了一整套 Ethernet Physical Layer。


MDI:PHY 最靠近网线的一侧

这是我这次比较容易混淆的一个概念。

MDI:

Medium Dependent Interface

1G / 2.5GBASE-T 常见四对:

MDI_A_P / MDI_A_N MDI_B_P / MDI_B_N MDI_C_P / MDI_C_N MDI_D_P / MDI_D_N

这里已经不是普通的 0/1 数字接口,而是Copper Ethernet PHY 的模拟差分物理信号

所以标准铜口结构应该这样看:

MAC ↓ PHY ↓ MDI ↓ Magnetics ↓ RJ45 ↓ Twisted Pair Cable

Magnetics,也就是 Ethernet 变压器,主要处理隔离、共模、EMC 等问题。

它并不是负责“数字变模拟”的——这个工作在 PHY 里面已经完成了。

我后来再看到MDIP/MDINMDI_A/B/C/D这类引脚时,就会直接想到:

这里已经进入 Copper Physical Layer 了。


Switch:不是网卡,而是多 Port 二层交换

这是另一个一开始很容易混的地方。

NIC 做的是:

CPU → Network

Switch 做的是:

CPU/Uplink │ ┌─ Switch ─┐ │ │ │ Port0 Port1 Port2 ...

Switch 会学习:

MAC_A → Port0 MAC_B → Port2 MAC_C → Uplink

以后收到 Ethernet Frame,就根据目的 MAC 地址决定从哪个 Port 发出去。

所以我现在最简单的区分就是:

NIC 负责 CPU 怎么进入 Ethernet;Switch 负责多个 Ethernet Port 之间怎么交换 Frame。

这也是为什么一颗多口 Switch 本身不能简单当成“多口网卡”。


4 个 RJ45,不代表 Linux 一定有 4 个 ethX

这个问题我一开始也专门确认过。

假设:

Linux │ eth1 │ Switch ├─ Port0 → RJ45 ├─ Port1 → RJ45 ├─ Port2 → RJ45 └─ Port3 → RJ45

Linux 完全可能只看到:

eth1

下面 4 个接口只是 Switch 内部的 Port。

因为:

eth1 = CPU 自己的网络接口 Port0~3 = Switch 的交换端口

两者不是一个概念。

如果使用 Linux DSA(Distributed Switch Architecture),情况会不同,Switch 的 User Port 可以表现成:

swp0 swp1 swp2 swp3

但那需要具体 Switch 有对应的 Kernel Driver 和软件架构支持。

所以更准确地说:

多个 RJ45 ≠ 多个 Linux NIC

这条结论对我理解 Switch 很有帮助。相关学习记录里也正是通过“Switch 自主工作”和 Linux Uplink 两个层面把这件事拆开的。


RGMII、SGMII 和 MDI 不要混在一起

在 Ethernet 原理图里,它们经常同时出现。

但其实非常好区分。

RGMII:

MAC │ RGMII │ PHY / Switch

属于并行数字接口

SGMII:

MAC / Switch │ SGMII │ PHY

属于高速串行数字接口

MDI:

PHY │ MDI │ Magnetics │ Cable

属于铜口物理层接口

所以我最后直接记成:

接口怎么理解
RGMII芯片间并行数字 Ethernet 接口
SGMII芯片间串行数字 Ethernet 接口
MDICopper PHY 面向介质的物理接口

另外,SerDes 也不等于 SGMII

SerDes 是 Serializer / Deserializer,是高速串行收发能力;SGMII、2500BASE-X、USXGMII 等才是具体的 Ethernet 接口形式。


Switch 的 Port 也分类型

看到:

6-Port Switch

不能马上理解成:

6 × RJ45

真正应该看的是:

几个 Port 自带 Copper PHY? 几个是 SerDes Port? 哪个是 CPU/Uplink Port? 支持什么速率?

如果 Switch Port 自带 PHY:

Switch │ Integrated PHY │ MDI │ Magnetics │ RJ45

这类最适合直接做普通铜口。

如果 Port 只是 SerDes:

Switch │ SGMII / 2500BASE-X │ External PHY │ MDI │ Magnetics │ RJ45

就还需要一颗外部 PHY。

我这次也是在分析一条Switch SerDes → External PHY → MDI的链路后,才真正把这两个 Port 类型区分清楚。


板内如果能走 SerDes,就尽量不要反复进出 Copper PHY

从架构上看,我现在更喜欢:

SoC MAC │ SGMII / USXGMII │ Switch

真正到了板外才:

Switch ↓ PHY ↓ MDI ↓ Magnetics ↓ RJ45

而如果出现:

NIC ↓ Copper PHY ↓ MDI ↓ Copper PHY ↓ SerDes ↓ Switch

链路就会复杂很多。

这里我实际碰到过一个很有价值的问题:

两颗 PHY 都有 MDI,能不能直接把两组 MDI 接在一起?

答案不能简单理解成“接口名字一样就能接”。

MDI 是模拟 Physical Layer 接口,标准铜口是按照 PHY 厂商的 Reference Design、Magnetics 和 Cable Channel 去设计的。

如果要做 PHY-to-PHY 的 transformerless / back-to-back 连接,必须确认两颗 PHY 是否明确支持,以及偏置、阻抗、耦合等要求。

不能把它当成:

TXP/N 直接接 RXP/N

这种普通数字 SerDes 来处理。

这也是我这次排查中最有价值的一个硬件认识:**MDI 和 SGMII 虽然都是差分线,但根本不是一类信号。**相关实测笔记里,PHY 的 SerDes 一侧和 MDI 一侧也表现出了完全不同的连接方式。


Switch 本身也有启动过程

另一个之前容易忽略的地方是:

Switch 并不是“上电就天然开始交换数据”。

一颗复杂一点的 Switch 通常还有:

Power ↓ Clock ↓ Reset ↓ Strap Sampling ↓ SPI Flash / EEPROM ↓ Firmware / Configuration ↓ PHY / SerDes Init ↓ Port Forwarding

所以看 Switch 电路时,除了数据线,我现在还会先找:

Power Clock Reset Strap SPI Flash / EEPROM MDIO / SPI / I2C

Strap 可能决定:

Boot Mode PHY Enable Port Mode Clock Mode Management Interface

因此一个 Switch 没工作,不一定和 Linux 有关系。

有时候 Linux 根本就没有参与它的启动。实际学习记录里也能看到典型的 Strap、SPI Flash、自启动和 PHY Port 组合。


2. 软件和调试:我后来不再一上来就 ping

ethX出现,只能证明网卡这一层起来了

比如:

iplink

能够看到:

eth1

如果是 USB NIC:

lsusb

也正常。

如果是 PCIe NIC:

lspci

也正常。

这些只能证明:

SoC ↓ PCIe / USB ↓ NIC ↓ Driver ↓ ethX

这部分工作了。

它并不能证明:

PHY ↓ Cable ↓ Switch

已经建立 Link。

这个区别是我这次排查过程中很重要的一步。


UPLink detected: yes不是一回事

例如:

iplinkshow eth1

看到:

<NO-CARRIER,BROADCAST,MULTICAST,UP>

这里的:

UP

只表示:

软件把这个接口打开了。

真正判断 Physical Link,我更关注:

ethtooleth1

里面:

Link detected: yes

以及:

cat/sys/class/net/eth1/carrier

正常应该:

1

再看:

LOWER_UP RUNNING

这些状态。

我实际遇到过:

UP 但是 NO-CARRIER Link detected: no carrier = 0

这时候 IP 配置得再漂亮也没有意义。

因为问题还停留在 Physical Layer。这个区分在实际日志分析里非常明显。


Link 正常以后,第二步应该看 Frame,而不是马上 ping

Physical Link 成立以后:

ip-slinkshow eth1

看:

RX packets TX packets

有没有增长。

然后:

tcpdump-ieth1-e-n

看有没有:

ARP DHCP IPv6 Broadcast Multicast

这一步很重要,因为:

Ethernet Frame 能不能收到,和 IP 是否在同一个网段是两件事情。

即使 IP 没配对,只要对端有广播、ARP 或 DHCP:

RX packets

照样可以增长。

因此我现在排网口基本按:

有没有 Carrier? ↓ 有没有 Ethernet Frame? ↓ 有没有 IP?

来走。


169.254.x.x不是 Switch 分配的 IP

这也是我学习过程中一个比较典型的误区。

看到一个下游设备拿到了:

169.254.x.x

第一反应很容易是:

是不是 Switch 给它分配了地址?

其实一般不是。

169.254.0.0/16是 IPv4 Link-Local。

很多系统在:

DHCP 请求 ↓ 没有服务器回应 ↓ 自己选择一个 169.254.x.x

作为兜底地址。

所以出现:

169.254.x.x

反而经常是在告诉我们:

DHCP 没成功。

对于普通二层 Switch 来说,它负责的是 Ethernet Frame 转发,而 DHCP Server 通常运行在主机、路由器或专门的网络服务上。


DHCP Server 应该放在哪里?

假设:

Linux 主机 │ eth1 │ Switch ├─ Device A ├─ Device B └─ Device C

如果希望下面的设备自动获得:

192.168.100.x

可以在 Linux 主机上跑:

dnsmasq

过程其实很简单:

Device │ │ DHCPDISCOVER ▼ Switch │ ▼ eth1 │ ▼ dnsmasq │ │ DHCPOFFER / DHCPACK ▼ Device 得到 IP

Switch 在这里依然只是转发二层广播。

它并不负责:

“给谁分什么 IP”

一个 dnsmasq 可以服务多个接口,但网段要分开

我这次还碰到了一个纯软件问题:

一台设备上可能同时有:

Wi-Fi AP Ethernet Port A Ethernet Port B

都需要 DHCP。

没有必要启动三个 dnsmasq,一个实例就可以:

bind-interfaces interface=wlan-ap dhcp-range=set:wifi,192.168.10.10,192.168.10.100,12h dhcp-option=tag:wifi,3,192.168.10.1 dhcp-option=tag:wifi,6,192.168.10.1 interface=eth1 dhcp-range=set:lan1,192.168.20.10,192.168.20.100,12h dhcp-option=tag:lan1,3,192.168.20.1 dhcp-option=tag:lan1,6,192.168.20.1

这里后来我才注意到一个细节:

dhcp-option=3 dhcp-option=6

如果不加 tag,可能会错误地应用到其他接口。

所以多网段时最好配成:

set:xxx tag:xxx

让 Gateway 和 DNS 跟对应地址池绑定。

这部分也是我在实际增加多个 DHCP 网段时踩到的一个软件配置点。


systemd 依赖也可能让“DHCP 配置正确但服务就是起不来”

还有一个问题跟 Ethernet 本身几乎没有关系,却很容易误判成网络问题。

例如:

dnsmasq.service

被 systemd 强绑定到某一个网卡:

BindsTo=sys-subsystem-net-devices-xxx.device

当这个接口不存在时:

Dependency failed

整个 dnsmasq 都起不来。

如果 dnsmasq 同时服务多个独立接口,这种强依赖反而可能不合理:

接口 A 不存在 ↓ dnsmasq 整体启动失败 ↓ 接口 B 的 DHCP 也一起没了

后来我更倾向把:

数据接口是否存在

和:

DHCP Service 是否允许启动

分开考虑。

这种问题如果只盯着dnsmasq.conf本身,很容易找错方向。


最后形成了一套比较固定的 Ethernet 排查顺序

现在再遇到多网口不通,我基本不会从ping开始。

我会按:

1. Power ↓ 2. Clock / Reset / Strap ↓ 3. NIC 是否枚举 ↓ 4. Switch 是否 Boot ↓ 5. PHY / SerDes Link ↓ 6. Carrier ↓ 7. Ethernet Frame ↓ 8. DHCP / ARP ↓ 9. IP / Route ↓ 10. Application

具体 Linux 命令也很固定:

# 网卡有没有iplink# 物理 Linkethtooleth1cat/sys/class/net/eth1/carrier# 二层有没有包ip-slinkshow eth1 tcpdump-ieth1-e-n# DHCPjournalctl-udnsmasq-f# 最后才是ipaddriprouteping

这样最大的好处,是能够快速判断问题到底属于:

硬件 PHY Switch Driver DHCP 还是 IP

而不是统称为“网口不通”。


3. 这次学习下来,我觉得最值得记住的几件事

第一次接触多网口 Switch 设计时,很容易从 RJ45 数量出发:

有 4 个网口 → 应该有 4 个网卡 → 应该有 4 个 IP

后来发现这个思路本身就不对。

更合理的理解应该是:

CPU │ NIC / MAC │ Uplink │ Switch ├─ Port ├─ Port ├─ Port └─ Port

Switch Port、Linux NIC 和 IP Address 本来就是三个不同层面的东西。

另外一个比较深的体会,是 Ethernet 原理图不能只看“差分线有没有接上”。

下面这些:

RGMII SGMII USXGMII MDI

虽然都在传 Ethernet,但处在完全不同的位置。

特别是:

SGMII → 芯片间数字接口 MDI → Copper PHY 模拟物理接口

如果这一层没分清,后面很容易把两种完全不同的差分信号当成同一种东西。

最后则是软件。

多网口不是把硬件 Link 做出来就结束了,还要继续考虑:

Switch 谁初始化? PHY 谁管理? Linux 能看到哪些接口? DHCP Server 放在哪里? 多个网段怎么隔离? 服务启动顺序是否合理?

所以现在如果让我再画一次多网口架构,我不会先画 RJ45,而是先画:

Linux / Application │ TCP/IP │ NIC / MAC │ Uplink 带宽 │ Switch ┌─────────┼─────────┐ │ │ │ PHY PHY PHY │ │ │ MDI MDI MDI │ │ │ Magnetics Magnetics Magnetics │ │ │ RJ45 RJ45 RJ45

然后逐层问:

SoC 怎么接入 Switch? Uplink 带宽够不够? Switch Port 是内置 PHY, 还是 SerDes? MDI 后面的电气设计是否正确? Switch 是自主启动, 还是由 BSP / Linux 配置? Linux 应该看到 ethX, 还是 DSA 的 swpX? DHCP 又由谁负责?

这些问题回答清楚之后,多网口设计就不会再是一堆 NIC、PHY 和 Switch 芯片堆在一起。

对我来说,这次最大的收获也不是记住了某颗芯片,而是终于能把“网络数据从 Linux 一直走到网线,中间到底经过了什么”顺下来。

后面无论换 1G、2.5G、5G 还是 10G,器件和接口会变,但这套分析方法基本不会变。

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

从全钛云台到机器人手机:揭秘主动交互如何重塑移动设备未来

上周&#xff0c;当“全球首款机器人手机”这个标题出现在眼前时&#xff0c;我的第一反应和很多人一样&#xff1a;这又是一个营销噱头吧&#xff1f;手机和机器人&#xff0c;这两个看似关联不大的领域&#xff0c;能碰撞出什么实质性的火花&#xff1f;是给手机加个轮子&…

作者头像 李华
网站建设 2026/8/16 3:14:04

电脑休眠与睡眠功能详解:原理、配置与常见问题排查

1. 项目概述&#xff1a;休眠与睡眠&#xff0c;你真的用对了吗&#xff1f;作为一名和电脑打了十几年交道的“老司机”&#xff0c;我发现一个挺有意思的现象&#xff1a;很多人用了多年电脑&#xff0c;却始终没搞明白“休眠”和“睡眠”这两个功能到底有啥区别。每次看到同事…

作者头像 李华
网站建设 2026/8/16 3:12:17

MySQL实战指南:从安装配置到性能优化的全链路指令手册

1. 项目概述&#xff1a;为什么你需要一份“活”的MySQL指令手册干了这么多年后端开发&#xff0c;数据库这块儿&#xff0c;MySQL绝对是绕不开的。新手入门&#xff0c;第一道坎儿往往是安装配置&#xff1b;等你能跑起来几个简单的SELECT了&#xff0c;又会发现网上搜到的指令…

作者头像 李华
网站建设 2026/8/16 3:11:24

RoboMaster_C板_启动与复位_CSDN

RoboMaster C 板烧录后没反应&#xff1f;聊聊 BOOT0 拉低与下载后按复位的原因 文章目录RoboMaster C 板烧录后没反应&#xff1f;聊聊 BOOT0 拉低与下载后按复位的原因一、背景二、为什么 BOOT0 必须拉低2.1 STM32 上电后先"看脚色"2.2 0 地址是个"别名窗口&q…

作者头像 李华