VID:PID(Vendor 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 层的识别入口问题:
- 内核用它辅助匹配 设备驱动 或类驱动。
lsusb、udevadm、设备管理器等工具用它展示设备身份。- udev 规则 常用它给设备节点设置权限、命名、软链接或自动动作。
- 厂商工具常用它识别芯片处于正常模式、bootloader 模式、maskrom 模式或调试模式。
它不是设备序列号,也不一定唯一到单台设备。多台同型号 USB 设备通常会有相同 VID:PID。
核心对象
| 对象 | 含义 | 工程关注点 |
|---|---|---|
| VID | Vendor ID,USB-IF 分配或管理的厂商编号 | 标识厂商或 VID 持有者,不标识单台设备 |
| PID | Product ID,厂商在自己 VID 下定义的产品编号 | 同一厂商可为不同产品、固件模式或接口形态分配不同 PID |
| USB 设备描述符 | 设备枚举时返回的基础描述符 | idVendor 和 idProduct 字段就来自这里 |
| USB class | 设备或接口声明的功能类别 | 决定能否走通用类驱动,例如 USB HID、UVC |
| Serial Number string | 可选字符串描述符 | 才可能区分同型号的不同物理设备 |
lsusb | Linux 用户态枚举显示工具 | 常显示为 Bus xxx Device yyy: ID vvvv:pppp name |
核心机制
1. 设备把 VID/PID 写在描述符里
USB 设备固件或芯片 ROM 会在 device descriptor 中提供 idVendor 和 idProduct 字段。可以把关键字段简化成:
device_descriptor = {
idVendor: 0x2207,
idProduct: 0x0001,
bDeviceClass: ...,
iSerialNumber: ...
}idVendor 和 idProduct 是 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可以按idVendor、idProduct、接口号、序列号、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。