ADB on linux

Linux/Linux 일반 : 2018.12.28 10:16


출처 : https://android-review.googlesource.com/c/platform/system/core/+/31640


FunctionFS: initial implementation This is the second version of a patch which demonstrates the possibility of using adbd (Android Debug Bridge daemon) with a generic FunctionFS gadget instead of a custom adb usb gadget in the Linux kernel. It contains changes introduced after Benoit's review - thank you Benoit. The patch adds a replacement usb access layer to adbd: it adds a new layer as a copy of an existing usb_linux_client.c and introduces FunctionFS support proper on top of the copied layer. The former usb access method is still available, the method is chosen at compilation time by setting USE_USB_FUNCFS variable to false in adb's Android.mk in the section dedicated to adbd. How to use on the target device: $ insmod g_ffs.ko idVendor=<vendor ID> iSerialNumber=<some string> $ mount -t functionfs adb /dev/usbgadget/adb -o uid=2000,gid=2000 $ ./adbd The Linux kernel 3.2 release's drivers/usb/gadget/composite.c contains module parameter definitions for idVendor and iSerialNumber and was verified to work. "adb devices" issued on host will list <some string> as the device name. In case adbd does not switch its identity to uid=2000,gid=2000, respective




아래 두 파일의 sys.usb.configfs 부분을 참고하세요

/system/core/rootdir/init.usb.configfs.rc /system/core/rootdir/init.usb.rc



출처 :https://wiki.tizen.org/USB/Linux_USB_Layers/Configfs_Composite_Gadget/Usage_eq._to_g_ffs.ko

Owner

  • Andrzej Pietrasiewicz <andrzej.p (at) samsung.com> (KERNEL)

Code change log

v4..v5:

- don't take ffs_lock explicitly in g_ffs - simplify gfs_init, bugfix not decrementing the "i" in error recovery

v3..v4:

- small fixes after Michal's review, thank you, Michal! - export ffs_lock instead of ffs_dev_lock and ffs_dev_unlock, which are now static inline - improved ffs_find_dev, ffs_alloc_dev by introducing ffs_get_single_dev() - rearranged kfree invocations in ffs_free_dev - eliminated goto in ffs_acquire_dev - used explicit decrementation in gfs_init - removed some add/remove empty line hunks

v2..v3:

- a number of fixes regarding systems with multiple udcs, e.g. systems, where more than one gadget can be loaded at a time - cleanup of ffs devices handling: since they need to be registered by both g_ffs and configfs-based gadget, they need to be managed in one place; instead of static callbacks in f_fs.c now each device can have its own set of callbacks - callbacks are used by the g_ffs, while configfs-based gadget is happy with generic ffs_acquire/release_dev(), ffs_ready/closed() - functionfs_init() and functionfs_cleanup() now called when the first device is created and when the last is removed, respectively - removed gfs_lock from g_ffs in favor of a lock in f_fs.c protecting the devices list - thanks to all the above the ffs_alloc_inst() is greatly simplified compared to v2 - simplified the way how usb_f_fs user's (g_ffs's) refcount is maintained (no ffs_owner static in f_fs.c) - some of patches 12..16 used to contain Michal's Acked-by, but since there have been (relatively) many changes to those patches, I removed the Acked-by lines

v1..v2:

- fixes after Michal's review, thank you, Michal!

- removal of unnecessary hunks, simplified VLAIS replacement code, used proper pointer dereferencing, simplified ffs_do_functionfs_bind(),

ffs_alloc_inst() and ffs_free(), style corrections, allocated usb_function structures in one chunk for all configs in g_ffs

Rebased onto Felipe's master.

At the moment I don't have any public git repo at hand, so a branch 'usb-gadget-configfs' will be available later at

Guide

This series aims at integrating configfs into FunctionFS, the way it has been done for acm, ncm, ecm, eem, ecm subset, rndis, obex, phonet

