1. Yocto网络基础:网络架构与核心配置

大家好,我是你们的嵌入式Linux讲师。今天咱们聊聊Yocto项目里的网络配置。说实话,网络这块儿在嵌入式开发中经常被忽略,但一旦出问题,排查起来特别头疼。我这些年带项目,至少有一半的联调时间都花在网络问题上。所以,打好基础很重要。

1.1 Yocto项目网络架构概述

Yocto项目的网络架构,说白了就是一套让嵌入式设备联网的完整方案。它不像桌面Linux那样“开箱即用”,因为嵌入式设备的硬件千差万别——有的用有线以太网,有的用Wi-Fi模块,还有的用4G/5G模组。

我个人习惯把Yocto的网络架构分成三层来看:

  • 硬件抽象层:负责驱动各种网络接口(eth0、wlan0、wwan0等)
  • 协议栈层:Linux内核自带的TCP/IP协议栈,这部分基本不用动
  • 配置管理层:用户空间的网络配置工具,比如ifupdown、systemd-networkd

嗯,这里要注意:Yocto本身不发明新的网络协议,它只是把Linux生态里成熟的网络组件打包成recipe,让你能灵活选择。你想想看,同样是做路由器,有的项目用Busybox的udhcpc,有的用dhcpcd,还有的用NetworkManager——Yocto都能支持。

核心观点:Yocto的网络架构是“可插拔”的。你不需要从头造轮子,只需要选对组件,配好参数。

1.2 网络栈组成:内核、驱动、协议栈

咱们拆开来看网络栈的每个部分。我在项目中遇到过好几次“网口灯亮了但ping不通”的诡异问题,最后发现都是驱动或协议栈配置的坑。

1.2.1 内核网络子系统

Linux内核的网络子系统是个庞然大物。但对我们嵌入式开发来说,重点关注这几个配置项:

内核配置项 说明 我的建议
CONFIG_NET 网络协议栈总开关 必须开启
CONFIG_INET IPv4支持 99%的项目都需要
CONFIG_IPV6 IPv6支持 看需求,建议开启
CONFIG_NETDEVICES 网络设备驱动框架 必须开启
CONFIG_ETHERNET 以太网驱动支持 有线网络必选

我曾经在一个项目里忘了开CONFIG_PACKET,结果tcpdump完全不能用,排查了整整两天。所以,建议你在Yocto的defconfig里把这些基础选项都加上。

1.2.2 网络设备驱动

驱动这块儿,Yocto通过内核模块或内置驱动来支持。常见的网络驱动有:

  • 有线网卡:如Intel的e1000/e1000e、Realtek的r8169、DWMAC(常见于STM32MP1)
  • 无线网卡:如Broadcom的brcmfmac、Qualcomm的ath10k、MediaTek的mt76
  • USB网卡:如asix、rtl8152、smsc95xx(树莓派上常见)

在Yocto里添加驱动很简单,比如你要加Realtek有线网卡驱动,在local.conf里写:

# 使能Realtek 8169网卡驱动
CONFIG_R8169=y
# 或者编译成模块
CONFIG_R8169=m

但要注意,有些芯片的驱动不在主线内核里,需要你打补丁。我记得有一次客户用了一款国产的Wi-Fi模块,驱动只支持老内核,我硬是花了三天把驱动移植到Yocto的5.10内核上。

1.2.3 协议栈与网络工具

协议栈这块儿,Linux内核已经做得非常成熟了。我们主要关注用户空间的工具链:

  • busybox:提供ifconfig、route、ping等基础命令,适合资源受限的设备
  • iproute2:新一代网络配置工具,ip命令比ifconfig更强大
  • dhcp客户端:udhcpc(busybox自带)、dhcpcd、NetworkManager
  • DNS解析:libc的getaddrinfo、dnsmasq(本地DNS缓存)

我个人习惯在Yocto里同时开启busybox和iproute2。busybox用来做基础诊断,iproute2用来做精细配置。你想想看,ifconfig已经快被淘汰了,但很多老工程师还是习惯用它——嗯,兼容并包嘛。

小技巧:在Yocto的IMAGE_INSTALL里添加"iproute2"和"busybox",就能同时拥有两套网络工具。

1.3 网络配置核心文件

