问题描述
我正在编写一个使用 UEFI 启动的小型 x86-64 爱好操作系统。我目前正在为 Intel 的 xHC 编写驱动程序。我现在可以寻址 USB 设备并为每个设备的端点 0 分配一个传输环。然后我使用 GET_DESCRIPTOR 请求来获取每个设备的配置描述符。我要求 QEMU 模拟 USB 键盘和 USB 鼠标。因此,我得到了 2 个不同的描述符,如下所示:
user@user-System-Product-Name:~$ hexdump -C result.bin 00000000 09 02 22 00 01 01 06 a0 32 09 04 00 00 01 03 01 |..".....2.......| 00000010 02 00 09 21 01 00 00 01 22 34 00 07 05 81 03 04 |...!...."4......| 00000020 00 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00001000 09 02 22 00 01 01 08 a0 32 09 04 00 00 01 03 01 |..".....2.......| 00001010 01 00 09 21 11 01 00 01 22 3f 00 07 05 81 03 08 |...!...."?......| 00001020 00 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00001030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00002000
@H_502_5@基本上,我要求 GDB 输出 RAM 的内容,我将描述符放在文件 result.bin 中。然后我在控制台中十六进制转储 result.bin 的内容。这里可以先看到USB鼠标的配置。然后,1页后,USB键盘的配置。
鼠标的配置描述符是
09 02 22 00 01 01 06 a0 32
。紧随其后的是 2 个接口描述符:09 04 00 00 01 03 01 02 00
和09 21 01 00 00 01 22 34 00
。后面跟着一个端点描述符:07 05 81 03 08 00 07
。在鼠标和键盘的第一个接口描述符中,表示有一个端点描述符(由描述符的 bNumEndpoints 字段表示,该字段是从 0 开始索引的字节数 4)。我希望以下描述符是端点描述符。相反,我得到了第二个接口描述符(由它的长度为 9 个字节而不是 7 个字节以及不同字段的值来表示)。
如https://wiki.osdev.org/Universal_Serial_Bus所述:
每个CONfigURATION描述符至少有一个INTERFACE描述符,每个INTERFACE描述符最多可以有15个ENDPOINT描述符。当主机请求某个 CONfigURATION 描述符时,设备返回 CONfigURATION 描述符,紧接着是第一个 INTERFACE 描述符,紧接着是接口定义的端点的所有 ENDPOINT 描述符(可能没有)。如果存在,则紧跟其后是下一个接口描述符,然后是其端点描述符(如果适用)。这种模式一直持续到特定配置范围内的所有信息都传输完毕。
在我的例子中,为什么我会得到 2 个接口描述符,然后是端点描述符?这是一个 QEMU 错误还是我应该期待的?
解决方法
您没有准确描述我在您的 shell 输出中看到的二进制数据。
转储以类型 2 的 9 字节描述符开始,因此这是您的设备描述符:
09 02 22 00 01 01 06 a0 32
然后有一个类型为 4 的 9 字节描述符,因此它是一个接口,并且它的
bNumEndpoints
设置为 1:09 04 00 00 01 03 01 02 00
然后还有另一个 0x21 类型的 9 字节描述符。我脑子里没认出那个代码,但它可能是标准的:
09 21 01 00 00 01 22 34 00
然后我们有一个类型为 5 的 7 字节描述符,所以这是一个端点描述符:
07 05 81 03 04 00 07