为什么我在 QEMU 上的 GET_DESCRIPTOR USB 请求后在端点描述符之前得到 2 个接口描述符?

Why do I get 2 interface descriptors before the endpoint descriptor after a GET_DESCRIPTOR USB request on QEMU?

我正在写一个 x86-64 的小爱好 OS 我用 UEFI 启动。我目前正在为 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

基本上,我要求 GDB 输出我在文件 result.bin 中放置描述符的 RAM 的内容。然后我在控制台中 hexdump result.bin 的内容。这里首先可以看到USB鼠标的配置。然后,1页之后,USB键盘的配置。

鼠标的配置描述符是09 02 22 00 01 01 06 a0 32。它后面跟着 2 个接口描述符:09 04 00 00 01 03 01 02 0009 21 01 00 00 01 22 34 00。这些后面跟着一个端点描述符:07 05 81 03 08 00 07.

在鼠标和键盘的第一个接口描述符中,表明有一个端点描述符(由描述符的bNumEndpoints 字段指示,字节号为4,从0 开始索引)。我希望以下描述符是端点描述符。相反,我得到了第二个接口描述符(由它的长度为 9 个字节而不是 7 个字节以及不同字段的值表示)。

https://wiki.osdev.org/Universal_Serial_Bus 所述:

Each CONFIGURATION descriptor has at least one INTERFACE descriptor, and each INTERFACE descriptor may have up to 15 ENDPOINT descriptors. When the host requests a certain CONFIGURATION descriptor, the device returns the CONFIGURATION descriptor followed immediately by the first INTERFACE descriptor, followed immediately by all of the ENDPOINT descriptors for endpoints that the interface defines (which may be none). This is followed immediately by the next INTERFACE descriptor if one exists, and then by its ENDPOINT descriptors if applicable. This pattern continues until all the information within the scope of the specific configuration is transfered.

在我的例子中,为什么我得到 2 个接口描述符后跟端点描述符?它是 QEMU 错误还是我应该预料到的?

你没有准确描述我在你的 shell 输出中看到的二进制数据。

转储以类型 2 的 9 字节描述符开始,因此这是您的设备描述符:

09 02 22 00 01 01 06 a0 32

然后有一个9字节的类型4的描述符,所以这是一个接口,它bNumEndpoints设置为1:

09 04 00 00 01 03 01 02 00

然后还有一个9字节的0x21类型的描述符。我不认识那个代码,但它可能是标准的东西:

09 21 01 00 00 01 22 34 00

然后我们有一个类型为 5 的 7 字节描述符,所以这是一个端点描述符:

07 05 81 03 04 00 07