当前位置: 首页 > news >正文

记录一次USB虚拟网络问题排查

背景介绍

项目是用yocto构建的,在升级kernel及yocto后(见https://www.cnblogs.com/ma-yangbiao/p/19149251), 发现某些功能不能正常工作。

问题介绍

目标机是某个不常用的x86平台,该x86 盒子通过USB连接MDM9150, 在该x86盒子上跑某个应用程序过程中,发现没有像预期一样建立和初始化USB虚拟网口custom_usb0。

调试

由于qxdm log在该目标机上受限。加入一些文本打印,重新编译运行,进一步调试发现是因为我们一个管理网络的服务ioctl返回错误,这个ioctl是自己客制化的驱动代码里负责处理的,

于是把相关的驱动编译成模块然后手动加载进内核,其中现象如下

$ sudo insmod ./custom_usb.ko

insmod: ERROR: could not insert module custom_usb.ko: Unknown symbol in module

$ dmesg | tail

[ 183.497776] custom_usb: Unknown symbol usbnet_suspend (err -2)

[ 183.497778] custom_usb: Unknown symbol usbnet_start_xmit (err -2)

[ 183.497793] custom_usb: Unknown symbol usbnet_stop (err -2)

[ 183.497797] custom_usb: Unknown symbol usbnet_disconnect (err -2)

[ 183.497801] custom_usb: Unknown symbol usbnet_probe (err -2)

[ 183.497804] custom_usb: Unknown symbol usbnet_resume (err -2)

这几个符号都来自linux kernel 驱动代码,具体在kernel/drivers/net/usb/usbnet.c,由CONFIG_USB_USBNET决定是否编译,但是在我的自己的defconfig中CONFIG_USB_USBNET已经被显示设置为y了。

于是在我的defconfig把CONFIG_USB_USBNET=m,重新编译后待会手动加载看看是不是报错,

同时该文件中有几处打印用的netdev_dbg,为了方便调试有2种方法运行时看到打印信息,

把netdev_dgb改成netdev_warn

改CONFIG_DYNAMIC_DEBUG=y,这是为了打开编译时动态打印开关,运行时还需要打开运行时调试开关:echo 'file drivers/net/usb/usbnet.c +p' > /sys/kernel/debug/dynamic_debug/control,这样即使是netdev_dbg也能打印到dmesg

我选择方法1,

再次编译完执行insmod usbnet.ko发现没有错误,再手动insmod custom_usb.ko也没有错误.

说明代码没问题,回过头来在usbnet.c-> usbnet_init()里加一句打印 pr_err("usbnet_init called\n");

我的defconfig里再设置CONFIG_USB_USBNET=y,重新编译更新,再次重启发现没有这句打印, 也就是说这个usbnet压根没有自动加载。

于是检查最终的defconfig检查一下,发现最终的.config里CONFIG_USB_USBNET=m

经过检查我的kernel recipe .bbapend代码,有这么一段值得怀疑

do_preconfigure_prepend () {

cat ${WORKDIR}/custom/defconfig >> ${WORKDIR}/defconfig

}

如果我更新后,还有别的部分更新那就会覆盖我的配置。

于是尝试删除上述这三行,同时加入这2行,

SRC_URI += "file://custom/defconfig.cfg"

KERNEL_FEATURES += " custom/defconfig.cfg"

再次编译,查看.config.还是不起作用CONFIG_USB_USBNET=m.

阅读源码,Kconfig并没有提及CONFIG_USB_USBNET是否有依赖项,查看代码CONFIG_USB_USBNET实际是属于CONFIG_USB_NET_DRIVERS的一个子模块,所以尝试也配置

CONFIG_USB_NET_DRIVERS=y

CONFIG_DYNAMIC_DEBUG=y

再次编译,这次可以看到最终的.config里已经成功使能CONFIG_DYNAMIC_DEBUG=y了。说明kernel升级后这些配置项与旧版本里的配置不再一样。

再重新烧image,重新尝试,在解决了其它问题后功能终于正常。

总结

yocto 的内核配置流程是:从 BSP 提供的 defconfig 开始,按顺序合并 KERNEL_FEATURES 和 SRC_URI 中的 .cfg 片段, 运行 merge_config.sh + olddefconfig 生成最终 .config。

kernel升级,伴随的一些配置的依赖项可能会发生变化,需要仔细确认。比如在我们这个case里,CONFIG_USB_USBNET依赖发生了变化,旧kernel里并不依赖CONFIG_USB_NET_DRIVERS,但新kernel版本依赖它。

usbnet的功能

最后分享一下,这次debug过程中加深了对usbnet的功能的认识,

usbnet.c 是一个通用的 USB 网络驱动核心,定义了一个结构体 struct usbnet,它包含struct net_device, struct usb_interface等指针,就像胶水一样把usb操作与网络的操作net_device联系在一起

它实现了一个“USB 网络设备”的抽象:负责处理 USB 传输、数据包队列,以及与内核的 net_device 的集成交互。通过usb虚拟网口收发数据等通用逻辑放在这里。

它被许多小型驱动程序共享:例如 cdc_ether、asix、r8152、rmnet_usb 等都依赖于 usbnet 作为基础,这些特定厂商的驱动只需重写/写少量部分即可。它将通用逻辑与硬件特性分离:核心部分负责收发(TX/RX)管理等通用逻辑,而其它特定的驱动则通过重写钩子函数来实现设备特定的行为。

它还导出了一些辅助函数,供其他驱动调用。

最终效果是:当你插入一个 USB 网卡时,内核可以将其识别为 usb0;而通过少量的驱动特定代码,也可以显示为例如 rmnet_usb0 等。

具体解读

模块初始化/退出

usbnet_init():注册通用的 USB 驱动框架,准备好供子驱动调用。

usbnet_exit():注销驱动,释放资源。

设备探测与移除

usbnet_probe():当匹配的 USB 设备插入时调用,分配并初始化 struct usbnet 和 struct net_device。

usbnet_disconnect():设备拔出时清理资源。

网络设备操作

usbnet_open() / usbnet_stop():启动或停止接口,提交/取消接收 URB。

usbnet_start_xmit():把上层网络栈传下来的数据包封装成 URB,提交给 USB core。

usbnet_change_mtu()、usbnet_set_mac_address():常见的 net_device 操作。

数据收发路径

发送 (TX):start_xmit() → 构造 URB → usb_submit_urb() → 设备。

接收 (RX):URB 完成回调 → rx_complete() → 调用 netif_rx() 把包交给内核协议栈。

提供 rx_fixup() / tx_fixup() 钩子,供子驱动修正报文格式。

电源管理与错误恢复

处理 USB suspend/resume。提供 usbnet_tx_timeout() watchdog,避免传输卡死。

http://www.cnnetsun.cn/news/40608.html

相关文章:

  • 学Simulink——基于高比例可再生能源渗透的复杂电网建模场景实例:大规模光伏并网对区域电网频率稳定影响研究
  • CANN Samples(十九):特色场景:机器人 AI 绘画 手写识别等
  • 毕设开源 深度学习YOLO交通路面缺陷检测系统(源码+论文)
  • 【URP】Unity[后处理]色彩调整ColorAdjustments
  • Flutter混合开发与WebView集成实战
  • 压缩空气储能和释能阶段模型,附相关文档文献。 建立了压缩空气储能系统中的压缩机、换热器、储气罐...
  • Profinet转Modbus TCP工业数据采集网关:实现1200PLC 与打标卡数据实时传输
  • Flutter 2025 国际化与本地化实战:从多语言支持到文化适配,打造真正全球化的用户体验
  • P1178 到天宫做客 题解
  • 2025年GEO优化机会与争议以及规范发展的必要性
  • 2026老年春晚怀化区域节目征集启动仪式在怀化学院举行
  • 【笔记篇】【硬件基础篇】电力电子元器件应用手册 阅读笔记(1)电阻器及其应用
  • 柠檬 软件测试之python全栈自动化测试工程师第25期
  • 为什么你的视觉AI项目总是耗时又低效?Florence-2-large-ft一站式解决方案
  • 基于php的微信小程序的学习交流平台系统(源码+lw+部署文档+讲解等)
  • springboot高校读书分享系统的设计与实现_34ur7fyk-
  • 如何快速解锁RouterOS无限权限:MikroTikPatch的终极指南
  • 测试工程师的增值型职业休假策略:从技术深耕到跨界突破
  • USART串口
  • SDET职业生涯中的关键决策点与路径选择
  • 第三方API密集型聚合服务的测试体系构建
  • System Informer:你的Windows系统管家,3大核心功能深度解析
  • 探索城市脉搏:解密共享单车数据背后的故事
  • 如何用abogen构建高质量有声书生成系统:从单文件到批量处理的完整指南
  • FastText实战进阶:解锁文本处理的极致性能与多场景应用
  • 车载功能测试都要做什么?总结来了~
  • 终极指南:掌握CogVLM多模态大模型核心技术
  • 【毕业设计/课程设计】基于Python的热门微博数据可视化分析源码+论文+PPT+数据
  • 监控选购全攻略:6大场景首选品牌,海康威视/格行视精灵各有侧重,小米性价比,萤石更全能;格行视精灵AOV技术+终生免流真好用?
  • 5步掌握Three.js延迟渲染技术:从多光源卡顿到流畅渲染的终极指南