and mass_storage. It contains everything that is required to provide the equivalent of g_ffs.ko with configfs.

Configfs support in FunctionFS has been awaited by the Android folks as discussed during the LPC 2013.

Apart from that a VLAIS (variable length array in a struct) patch is added. It is not strictly necessary, but it won't hurt and it

will make the Clang people happy.


FunctionFS is more complicated than most other USB functions, so the resulting patch series is a bit long. Howerver, it is supposed to do things in steps.

1) preliminary work: extend generic configfs support in USB gadget, convert g_ffs to new function interfaces of f_ecm, f_subset, f_rndis; g_ffs is the

last user of the old interfaces so remove compatibility layers

2) factoring out a u_fs.h header and finally making f_fs a separate module with both old and new function interface

3) converting all users of f_fs (in fact only g_ffs) to the new interface and remove compatiblilty layer

4) add configfs support

A branch 'usb-gadget-configfs' is available at

git://git.linaro.org/people/mszyprowski/linux-srpol.git



BACKWARD COMPATIBILITY

Please note that the old g_ffs.ko is still available and works.

USING THE NEW "GADGET"

Please refer to this post:

http://www.spinics.net/lists/linux-usb/msg76388.html

for general information from Sebastian on how to use configfs-based gadgets (*).

With configfs the procedure is as follows, compared to the information mentioned above (*):

instead of mkdir functions/acm.ttyS1 do

mkdir functions/ffs.<instance name>

e.g. mkdir functions/ffs.ptp

In functions/<function>.<instance name> there will be no attribute files at all, because all parameters are passed with FunctionFS.

An example gadget with adb and ptp functions:

(I assume there are ptpd and adbd daemons using FunctionFS available, a proof-of-concept adbd can be found here:

https://android-review.googlesource.com/#/c/31640/,

an early version of ptp which I used is here:

http://www.spinics.net/lists/linux-usb/msg41963.html)

$ modprobe libcomposite

$ mount none cfg -t configfs

$ mkdir cfg/usb_gadget/g1
$ cd cfg/usb_gadget/g1
 
$ mkdir configs/c.1
$ mkdir functions/ffs.adb
$ mkdir functions/ffs.ptp

$ mkdir strings/0x409
$ mkdir configs/c.1/strings/0x409

$ echo 0x2d01 > idProduct
$ echo 0x04e8 > idVendor

$ echo my-serial-num > strings/0x409/serialnumber
$ echo my-manufacturer > strings/0x409/manufacturer
$ echo "FunctionFS gadget (ptp, adb)" > strings/0x409/product

$ echo "Conf 1" > configs/c.1/strings/0x409/configuration
$ echo 120 > configs/c.1/MaxPower
$ ln -s functions/ffs.ptp configs/c.1
$ ln -s functions/ffs.adb configs/c.1

$ mkdir /dev/usbffs
$ mount ptp /dev/usbffs -t functionfs
$ ptpd

$ mkdir -p /dev/usbgadget/adb
$ mount -t functionfs adb /dev/usbgadget/adb -o uid=2000,gid=2000
$ adbd

$ echo s3c-hsotg > cfg/usb_gadget/g1/UDC

After unbinding the gadget with

 
echo "" > UDC 

the symbolic links in the configuration directory can be removed, the strings/* subdirectories in the configuration directory can

be removed, the strings/* subdirectories at the gadget level can be removed and the configs/* subdirectories can be removed.

The functions/* subdirectories can be removed. After that the gadget directory can be removed.

Daemons need to be closed and then the respective modules can be unloaded.


TESTING THE FUNCTIONS

FunctionFS)

device: connect the gadget, enable it host: mount the ptp device, adb shell


출처 : https://www.kernel.org/doc/Documentation/usb/functionfs.txt


*How FunctionFS works*

From kernel point of view it is just a composite function with some
unique behaviour.  It may be added to an USB configuration only after
the user space driver has registered by writing descriptors and
strings (the user space program has to provide the same information
that kernel level composite functions provide when they are added to
the configuration).

This in particular means that the composite initialisation functions
may not be in init section (ie. may not use the __init tag).

From user space point of view it is a file system which when
mounted provides an "ep0" file.  User space driver need to
write descriptors and strings to that file.  It does not need
to worry about endpoints, interfaces or strings numbers but
simply provide descriptors such as if the function was the
only one (endpoints and strings numbers starting from one and
interface numbers starting from zero).  The FunctionFS changes
them as needed also handling situation when numbers differ in
different configurations.

When descriptors and strings are written "ep#" files appear
(one for each declared endpoint) which handle communication on
a single endpoint.  Again, FunctionFS takes care of the real
numbers and changing of the configuration (which means that
"ep1" file may be really mapped to (say) endpoint 3 (and when
configuration changes to (say) endpoint 2)).  "ep0" is used
for receiving events and handling setup requests.

When all files are closed the function disables itself.

What I also want to mention is that the FunctionFS is designed in such
a way that it is possible to mount it several times so in the end
a gadget could use several FunctionFS functions. The idea is that
each FunctionFS instance is identified by the device name used
when mounting.

One can imagine a gadget that has an Ethernet, MTP and HID interfaces
where the last two are implemented via FunctionFS.  On user space
level it would look like this:

$ insmod g_ffs.ko idVendor=<ID> iSerialNumber=<string> functions=mtp,hid
$ mkdir /dev/ffs-mtp && mount -t functionfs mtp /dev/ffs-mtp
$ ( cd /dev/ffs-mtp && mtp-daemon ) &
$ mkdir /dev/ffs-hid && mount -t functionfs hid /dev/ffs-hid
$ ( cd /dev/ffs-hid && hid-daemon ) &

On kernel level the gadget checks ffs_data->dev_name to identify
whether it's FunctionFS designed for MTP ("mtp") or HID ("hid").

If no "functions" module parameters is supplied, the driver accepts
just one function with any name.

When "functions" module parameter is supplied, only functions
with listed names are accepted. In particular, if the "functions"
parameter's value is just a one-element list, then the behaviour
is similar to when there is no "functions" at all; however,
only a function with the specified name is accepted.

The gadget is registered only after all the declared function
filesystems have been mounted and USB descriptors of all functions
have been written to their ep0's.

Conversely, the gadget is unregistered after the first USB function
closes its endpoints.


출처 :https://github.com/rockchip-linux/linux-adb/blob/master/run_adbd.sh


#! /bin/sh
UDC=`ls /sys/class/udc/| awk '{print $1}'`
mkdir /dev/usb-ffs -m 0770
mkdir /dev/usb-ffs/adb -m 0770
mkdir /sys/kernel/config/usb_gadget/g1 -m 0770
sleep 1
echo 0x2207 > /sys/kernel/config/usb_gadget/g1/idVendor
echo 0x0006 > /sys/kernel/config/usb_gadget/g1/idProduct
mkdir /sys/kernel/config/usb_gadget/g1/strings/0x409 -m 0770
sleep 1
echo "0123456789ABCDEF" > /sys/kernel/config/usb_gadget/g1/strings/0x409/serialnumber
echo "rockchip" > /sys/kernel/config/usb_gadget/g1/strings/0x409/manufacturer
echo "rk3xxx" > /sys/kernel/config/usb_gadget/g1/strings/0x409/product
sleep 1
mkdir /sys/kernel/config/usb_gadget/g1/functions/ffs.adb
mkdir /sys/kernel/config/usb_gadget/g1/configs/b.1 -m 0770
mkdir /sys/kernel/config/usb_gadget/g1/configs/b.1/strings/0x409 -m 0770
sleep 1
ln -s /sys/kernel/config/usb_gadget/g1/functions/ffs.adb /sys/kernel/config/usb_gadget/g1/configs/b.1
echo "adb" > /sys/kernel/config/usb_gadget/g1/configs/b.1/strings/0x409/configuration
mount -t functionfs adb /dev/usb-ffs/adb
adbd &


출처 :
https://github.com/tonyho/adbd-linux/blob/master/adb.sh

#!/bin/bash
#https://wiki.linaro.org/LMG/Kernel/AndroidConfigFSGadgets#ADB_gadget_configuration
modprobe g_ether
rmmod g_ether
sleep 1
#Mount ConfigFS and create Gadget
mount -t configfs none /config
mkdir -p /config/usb_gadget/g1
cd /config/usb_gadget/g1
#Set default Vendor and Product IDs for now
echo 0x18d1 > idVendor
echo 0x4E26 > idProduct
#Create English strings and add random deviceID
mkdir strings/0x409
echo 0123459876 > strings/0x409/serialnumber
#Update following if you want to
echo "Test" > strings/0x409/manufacturer
echo "Test" > strings/0x409/product
#Create gadget configuration
mkdir configs/c.1
mkdir configs/c.1/strings/0x409
echo "Conf 1" > configs/c.1/strings/0x409/configuration
echo 120 > configs/c.1/MaxPower
#Create Adb FunctionFS function
#And link it to the gadget configuration
#stop adbd
mkdir -p functions/ffs.adb
ln -s /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/c.1/ffs.adb
#Start adbd application
mkdir -p /dev/usb-ffs/adb
mount -o uid=2000,gid=2000 -t functionfs adb /dev/usb-ffs/adb
adbd &
#Enable the Gadget
#Replace "ci_hdrc.0" with your platform UDC driver as found in /sys/class/udc/
echo 'ci_hdrc.0' > /config/usb_gadget/g1/UDC
#echo "ci_hdrc.0" > /config/usb_gadget/g1/UDC



출처 :
https://wiki.linaro.org/LMG/Kernel/AndroidConfigFSGadgets

How to enable Android ConfigFS gadgets

  • The instructions to enabled MTP/PTP from command line did not work for me reliably on Marshmallow release or AOSP master snapshots. They work fine on Lollipop though.

Synopsis

  • Android moved to ConfigFS based USB gadgets for their newer (android-3.14+) kernels.
  • Following configurations are verified on IFC6410 running Lollipop (android-5.1.1) and AOSP master (as on 20-Jan-2016) with kernel 3.18 with software rendering (libGLES_android).

Kernel Configuration

  • Make sure your kernel has at least following ConfigFS USB gadget and Android configs enabled.

CONFIG_USB_CONFIGFS=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_MTP=y
CONFIG_USB_CONFIGFS_F_PTP=y
CONFIG_USB_CONFIGFS_UEVENT=y

Enable Android USB gadgets from UI

CHANGES FOR AOSP MASTER SNAPSHOT

  • AOSP has already checked in ConfigFS init scripts in system/core project and these scripts work out of the box. We just have to add minor ConfigFS initialization steps in init.${ro.hardware}.rc to set ConfigFS gadget and UDC driver related properties and mount ConfigFS usb gadgets.

init.${ro.hardware}.rc changes

on init
+    # Create mount-point for ConfigFS USB gadgets
+    # Add standard gadget entries
+    mount configfs none /config
+    mkdir /config/usb_gadget/g1 0770 shell shell
+    write /config/usb_gadget/g1/idVendor 0x18D1
+    write /config/usb_gadget/g1/idProduct 0x4E26
+    mkdir /config/usb_gadget/g1/strings/0x409 0770 shell shell
+    write /config/usb_gadget/g1/strings/0x409/serialnumber 0123459876
+    write /config/usb_gadget/g1/strings/0x409/manufacturer Qcom
+    write /config/usb_gadget/g1/strings/0x409/product IFC6410
+    mkdir /config/usb_gadget/g1/configs/b.1 0770 shell shell
+    mkdir /config/usb_gadget/g1/configs/b.1/strings/0x409 0770 shell shell
+    write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "Conf 1"
+    write /config/usb_gadget/g1/configs/b.1/MaxPower 120
+
+    # Create adb+ffs gadget function
+    mkdir /config/usb_gadget/g1/functions/ffs.adb 0770 shell shell
+    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
+
+    # Create MTP and PTP functions
+    mkdir /config/usb_gadget/g1/functions/mtp.gs0 0770 shell shell
+    mkdir /config/usb_gadget/g1/functions/ptp.gs1 0770 shell shell

on boot
+    setprop sys.usb.configfs 1
+    #Replace "ci_hdrc.0" with your platform UDC driver as found in /sys/class/udc/
+    setprop sys.usb.controller ci_hdrc.0

CHANGES FOR LOLLIPOP (ANDROID-5.1.1_R18)

  • Only ADB and MTP can be enabled at the moment from UI/Settings Application for lollipop. PTP works from command line but can not be enabled reliably from UI at the moment. So it is skipped for the time being.

init.rc changes

  • There is this minor ConfigFS change we have introduced in init.rc, wherein instead of starting adbd daemon directly we let "persist.sys.usb.config" property change trigger that for us. This "on property" trigger in "init.usb.rc" will take care of ConfigFS gadget configuration.

 # adbd on at boot in emulator
 on property:ro.kernel.qemu=1
-    start adbd
+    setprop persist.sys.usb.config adb

 service lmkd /system/bin/lmkd
     class core
  • Also evident from above init.rc change is that the system USB properties are not persistent across reboots if we are running in an emulator or using software graphics rendering. That means the system will always start with only adb enabled and you have to manully select MTP/PTP/RNDIS option from the Settings application to enable them.

init.usb.rc changes

  • This is how my init.usb.rc looked like at that time. Supported configurations are ADB only, MTP only, MTP+ADB.
  • You can probably come up with a better version yourself if you follow init.usb.configfs.rc script from AOSP master. Just saying :)

#
# USB configuration common for all android devices
#

on init
    # Create ConfigFS mount point for USB gadgets
    # Add standard gadget entries
    mount configfs none /config
    mkdir /config/usb_gadget/g1
    write /config/usb_gadget/g1/idVendor 0x18D1
    write /config/usb_gadget/g1/idProduct 0x4E26
    mkdir /config/usb_gadget/g1/strings/0x409
    write /config/usb_gadget/g1/strings/0x409/serialnumber 0123459876
    write /config/usb_gadget/g1/strings/0x409/manufacturer Qcom
    write /config/usb_gadget/g1/strings/0x409/product IFC6410
    mkdir /config/usb_gadget/g1/configs/c.1
    mkdir /config/usb_gadget/g1/configs/c.1/strings/0x409
    write /config/usb_gadget/g1/configs/c.1/strings/0x409/configuration "Conf 1"
    write /config/usb_gadget/g1/configs/c.1/MaxPower 120

    # Create adb+ffs gadget function
    mkdir /config/usb_gadget/g1/functions/ffs.adb
    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

# Used to disable USB when switching states
on property:sys.usb.config=none
    write /config/usb_gadget/g1/UDC ""
    stop adbd
    setprop sys.usb.state ${sys.usb.config}

# adb only gadget configuration
# This is the fallback configuration if the
# USB manager fails to set a standard configuration
on property:sys.usb.config=adb
    stop adbd
    symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/c.1/ffs.adb
    start adbd
    #Had to set this property early because userspace expect us to be done with state changes in 1 second.
    setprop sys.usb.state ${sys.usb.config}
    #Add this 2 second wait/delay to calm things down after adbd restart and before we enable UDC.
    wait /dev/socket/waiting
    #Replace "ci_hdrc.0" with your platform UDC driver as found in /sys/class/udc/
    write /config/usb_gadget/g1/UDC ci_hdrc.0

# MTP
on property:sys.usb.config=mtp
    rm /config/usb_gadget/g1/configs/c.1/ffs.adb
    mkdir /config/usb_gadget/g1/functions/mtp.mtp
    symlink /config/usb_gadget/g1/functions/mtp.mtp /config/usb_gadget/g1/configs/c.1/mtp.mtp
    #Replace "ci_hdrc.0" with your platform UDC driver as found in /sys/class/udc/
    write /config/usb_gadget/g1/UDC ci_hdrc.0
    setprop sys.usb.state ${sys.usb.config}

# MTP + ADB
on property:sys.usb.config=mtp,adb
    stop adbd
    symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/c.1/ffs.adb
    start adbd
    mkdir /config/usb_gadget/g1/functions/mtp.mtp
    symlink /config/usb_gadget/g1/functions/mtp.mtp /config/usb_gadget/g1/configs/c.1/mtp.mtp
    #Had to set this property early because userspace expect us to be done with state changes in 1 second.
    setprop sys.usb.state ${sys.usb.config}
    #Add this 2 second wait/delay to calm things down after adbd restart and before we enable UDC.
    wait /dev/socket/waiting
    #Replace "ci_hdrc.0" with your platform UDC driver as found in /sys/class/udc/
    write /config/usb_gadget/g1/UDC ci_hdrc.0

# Used to set USB configuration at boot and to switch the configuration
# when changing the default configuration
on property:persist.sys.usb.config=*
    setprop sys.usb.config ${persist.sys.usb.config}

Manual / Command line instructions (Works only for Lollipop at the moment)

ADB GADGET CONFIGURATION

  • Run following commands from Android shell as root.

#Mount ConfigFS and create Gadget
mount -t configfs none /config
mkdir /config/usb_gadget/g1
cd /config/usb_gadget/g1

#Set default Vendor and Product IDs for now
echo 0x18d1 > idVendor
echo 0x4E26 > idProduct

#Create English strings and add random deviceID
mkdir strings/0x409
echo 0123459876 > strings/0x409/serialnumber

#Update following if you want to
echo "Test" > strings/0x409/manufacturer
echo "Test" > strings/0x409/product

#Create gadget configuration
mkdir configs/c.1
mkdir configs/c.1/strings/0x409
echo "Conf 1" > configs/c.1/strings/0x409/configuration
echo 120 > configs/c.1/MaxPower

#Create Adb FunctionFS function
#And link it to the gadget configuration
stop adbd
mkdir functions/ffs.adb
ln -s /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/c.1/ffs.adb

#Start adbd application
mkdir -p /dev/usb-ffs/adb
mount -o uid=2000,gid=2000 -t functionfs adb /dev/usb-ffs/adb
start adbd

#Enable the Gadget
#Replace "ci_hdrc.0" with your platform UDC driver as found in /sys/class/udc/
echo "ci_hdrc.0" > /config/usb_gadget/g1/UDC

MTP GADGET CONFIGURATION

  • While ADB was straight forward. MTP is a bit tricky. We have to make sure that we set following properties in on init section of init.rc to notify userspace of USB state early enough before UsbDeviceManager service kicks in.

setprop persist.sys.usb.config mtp
setprop sys.usb.config mtp
setprop sys.usb.state mtp

If not set during on init, adb will be set as default and overwriting later won't help.

  • Run following commands from Android shell as root.

#Mount ConfigFS and create Gadget
mount -t configfs none /config
mkdir /config/usb_gadget/g1
cd /config/usb_gadget/g1

#Set default Vendor and Product IDs for now
echo 0x18d1 > idVendor
echo 0x4E26 > idProduct

#Create English strings and add random deviceID
mkdir strings/0x409
echo 0123459876 > strings/0x409/serialnumber

#Update following if you want to
echo "Test" > strings/0x409/manufacturer
echo "Test" > strings/0x409/product

#Create gadget configuration
mkdir configs/c.1
mkdir configs/c.1/strings/0x409
echo "Conf 1" > configs/c.1/strings/0x409/configuration
echo 120 > configs/c.1/MaxPower
  • Make sure we create MTP function and add (symlink) it in gadget configuration only when the Android boot is complete. You can check that by checking the status of sys.boot_completed property before running the following commands.

#Create MTP function, 
#And link it to the gadget configuration
mkdir /config/usb_gadget/g1/functions/mtp.mtp
ln -s /config/usb_gadget/g1/functions/mtp.mtp /config/usb_gadget/g1/configs/c.1/mtp.mtp

#Enable the Gadget
#Replace "ci_hdrc.0" with your platform UDC driver as found in /sys/class/udc/
echo "ci_hdrc.0" > /config/usb_gadget/g1/UDC

MTP + ADB GADGET CONFIGURATION

  • Like MTP config above make sure that we set following properties in on init section of init.rc to notify userspace of USB state early enough before UsbDeviceManager service kicks in.

setprop persist.sys.usb.config mtp,adb
setprop sys.usb.config mtp,adb
setprop sys.usb.state mtp,adb
  • Run following commands from Android shell as root.

#Mount ConfigFS and create Gadget
mount -t configfs none /config
mkdir /config/usb_gadget/g1
cd /config/usb_gadget/g1

#Set default Vendor and Product IDs for now
echo 0x18d1 > idVendor
echo 0x4E26 > idProduct

#Create English strings and add random deviceID
mkdir strings/0x409
echo 0123459876 > strings/0x409/serialnumber

#Update following if you want to
echo "Test" > strings/0x409/manufacturer
echo "Test" > strings/0x409/product

#Create gadget configuration
mkdir configs/c.1
mkdir configs/c.1/strings/0x409
echo "Conf 1" > configs/c.1/strings/0x409/configuration
echo 120 > configs/c.1/MaxPower

#Create Adb FunctionFS function
#And link it to the gadget configuration
stop adbd
mkdir functions/ffs.adb
ln -s /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/c.1/ffs.adb

#Start adbd application
mkdir -p /dev/usb-ffs/adb
mount -o uid=2000,gid=2000 -t functionfs adb /dev/usb-ffs/adb
start adbd
  • Make sure we create MTP function and add (symlink) it in gadget configuration only when the Android boot is complete. You can check that by checking the status of sys.boot_completed property before running the following commands.

#Create MTP function, 
#And link it to the gadget configuration
mkdir /config/usb_gadget/g1/functions/mtp.mtp
ln -s /config/usb_gadget/g1/functions/mtp.mtp /config/usb_gadget/g1/configs/c.1/mtp.mtp

#Enable the Gadget
#Replace "ci_hdrc.0" with your platform UDC driver as found in /sys/class/udc/
echo "ci_hdrc.0" > /config/usb_gadget/g1/UDC

PTP GADGET CONFIGURATION

  • Just like MTP, we have to make sure that we set following properties in on init section of init.rc to notify userspace of USB state early enough before UsbDeviceManager service kicks in.

setprop persist.sys.usb.config ptp
setprop sys.usb.config ptp
setprop sys.usb.state ptp

If not set during on init, adb will be set as default and overwriting later won't help.

  • Run following commands from Android shell as root.

#Mount ConfigFS and create Gadget
mount -t configfs none /config
mkdir /config/usb_gadget/g1
cd /config/usb_gadget/g1

#Set default Vendor and Product IDs for now
echo 0x18d1 > idVendor
echo 0x4E26 > idProduct

#Create English strings and add random deviceID
mkdir strings/0x409
echo 0123459876 > strings/0x409/serialnumber

#Update following if you want to
echo "Test" > strings/0x409/manufacturer
echo "Test" > strings/0x409/product

#Create gadget configuration
mkdir configs/c.1
mkdir configs/c.1/strings/0x409
echo "Conf 1" > configs/c.1/strings/0x409/configuration
echo 120 > configs/c.1/MaxPower
  • Make sure we create PTP function and add (symlink) it in gadget configuration only when the Android boot is complete. You can check that by checking the status of sys.boot_completed property before running the following commands.

#Create MTP and PTP function,
#And link it to the gadget configuration
#Android's PTP implementation piggyback on MTP function so make sure we have MTP function created beforehand.
mkdir /config/usb_gadget/g1/functions/mtp.mtp
mkdir /config/usb_gadget/g1/functions/ptp.ptp
ln -s /config/usb_gadget/g1/functions/ptp.ptp /config/usb_gadget/g1/configs/c.1/ptp.ptp

#Enable the Gadget
#Replace "ci_hdrc.0" with your platform UDC driver as found in /sys/class/udc/
echo "ci_hdrc.0" > /config/usb_gadget/g1/UDC

PTP + ADB GADGET CONFIGURATION

  • Like PTP config above make sure that we set following properties in on init section of init.rc to notify userspace of USB state early enough before UsbDeviceManager service kicks in.

setprop persist.sys.usb.config ptp,adb
setprop sys.usb.config ptp,adb
setprop sys.usb.state ptp,adb
  • Run following commands from Android shell as root.

#Mount ConfigFS and create Gadget
mount -t configfs none /config
mkdir /config/usb_gadget/g1
cd /config/usb_gadget/g1

#Set default Vendor and Product IDs for now
echo 0x18d1 > idVendor
echo 0x4E26 > idProduct

#Create English strings and add random deviceID
mkdir strings/0x409
echo 0123459876 > strings/0x409/serialnumber

#Update following if you want to
echo "Test" > strings/0x409/manufacturer
echo "Test" > strings/0x409/product

#Create gadget configuration
mkdir configs/c.1
mkdir configs/c.1/strings/0x409
echo "Conf 1" > configs/c.1/strings/0x409/configuration
echo 120 > configs/c.1/MaxPower
  • Make sure we create MTP function and add (symlink) it in gadget configuration only when the Android boot is complete. You can check that by checking the status of sys.boot_completed property before running the following commands.

  • Also for PTP + ADB gadget configuration make sure we add or symlink PTP function to the gadget configuration before we add ADB. Symlink order matters here. Not sure why.

#Create MTP and PTP function,
#And link it to the gadget configuration
#Android's PTP implementation piggyback on MTP function so make sure we have MTP function created beforehand.
mkdir /config/usb_gadget/g1/functions/mtp.mtp
mkdir /config/usb_gadget/g1/functions/ptp.ptp
ln -s /config/usb_gadget/g1/functions/ptp.ptp /config/usb_gadget/g1/configs/c.1/ptp.ptp

#Create Adb FunctionFS function
#And link it to the gadget configuration
stop adbd
mkdir functions/ffs.adb
ln -s /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/c.1/ffs.adb

#Start adbd application
mkdir -p /dev/usb-ffs/adb
mount -o uid=2000,gid=2000 -t functionfs adb /dev/usb-ffs/adb
start adbd

#Enable the Gadget
#Replace "ci_hdrc.0" with your platform UDC driver as found in /sys/class/udc/
echo "ci_hdrc.0" > /config/usb_gadget/g1/UDC

Known Issues

  • Android's MTP and PTP implementations are mutually exclusive so make sure we have only one of it linked to a configuration at a time from command line. Otherwise it opens up another set of crashes.
  • There are few corner cases where in kernel OOPs while trying out different set of MTP/PTP and ADB configurations in random order.
  • If you are running into waitForState() failures in logcat while doing USB state changes for lollipop then you might want to increase the transition timeout in waitForState() at frameworks/base/services/usb/java/com/android/server/usb/UsbDeviceManager.java.













Posted by Real_G