【CSDN 编者按】随着时间的推移,如今 Android 开发人员无需再通过 USB 驱动程序连接设备了,这具体是怎么做到的呢?
原文链接:https://fabiensanglard.net/android_windows_driver/index.html
未经允许,禁止转载!
作者 | FABIEN SANGLARD 译者 | 弯月
责编 | 夏萌出品 | CSDN(ID:CSDNnews)在 Android 平台出现的早期,使用 Linux 和 Mac OS X 的 Android 开发人员只需要一根 USB 线就可以连接他们的设备,而 Windows 用户则需要寻找并安装驱动程序,非常繁琐。而如今,我们不再需要驱动程序了,这究竟怎么回事?
USB 驱动程序 / OS 的基础知识当你将设备插入到 USB 端口时,操作系统需要加载其接口的驱动程序。为此,操作系统需要检查 USB 描述符的层次结构。
通常情况下,只需读取设备描述符的厂商 ID(VID)和产品 ID(PID),就足以确定应加载哪些驱动程序。三大主流操作系统内置了“默认”的设备类驱动程序,因此大多数 USB 设备都能够自动安装。举个例子,当连接 ErgoDox EZ 键盘时,Windows 会加载 hidusb.sys,而不需要用户安装驱动程序。如果 Windows 找不到内置的设备类驱动程序(或者有更好的匹配项),则会加载用户安装的驱动程序。例如,苹果 Magic Trackpad 也会获取 hidusb.sys,但如果安装了 Bingxing Wang 的驱动程序,那么 Windows 就会加载 AmtPtpDeviceUm.dll(支持右键单击和多指手势)。
找不到驱动程序如果找不到驱动程序,Linux 将加载 usbfs,这样用户空间程序也可以访问设备。Mac OS 也是如此,只不过使用的是 IOKit;而 Windows 会报错,即没有加载驱动程序,就无法访问 Android 设备。
Android 驱动程序为了说明在安装驱动程序时发生了什么,我们来看看 Google USB Driver 的“核心”文件:android_winusb.inf。
INF 文件指示:“当 VID=0x18D1 且 PID=0x4E11(即Google Nexus One)时,加载 winusb 驱动程序”。WinUSB 是什么?类似于 Linux 的 usbfs 和 Mac OS 的 IOKit,它是一种 USB 驱动程序,允许用户空间程序枚举接口,并在端点之间进行读/写。这就是 adb(Android 调试桥)用来与 Android 设备通信的方式。
为什么 Android 设备不再需要 Windows 驱动程序前面描述的方法有一个明显的缺陷。如果 Android 设备的 VID/PID 未列出,winusb 将不会加载。Windows 8 有一种比 INF 文件更好的方法来确定接口需要哪个驱动程序。它可以直接询问设备!当连接设备时,操作系统发出 String Descriptors 请求,索引为 0xEE。如果设备与微软操作系统描述符(MOD)兼容,则返回字符串 M\0S\0F\0T\01\000\0\0。在这种情况下,Windows 会请求扩展兼容 ID OS 特征描述符。我们可以使用 Pixel 6 上的 libusb 的 xusb 检查此描述符。
该设备已设置为启用媒体传输协议和开发者模式。此特征描述符会指示这两个接口需要哪个驱动程序:第一个接口使用 mtp.sys,第二个接口使用 winusb.sys。加载 winusb.sys 后,用户空间可执行文件(如 adb)就可以打开设备,声明接口,然后开始开发工作。不再需要驱动程序!
哪些设备支持微软的操作系统描述符我看了看我收藏的 Pixel 系列设备,似乎微软操作系统描述符支持始于 Pixel 2(2017年)和 Pixel 3a(2019年)之间(抱歉,我没有 Pixel 3 可以测试)。
扩展属性操作系统描述符Pixel 8 这类的新设备具有扩展属性操作系统特征描述符,包含 GUID、帮助页面、URL 甚至图标。