VID:PIDVendor ID and Product ID)是 USB 设备在 USB 枚举 阶段暴露的一组十六进制标识:VID 表示厂商,PID 表示该厂商定义的某类产品或模式。

例如 lsusb 输出里的 2207:0001 可以读作:

VID = 0x2207
PID = 0x0001

这里的 0x 表示十六进制。2207 不是十进制两千二百零七,而是 16 进制数;0001 也是以 16 进制显示的产品编号。

核心问题

主机插入一个 USB 设备时,最先面对的问题不是“这台设备是谁的资产”,而是“这是什么类型的 USB 外设,该用哪个驱动和权限策略处理它”。

VID:PID 解决的是 USB 层的识别入口问题:

  • 内核用它辅助匹配 设备驱动 或类驱动。
  • lsusbudevadm、设备管理器等工具用它展示设备身份。
  • udev 规则 常用它给设备节点设置权限、命名、软链接或自动动作。
  • 厂商工具常用它识别芯片处于正常模式、bootloader 模式、maskrom 模式或调试模式。

它不是设备序列号,也不一定唯一到单台设备。多台同型号 USB 设备通常会有相同 VID:PID。

核心对象

对象含义工程关注点
VIDVendor ID,USB-IF 分配或管理的厂商编号标识厂商或 VID 持有者,不标识单台设备
PIDProduct ID,厂商在自己 VID 下定义的产品编号同一厂商可为不同产品、固件模式或接口形态分配不同 PID
USB 设备描述符设备枚举时返回的基础描述符idVendoridProduct 字段就来自这里
USB class设备或接口声明的功能类别决定能否走通用类驱动,例如 USB HIDUVC
Serial Number string可选字符串描述符才可能区分同型号的不同物理设备
lsusbLinux 用户态枚举显示工具常显示为 Bus xxx Device yyy: ID vvvv:pppp name

核心机制

1. 设备把 VID/PID 写在描述符里

USB 设备固件或芯片 ROM 会在 device descriptor 中提供 idVendoridProduct 字段。可以把关键字段简化成:

device_descriptor = {
  idVendor:  0x2207,
  idProduct: 0x0001,
  bDeviceClass: ...,
  iSerialNumber: ...
}

idVendoridProduct 是 16-bit 无符号整数,常按 4 位十六进制显示。冒号 : 只是工具输出时的分隔符,不是 USB 报文里的运算符。

2. 主机枚举时读取描述符

一次简化的识别路径是:

device plugged in
  -> host resets USB port
  -> host assigns a temporary address
  -> host reads device descriptor
  -> kernel sees idVendor/idProduct/class/subclass/protocol
  -> driver core chooses a driver or leaves it for user space
  -> udev receives the event and applies rules

这一步说明了为什么 lsusb 能在设备刚插上时显示 VID:PID:主机不需要先加载厂商应用,只要设备能完成基础枚举,就能读到描述符。

3. VID/PID 与驱动匹配不是唯一规则

驱动匹配通常同时看多种信息:

  • 类驱动匹配:如果接口声明标准类,系统可以按 class/subclass/protocol 绑定通用驱动,例如 HID 或 UVC。
  • 厂商驱动匹配:如果设备使用私有协议,驱动可能显式声明支持某组 VID/PID。
  • 用户态规则匹配udev 可以按 idVendoridProduct、接口号、序列号、USB 路径等设置权限或软链接。

所以 VID:PID 是强识别信号,但不是全部身份模型。对于同型号多设备,通常还要结合序列号、USB 物理路径、接口号或业务层 SN 与 Device ID

工程用途

  • 写 USB 设备权限规则,例如让非 root 用户访问串口、HID、烧录工具或调试接口。
  • 判断设备处于哪个模式,例如正常应用固件、bootloader、recovery、maskrom。
  • 排查驱动绑定错误:同一个硬件暴露了预期外的 PID,可能意味着固件模式不对。
  • 给测试脚本做初步过滤:先按 VID/PID 找候选设备,再按 serial、接口或 topology 精确定位。
  • 在嵌入式 bring-up 中确认 USB device descriptor 是否按固件配置生效。

一个常见 udev 匹配片段是:

SUBSYSTEM=="usb", ATTR{idVendor}=="2207", ATTR{idProduct}=="0001", MODE="0660", GROUP="plugdev"

这里 ATTR{idVendor}ATTR{idProduct} 对应内核 sysfs 中暴露的字符串值,写规则时通常使用小写 4 位十六进制。

边界与常见坑

  • VID:PID 不是序列号:它通常只能说明“哪类设备”,不能说明“哪一台设备”。要区分同型号多台设备,优先看 serial、USB by-path 或业务层 ID。
  • PID 由厂商定义,不是全球语义0001 在不同 VID 下含义不同,不能脱离 VID 单独解释。
  • 同一硬件可能有多个 PID:ROM、bootloader、应用固件、DFU、调试模式可能暴露不同 PID。
  • 复合设备要看接口:一个物理 USB 设备可能同时暴露 HID、串口、UVC 等多个 interface,只看 VID:PID 不一定知道具体功能。
  • 类驱动可能不需要专门 VID/PID 表:标准 HID、UVC 设备常靠 class 信息绑定通用驱动。
  • 不要把 VID/PID 当安全边界:攻击者可以伪造 USB 描述符;权限、认证和固件信任不能只靠 VID/PID。

相关术语