1. RNDIS 协议概述

RNDIS(Remote Network Driver Interface Specification)是微软定义的一种基于 USB 的虚拟以太网协议,允许 USB 设备在主机端呈现为标准网络适配器。本章从规范定义、协议对比和主机原生支持三个维度展开,为后续性能优化建立基础认知。

RNDIS 在 USB Gadget 协议栈中的位置 USB 硬件层(UDC / 控制器) Linux USB Gadget 框架(udc-core / configfs / functionfs) USB 通信设备类(CDC)协议实现层 RNDIS 协议(本课程核心) RNDIS 封装 CDC 数据 通过 USB 批量传输 模拟以太网帧

1.1 RNDIS 规范定义

RNDIS 由微软在 Windows XP 时代提出,规范文档为 Microsoft RNDIS Specification v1.0。其核心设计思想是:将 USB 设备抽象为虚拟以太网适配器,主机端无需安装专用驱动即可识别并建立网络连接。

关键设计要点:

  • 消息驱动:RNDIS 使用控制消息(REMOTE_NDIS_*)进行设备初始化、状态查询和总线事件通知。
  • 数据封装:以太网帧被封装在 USB 批量传输(Bulk Transfer)的数据包中,每个 USB 数据包携带一个完整的 RNDIS 消息头。
  • 零拷贝支持:规范允许通过 USB 直接传递 DMA 缓冲区地址,减少数据搬运开销。
  • 多包聚合:支持将多个小以太网帧合并到一个 USB 传输请求块(URB)中,提升吞吐量。

RNDIS 消息分为三类:

消息类型 方向 用途 典型消息
控制消息 主机 ↔ 设备 初始化、查询、重置 REMOTE_NDIS_INITIALIZE_MSG / CMD
数据消息 主机 ↔ 设备 承载以太网帧 REMOTE_NDIS_PACKET_MSG
状态消息 设备 → 主机 链路状态、媒体连接变化 REMOTE_NDIS_INDICATE_STATUS_MSG

1.2 RNDIS 与 CDC ECM / EEM 的区别

USB-IF 定义的通信设备类(CDC)包含多种以太网控制模型。RNDIS 与 CDC ECM(Ethernet Control Model)、CDC EEM(Ethernet Emulation Model)是三种最常见的 USB 虚拟以太网协议。下表从多个维度进行对比:

对比维度 RNDIS CDC ECM CDC EEM
规范来源 微软(专有) USB-IF(开放标准) USB-IF(开放标准)
传输类型 批量传输(Bulk) 批量传输 + 中断端点 批量传输
消息头开销 8 字节(数据包) 0 字节(无额外头) 2 或 4 字节
多包聚合 原生支持 不支持 原生支持
主机驱动 Windows 内置;Linux/macOS 需额外驱动 Linux/macOS 原生;Windows 需第三方 Linux 原生;Windows/macOS 支持有限
性能上限 中等(受消息头开销影响) 高(无额外封装) 高(低开销 + 聚合)
适用场景 Windows 主机生态 Linux/macOS 主机生态 嵌入式设备间通信

实践建议:如果你的目标主机以 Windows 为主(如工业平板、医疗设备),RNDIS 是免驱首选;若主机为 Linux 或 macOS,优先考虑 CDC ECM 或 EEM 以获得更好的原生性能和更低的协议开销。

三种协议数据包封装对比 RNDIS RNDIS头 以太网帧(46~1514 字节) 8 字节消息头 + 以太网帧 CDC ECM 以太网帧(直接传输,无额外头) 0 字节额外开销,纯以太网帧 CDC EEM EEM头 以太网帧(46~1514 字节) 2/4 字节头 协议开销对比 RNDIS: 8 字节/包 CDC ECM: 0 字节/包 CDC EEM: 2~4 字节/包 小包场景下,ECM 性能最优 RNDIS 聚合后开销可分摊

1.3 主机端原生支持情况

不同操作系统对 RNDIS 的原生支持程度差异显著,直接影响驱动开发策略和部署成本。

Windows 主机

  • Windows XP / Vista / 7 / 8 / 10 / 11:内置 RNDIS 驱动(usb_rndis.sys),即插即用。
  • Windows CE / Embedded Compact:同样内置支持,广泛用于工业设备。
  • 驱动加载流程:设备枚举 → 匹配 USB 类代码(02h, 02h, FFh)→ 加载 usb_rndis.sys → 创建虚拟网卡。

Linux 主机

  • 内核主线:从 2.6.x 开始通过 rndis_host 驱动支持,需编译为模块或内置。
  • 常见发行版:Ubuntu/Debian/Fedora 默认包含,但部分嵌入式发行版可能裁剪。
  • 加载方式:自动匹配 USB 设备描述符中的 RNDIS 协议标识,或手动 modprobe rndis_host。

macOS 主机

  • 原生支持:macOS 从 10.6(Snow Leopard)开始内置 RNDIS 驱动(AppleRNDIS.kext)。
  • 限制:仅支持 64 位架构;Big Sur 之后需注意系统扩展(System Extension)签名要求。
  • 常见问题:部分第三方 USB 设备因描述符不标准导致驱动加载失败,需修改设备固件。

兼容性陷阱:RNDIS 规范要求设备在 USB 接口描述符中声明类代码为 02h(通信设备类)、子类 02h(抽象控制模型)、协议 FFh(厂商自定义)。部分设备错误使用 00h 或 E0h 类代码,导致 Windows 无法自动识别,需要手动安装 inf 文件。

各操作系统 RNDIS 驱动栈对比 Windows usb_rndis.sys NDIS 中间层 USB 总线驱动 硬件抽象层(HAL) Linux rndis_host.ko usbnet 框架 USB 核心(usbcore) HCI 驱动(ehci/xhci) macOS AppleRNDIS.kext IOKit 网络栈 USB 家族驱动 XHCI 控制器驱动 三系统均内置 RNDIS 驱动,但 Linux/macOS 需确保内核配置或系统扩展已启用

1.4 小结