usb modeswitch hacks

在ubuntu上开发调试android时,有些Android手机在上ubuntu后无法使用adb,但在windows上是可以的,比如联想的a790e。

手机第一次通过usb连上ubuntu后,用lsusb输出如下:

usb modeswitch hacks_第1张图片

上面的VID 2006: PID 5014就是手机的设备id。

而在windows上面,adb interface可用,用设备管理器看到显示的设备ID却是 VID 2006: PID 5010:

usb modeswitch hacks_第2张图片

这其实是windows上面的特殊处理导致的。在windows上用adb shell打开文件系统看,会发现在手机的/system目录下有个叫cdrom.iso的文件,每次手机一插入windows的usb后,马上就会自动弹出这么一个对话框:

usb modeswitch hacks_第3张图片

是不是很像一个存储类设备如u盘插入usb了的情形?对的,手机插入usb后,首先是通知系统这是一个存储类设备,这在ubuntu下面通过lsusb -t可以证实:

usb modeswitch hacks_第4张图片

其class=stor应该就是表明设备属于storage类,usb-storage driver就是管理这个存储类usb设备的驱动。

也就是说,手机‘显示’地向系统report的接口总是存储类接口,表现在windows上面,就是手机一开始被当作一个usb cdrom drive,windows的热插拔(plug&play)服务等会导致mount上去的cdrom.iso文件里的autorun文件被执行,autorun又会执行一个change usb mode的win32程序,正是这个程序让手机里隐藏的adb调试接口(usb接口,即声明usb设备干啥用的一个‘句柄’)给暴露了出来。显然这一系列过程都是专为win32做的,厂商未提供linux上的方案的话,自然adb interface就无法在ubuntu上暴露了。不过linux世界也早有了usb_modeswitch工具来处理这种设备。在ubuntu上,通过apt-cache search usb-modewitch关键字可以找到相关的包安装。

usb_modeswitch不光是一个单独的程序,通过dpkg可以看到它有哪些重要部分

usb modeswitch hacks_第5张图片

/usr/sbin/目录下的两个都是独立的程序,/lib/udev/目录下同名的usb_modeswitch是一个bash脚本,在/etc/目录下还有usb_modeswitch.conf的配置文件。还有一个usb-modeswitch-data的数据包,包含了usb_modeswitch针对不同设备的配置数据库以及同热插拔服务udevd相关的配置文件等:

usb modeswitch hacks_第6张图片

那么对于一部未添加过到usb_modeswitch数据库的设备来说,该怎样enable它呢。这里拿联想a790e为例。

先用standalone的usb_modeswitch program手动测试该设备在接受什么参数的情况下可以转换mode。usb_modeswitch可以带-V [vendor_id] -P [mode_id]  --[mode_name]使用

usb modeswitch hacks_第7张图片

其中mode参数就是收集的已知涵盖大部分厂商的设备的mode switch code,比如--huawei-mode, --sony-mode, --gct-mode,如果匹配设备的mode code,就可以用lsusb看到变化,联想a790e手机就是在尝试到--sierra-mode时响应变化的。

接着要把这些知识作为usb_modeswitch的配置文件保存下来,在/etc/usb_modeswitch.d/目录下,创建名为2006:5014的文件,录入"SierraMode=1"即可。这个配置文件代替了手动为usb_modeswitch输入参数的作用。usb_modeswitch自己可以通过类似lsusb的内容匹配/etc/usb_modeswitch.d/下面的vendor_id和device_id,然后再为匹配的device file发送响应mode的code。

可这一切都是在单独执行standalone的程序情况下完成的,怎么在手机一插入usb口就可自动完成呢?udev派上用场了。每当有新的设备在内核中被创建时,相应的/sys系统文件会被创建,同时有相应的uevent被发送到用户空间。udevd监听uevent,然后匹配udevd的配置数据库,采取相应的动作。比如为新发现的内核文件创建一个方便的symlink,或者执行某个应用程序。这里的思路就是让udevd当发现联想a790e的device id后执行usb_modeswitch程序。

如果安装了前面提到的usb-modeswitch-data包,则在/lib/udevd/rules.d/目录下,可以发现已经有40-usb_modeswitch.rules的配置文件了,可以在这个文件的末尾,或者在/etc/udev/rules.d/目录下新创建一个同名的文件在里面加入

ACTION=="add", ATTRS{idVendor}=="2006", ATTRS{idProduct}=="5014", RUN+="usb_modeswitch '%b/%k'"

注意,这里RUN+=usb_modeswitch并不是直接执行的/sbin/目录下的usb_modeswitch二进制文件,而是/lib/udevd/目录下的一个叫usb_modeswitch的脚本,因为udevd规则里写的PROGRAM和RUN来执行程序都假设它的工作目录是/lib/udevd/目录。这个脚本最终会dispatch到/sbin/usb_modeswitch继而起到单独执行它的同样效果。

现在每次把手机插入ubuntu后,都可以发现2006:5010的adb调试接口出现了。

你可能感兴趣的:(usb modeswitch hacks)