这部分是实操的重点。Yocto支持两种主流的网络配置方式:传统的/etc/network/interfaces和现代的systemd-networkd。咱们一个一个说。

1.3.1 /etc/network/interfaces(传统方式)

这是Debian/Ubuntu系的老牌配置方式。Yocto默认使用Busybox的ifupdown工具来解析这个文件。一个典型的配置如下:

# /etc/network/interfaces
# 回环接口
auto lo
iface lo inet loopback

# 有线网卡 - 静态IP
auto eth0
iface eth0 inet static
    address 192.168.1.100
    netmask 255.255.255.0
    gateway 192.168.1.1
    dns-nameservers 8.8.8.8 114.114.114.114

# 无线网卡 - DHCP
auto wlan0
iface wlan0 inet dhcp
    wpa-ssid "MyWiFi"
    wpa-psk "password123"

我在项目中遇到过一个问题:用这种方式配置Wi-Fi时,wpa_supplicant的启动顺序经常搞错。后来我学乖了,在Yocto的systemd服务里加了依赖关系才解决。

避坑指南:我曾经在/etc/network/interfaces里同时配置了eth0和wlan0的默认网关,结果路由表冲突,网络时通时断。记住:默认网关只能有一个。

1.3.2 systemd-networkd(现代方式)

如果你的Yocto项目用了systemd(现在大部分都用了),我强烈建议你用systemd-networkd。它更灵活,也更适合复杂的网络场景。

配置文件的路径是/etc/systemd/network/,每个网络接口一个文件。比如:

# /etc/systemd/network/20-eth0.network
[Match]
Name=eth0

[Network]
Address=192.168.1.100/24
Gateway=192.168.1.1
DNS=8.8.8.8
DNS=114.114.114.114

DHCP方式更简单:

# /etc/systemd/network/30-wlan0.network
[Match]
Name=wlan0

[Network]
DHCP=yes

嗯,这里要注意:systemd-networkd默认不处理Wi-Fi的认证。你需要配合wpa_supplicant一起用。我个人习惯在Yocto的systemd服务里这样配置:

# wpa_supplicant服务启动后,再启动systemd-networkd
[Unit]
Description=WPA supplicant
After=network-pre.target
Before=network.target

[Service]
ExecStart=/usr/sbin/wpa_supplicant -i wlan0 -c /etc/wpa_supplicant.conf
Restart=always

1.3.3 两种方式的对比

对比项 /etc/network/interfaces systemd-networkd
适用场景 简单网络、资源受限设备 复杂网络、需要动态管理
配置文件格式 单文件,顺序解析 多文件,按文件名排序
Wi-Fi支持 需手动配置wpa_supplicant 需配合wpa_supplicant
热插拔支持 有限 原生支持
Yocto集成难度 低(默认支持) 中(需添加systemd和networkd)

我个人建议:新项目直接用systemd-networkd。虽然配置起来稍微复杂一点,但后期维护省心很多。特别是当你的设备需要支持USB网卡热插拔时,systemd-networkd的优势就体现出来了。

总结一下:Yocto的网络配置,核心就是选对工具、配好文件。内核驱动是基础,用户空间工具是手段,配置文件是最终落地的关键。这三者缺一不可。

知识体系结构图

下面这张图展示了本章的知识脉络,我手绘了一个SVG,方便你理解各个组件之间的关系:

Yocto网络架构知识体系 用户空间网络工具 busybox (ifconfig) iproute2 (ip命令) dhcp客户端 网络配置核心文件 /etc/network/interfaces /etc/systemd/network/*.network Linux内核网络栈 网络设备驱动 TCP/IP协议栈 套接字接口 物理硬件(以太网/Wi-Fi/4G模块) 配置管理 内核驱动 硬件抽象

这张图从下往上展示了Yocto网络的完整栈:硬件在最底层,内核网络栈在中间,配置管理层在上层,用户工具在最顶层。你配置网络时,其实就是从上往下操作——先用工具编辑配置文件,然后配置文件告诉内核怎么驱动硬件。

我的经验:遇到网络问题,先看硬件层(灯亮不亮),再看驱动层(dmesg有没有报错),然后看配置层(文件对不对),最后看工具层(命令能不能用)。按这个顺序排查,90%的问题都能快速定位。

可可精品资料库