【问题标题】:Why do I get 2 interface descriptors before the endpoint descriptor after a GET_DESCRIPTOR USB request on QEMU?为什么在 QEMU 上的 GET_DESCRIPTOR USB 请求之后,我会在端点描述符之前获得 2 个接口描述符?
【发布时间】:2021-09-28 05:00:52
【问题描述】:

我正在编写一个使用 UEFI 启动的小型 x86-64 爱好操作系统。我目前正在为英特尔的 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 的内容。然后我在控制台中十六进制转储 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 字段表示,它是从 0 开始索引的第 4 个字节)。我希望以下描述符是端点描述符。相反,我得到了第二个接口描述符(通过它的长度为 9 个字节而不是 7 个字节以及不同字段的值来表示)。

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

每个 CONFIGURATION 描述符至少有一个 INTERFACE 描述符,每个 INTERFACE 描述符最多可以有 15 个 ENDPOINT 描述符。当主机请求某个 CONFIGURATION 描述符时,设备返回 CONFIGURATION 描述符,紧接着是第一个 INTERFACE 描述符,紧接着是接口定义的端点的所有 ENDPOINT 描述符(可能没有)。如果存在,则紧随其后的是下一个 INTERFACE 描述符,然后是其 ENDPOINT 描述符(如果适用)。这种模式一直持续到特定配置范围内的所有信息都被传输为止。

在我的情况下,为什么我得到 2 个接口描述符,然后是端点描述符?这是一个 QEMU 错误还是我应该预料到的?

【问题讨论】:

    标签: usb x86-64 osdev hci


    【解决方案1】:

    您没有准确描述我在您的 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
    

    【讨论】:

    • 是的,这就是问题所在。接口描述符后面应该跟端点描述符(它在 bNumEndpoints 字段中声明的端点)。相反,它后面是另一个本身不是端点的描述符。即使不一定是接口描述符,它也肯定不是端点描述符。它带来了一个问题:那个描述符在那里做什么?
    • 请注意,正如您在问题中所说,您 没有 获得两个接口描述符。您将获得一个接口描述符和一个关于该接口的未识别描述符。
    • 您感到困惑的描述符称为“HID 类描述符”或“HID 描述符”。该结构在HID 1.11 的“HID Descriptor”部分中定义,常量 0x21 是在同一文档的“Standard Requests”部分中定义的。 (至少我是这么认为的,在找了几分钟之后。)
    • 好的,非常感谢,我最终会看看这一切。
    • 为什么在osdev.org上说接口描述符后面紧跟端点描述符?我还是不明白。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 1970-01-01
    • 2015-09-14
    • 2014-06-24
    相关资源
    最近更新 更多