我正在编写一个小型 x86-64 业余爱好操作系统,我使用 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 输出 RAM 的内容,我将描述符放置在文件 result.bin 中。然后我在控制台中十六进制转储 result.bin 的内容。这里首先可以看到USB鼠标的配置。然后,一页后,USB键盘的配置。
鼠标的配置描述符为09 02 22 00 01 01 06 a0 32
。接下来是 2 个接口(interface)描述符: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
。
在鼠标和键盘的第一个接口(interface)描述符中,表明有一个端点描述符(由描述符的 bNumEndpoints 字段表示,该字段是从 0 开始索引的字节号 4)。我希望以下描述符是端点描述符。相反,我得到了第二个接口(interface)描述符(由它的长度为 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 个接口(interface)描述符,后跟端点描述符?这是 QEMU 错误还是我应该预料到的?
最佳答案
您没有准确描述我在 shell 输出中看到的二进制数据。
转储以类型 2 的 9 字节描述符开始,因此这是您的设备描述符:
09 02 22 00 01 01 06 a0 32
然后有一个类型 4 的 9 字节描述符,因此这是一个接口(interface),并且它的 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
关于usb - 为什么在 QEMU 上发出 GET_DESCRIPTOR USB 请求后,我会在端点描述符之前获得 2 个接口(interface)描述符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68458989/