ADB和MTP是Android基于USB实现的两个重要功能,极大地方便了用户在PC与Android设备之间的互操作,比如传输文件、安装应用、开发调试应用。
本文讲述如何在特定软硬件平台下支持Android ADB和MTP功能。
Android版本: KitKat 4.4.2
Linux内核版本: 3.10 (Vendor Kernel)
硬件平台: Atmel SAMA5D3 SoC
针对Linux内核的更改
Merge Android Linux内核USB Gadget驱动到处理器厂商Linux内核
Vendor Linux内核和Android Linux内核都是基于Mainline Linux内核进行开发的。芯片厂商和Google公司都会修改Linux内核代码以支持自己的硬件平台及Android系统。新添加的功能和支持在稳定后会重新合并到后续版本的Mainline Linux内核。
从内核版本3.3开始,Android Linux内核开始与Mainline Linux内核融合,但目前(本文使用的内核版本3.10)还是有一部分功能没有并入Mainline Linux内核,比如用于支持Android ADB, Mass Storage和MTP/PTP等功能的Android USB Gadget驱动。
如果要在某个芯片厂商的硬件平台上运行Android系统,并支持这些USB相关的功能,必须将Android Linux内核中的Android USB Gadget驱动并入Vendor Linux内核。有些处理器芯片厂商会提供支持Android的Linux 内核,如果要命名的话,可以称之为Vendor Android Linux内核,而如果我们所使用的硬件平台,厂商没有提供完整支持Android的Linux内核,Android平台开发者可以自己合并代码以添加支持。
可以在多个源找到Android Linux内核的源代码,本文使用github上的源:
https://github.com/android/kernel_common branch:android-3.10
从Android Linux内核获得Android USB Gadget驱动的补丁
受影响的文件
drivers/usb/gadget/Kconfig
drivers/usb/gadget/Makefile
drivers/usb/gadget/android.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/f_accessory.c
drivers/usb/gadget/f_audio_source.c
drivers/usb/gadget/f_fs.c
drivers/usb/gadget/f_mtp.c
drivers/usb/gadget/f_rndis.c
drivers/usb/gadget/rndis.c
drivers/usb/gadget/u_serial.c
drivers/usb/gadget/udc-core.c
include/linux/usb/f_accessory.h
include/linux/usb/f_mtp.h
include/uapi/linux/usb/f_accessory.h
include/uapi/linux/usb/f_mtp.h
使用gitformat-patch命令生成所需要的补丁(下面的命令并不是普遍适用的,只是一个参考,需要根据具体情况灵活变通)
git format-patch -n29 drivers/usb/gadget/ include/linux/usb/f_mtp.h include/linux/usb/f_accessory.h include/uapi/linux/usb/f_mtp.h include/uapi/linux/usb/f_accessory.h
得到如下补丁
0001-usb-gadget-Add-Android-Composite-Gadget-driver.patch
0002-usb-gadget-mtp-Add-MTP-PTP-function.patch
0003-usb-gadget-adb-Add-ADB-function.patch
0004-usb-gadget-accessory-Add-Android-Accessory-function.patch
0005-usb-gadget-adb-allow-freezing-in-adb_read.patch
0006-usb-gadget-adb-do-not-set-error-flag-when-dequeuing-.patch
0007-usb-gadget-adb-Only-enable-the-gadget-when-adbd-is-r.patch
0008-usb-gadget-composite-Fix-corruption-when-changing-co.patch
0009-usb-gadget-android-Fix-product-name.patch
0010-usb-gadget-android-Add-FunctionFS.patch
0011-usb-gadget-accessory-Fix-section-mismatch.patch
0012-usb-gadget-Fix-usb-string-id-allocation.patch
0013-USB-gadget-Add-ACCESSORY_SET_AUDIO_MODE-control-requ.patch
0014-USB-gadget-f_accessory-Add-support-for-HID-input-dev.patch
0015-USB-gadget-f_audio_source-New-gadget-driver-for-audi.patch
0016-usb-gadget-f_fs-Fix-enumeration-in-fullspeed-mode.patch
0017-usb-gadget-accessory-Fix-section-mismatch-again.patch
0018-usb-gadget-android-Fixes-and-hacks-to-make-android-u.patch
0019-HACK-usb-gadget-Fix-enumeration-on-boot.patch
0020-usb-gadget-Fix-android-gadget-driver-build.patch
0021-usb-gadget-android-Fixes-and-hacks-to-make-android-u.patch
0022-usb-gadget-android-move-init-to-late_initcall-for-no.patch
0023-usb-gadget-android-3.10-fixes.patch
0024-USB-remove-duplicate-out-endpoint-creation-in-MTP-mo.patch
0025-usb-gadget-android-Remove-device-if-probe-fails.patch
0026-usb-gadget-f_mtp-move-userspace-interface-to-uapi.patch
0027-usb-gadget-f_accessory-move-userspace-interface-to-u.patch
0028-fix-false-disconnect-due-to-a-signal-sent-to-the-rea.patch
0029-drivers-usb-gadget-64-bit-related-type-fixes.patch
应用补丁
将这些patches复制到Vendor Linux内核源代码根目录下,使用git am命令将这些patches应用到Vendor Linux内核
git am *.patch
内核配置
为了让内核支持USB ADB和MTP功能,在编译前还需要在内核配置中使能相应选项。
Kernel Configuration
> Device Drivers
> USB Support
> USB Gadget Support
> Android Composite Gadget
针对Android的更改
从内核版本3.8开始,adb功能的实现发生了变化,把它的实现从内核代码中移除,在用户空间借助usb的functionfs功能实现adb。
内核 commit history
commit de8cff675b3de92ad4bb18a69cfe19091e810f49
Author:Benoit Goby <benoit@android.com>
Date:Mon Nov 5 18:47:08 2012 -0800
usb: gadget: Fix android gadget driver build
Removed obsolete f_adb function
Change-Id:Idfb4110429bc0ea63f493c68ad667f49ca471987
Signed-off-by: Benoit Goby<benoit@android.com>
android commit history
system/core
commitfd96db17b7f07eb6615af01fd1908b74383bf04b
Author:Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Date:Fri Jan 13 15:13:46 2012 +0100
FunctionFS: initial implementation
This is the second version of a patch whichdemonstrates the possibility
of using adbd (Android Debug Bridge daemon)with a generic FunctionFS gadget
instead of a custom adb usb gadget in theLinux kernel. It contains changes
introduced after Benoit‘s review - thank youBenoit.
The patch adds a new usb access layer toadbd using FunctionFS. The former
usb access method is still available. Themethod is chosen at runtime
depending if /dev/usb-ffs/adb/ep0 or/dev/android_adb is accessible.
How to use on the target device:
$ insmod g_ffs.ko idVendor=<vendor ID>iSerialNumber=<some string>
$ mount -t functionfs adb /dev/usb-ffs/adb-o uid=2000,gid=2000
$ ./adbd
This patch requires a patch to bionic whichadds <linux/usb_functionfs.h>
which is an exact copy of the relevant filein the linux kernel.
Change-Id:I4b42eb267ffa50fca7a5fba46f388a2f083e8b2d
Signed-off-by: Andrzej Pietrasiewicz<andrzej.p@samsung.com>
Signed-off-by: Kyungmin Park<kyungmin.park@samsung.com>
[benoit@android.com: detect at runtime iffunctionfs is mounted
or fallback using f_adb]
Signed-off-by: Benoit Goby<benoit@android.com>
为了使能adb功能,还需要在usb启动配置脚本中挂载usb functionfs文件系统
当前目录:<Android源代码根目录>/device/atmel
补丁如下:
diff--git a/sama5d3/init.sama5-ek.usb.rc b/sama5d3/init.sama5-ek.usb.rc
index80a2efa..be101e8 100644
---a/sama5d3/init.sama5-ek.usb.rc
+++b/sama5d3/init.sama5-ek.usb.rc
@@-1,3 +1,9 @@
+onfs
+mkdir /dev/usb-ffs 0770 shell shell
+mkdir /dev/usb-ffs/adb 0770 shell shell
+mount functionfs adb /dev/usb-ffs/adb uid=2000,gid=2000
+write /sys/class/android_usb/android0/f_ffs/aliases adb
+
on property:sys.usb.config=mtp,adb
write /sys/class/android_usb/android0/enable0
write/sys/class/android_usb/android0/idVendor 03EB