您的位置:首页 > 移动开发 > Android开发

Androidadb驱动实现原理

2017-07-23 18:36 92 查看
Androidadb的驱动由androidadb.c和f_adb.c实现,androidadb.c的开头会
#include “f_adb.c”
,最终编译出来的是g_androidadb.ko文件。

这里涉及到Linux USB Composite Framework的知识,下次再整理一下这方面的知识。

创建
struct usb_composite_driver

Androidadb属于USB复合设备,注册这样的设备需要使用到USB Composite Framework,因此首先必须要创建一个
struct usb_composite_driver
并调用
usb_composite_probe()
向USB Composte Framework注册驱动。

static struct usb_composite_driver android_usb_driver = {
.name       = "android_usb",
.dev        = &device_desc,
.strings    = dev_strings,
.bind = android_bind,
.unbind     = android_usb_unbind,
.max_speed  = USB_SPEED_HIGH,
};

static int __init init(void)
{
struct android_dev *dev;
int err;

android_class = class_create(THIS_MODULE, "android_usb");
if (IS_ERR(android_class))
return PTR_ERR(android_class);

dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;

dev->disable_depth = 1;
dev->functions = supported_functions;
INIT_LIST_HEAD(&dev->enabled_functions);
INIT_WORK(&dev->work, android_work);
mutex_init(&dev->mutex);

err = android_create_device(dev);
if (err) {
class_destroy(android_class);
kfree(dev);
return err;
}

_android_dev = dev;

/* Override composite driver functions */
composite_driver_template.setup = android_setup;
composite_driver_template.disconnect = android_disconnect;

return usb_composite_probe(&android_usb_driver);
}
module_init(init);


module_init(init)
中首先去创建一个名为”android_usb”的sys class。并且调用
android_create_device()
函数创建”android0”的设备,它的属性文件包括:

static struct device_attribute *android_usb_attributes[] = {
&dev_attr_idVendor,
&dev_attr_idProduct,
&dev_attr_bcdDevice,
&dev_attr_bDeviceClass,
&dev_attr_bDeviceSubClass,
&dev_attr_bDeviceProtocol,
&dev_attr_iManufacturer,
&dev_attr_iProduct,
&dev_attr_iSerial,
&dev_attr_functions,
&dev_attr_enable,
&dev_attr_state,
NULL
};


其中
dev_attr_functions/dev_attr_enable/dev_attr_state
三个属性都有对应的show和store函数,这些函数配置Androidadb或者在adbd应用程序中会去使用,通过这三个来添加functions和使能androidadb功能。

functions_show()/functions_store()

enable_show()/enable_store()

state_show()

#insmod g_androidadb.ko
之后,在
/sys/class/android_usb/android0/
或者
/sys/devices/virtual/android_usb/android0/
目录下就可以看到这些属性文件。

-rw-r--r-- 0        0              4096 2017-05-01 18:31 bDeviceClass
-rw-r--r-- 0        0             4096 2017-05-01 18:31 bDeviceProtocol
-rw-r--r-- 0        0          4096 2017-05-01 18:31 bDeviceSubClass
-rw-r--r-- 0        0              4096 2017-05-01 18:31 bcdDevice
-rw-r--r-- 0        0              4096 2017-05-01 18:31 enable
drwxr-xr-x 0        0                   2017-05-01 18:31 f_adb
-rw-r--r-- 0        0              4096 2017-05-01 18:31 functions
-rw-r--r-- 0        0              4096 2017-05-01 18:31 iManufacturer
-rw-r--r-- 0        0              4096 2017-05-01 18:31 iProduct
-rw-r--r-- 0        0              4096 2017-05-01 18:31 iSerial
-rw-r--r-- 0        0              4096 2017-05-01 18:31 idProduct
-rw-r--r-- 0        0              4096 2017-05-01 18:31 idVendor
drwxr-xr-x 0        0                   2017-05-01 18:31 power
-r--r--r-- 0        0              4096 2017-05-01 18:31 state
lrwxrwxrwx 0        0                   2017-05-01 18:31 subsystem -> ../../../../class/android_usb
-rw-r--r-- 0        0              4096 2017-05-01 18:31 uevent


在android_bind()中初始化android_usb_function

当调用
usb_composite_probe()
,最终会触发
android_bind()
函数的执行。

android_bind()
中首先调用
android_init_functions()
,传递进来的参数为
struct android_usb_function *supported_functions[]
,这里面定义了android usb所有的function,根据需要打开某些功能,这里只使用了 adb_function的功能。

static struct android_usb_function adb_function = {
.name       = "adb",
.enable     = adb_android_function_enable,
.disable    = adb_android_function_disable,
.init       = adb_function_init,
.cleanup    = adb_function_cleanup,
.bind_config    = adb_function_bind_config,
};

static struct android_usb_function *supported_functions[] = {
//&ffs_function,
&adb_function,
//&acm_function,
//&mtp_function,
//&ptp_function,
//&rndis_function,
//&mass_storage_function,
//&accessory_function,
//&audio_source_function,
NULL
};

static int android_init_functions(struct android_usb_function **functions,
struct usb_composite_dev *cdev)
{
......

for (; (f = *functions++); index++) {
f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name);
f->dev = device_create(android_class, dev->dev,
MKDEV(0, index), f, f->dev_name);
if (IS_ERR(f->dev)) {
pr_err("%s: Failed to create dev %s", __func__,
f->dev_name);
err = PTR_ERR(f->dev);
goto err_create;
}

......
}
return 0;

err_out:
device_destroy(android_class, f->dev->devt);
err_create:
kfree(f->dev_name);
return err;
}


android_init_functions()
函数中会为function创建一个名为 f_xxx的sys class,比如说这里用到的是adb的function,那么名字就为 f_adb。因此可以在
/sys/class/android_usb/android0/
看到f_adb的目录。

接下来就会调用
struct android_usb_function的.init()
函数,这里肯定是
adb_function_init()
函数,在这里面又会调用
adb_setup()
函数。这样代码就从androidadb.c调到f_adb.c了。

static int
adb_function_init(struct android_usb_function *f,
struct usb_composite_dev *cdev)
{

f->config = kzalloc(sizeof(struct adb_data), GFP_KERNEL);

if (!f->config)
return -ENOMEM;

return adb_setup();
}

if (f->init) {
err = f->init(f, cdev);
if (err) {
pr_err("%s: Failed to init %s", __func__,
f->name);
goto err_out;
}
}


adb_setup()

在这个函数里面,初始化了读写队列,并且调用
misc_register()
在 /dev 目录下创建了一个名为” android_adb”的设备节点,这个节点用于与应用空间的数据通信使用。当然,这里面肯定包含对于
/dev/android_adb
节点的write()和read()函数。

/* file operations for ADB device /dev/android_adb */
static const struct file_operations adb_fops = {
.owner = THIS_MODULE,
.read = adb_read,
.write = adb_write,
.open = adb_open,
.release = adb_release,
};
static struct miscdevice adb_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = adb_shortname,
.fops = &adb_fops,
};


android_bind()
初始化USB设备描述符并分配string ID

/* Allocate string descriptor numbers ... note that string
* contents can be overridden by the composite_dev glue.
*/
id = usb_string_id(cdev);

if (id < 0)
return id;
strings_dev[STRING_MANUFACTURER_IDX].id = id;
device_desc.iManufacturer = id;

id = usb_string_id(cdev);

if (id < 0)
return id;
strings_dev[STRING_PRODUCT_IDX].id = id;
device_desc.iProduct = id;

/* Default strings - should be updated by userspace */
strncpy(manufacturer_string, "Android", sizeof(manufacturer_string)-1);
strncpy(product_string, "Android", sizeof(product_string) - 1);
strncpy(serial_string, "0123456789ABCDEF", sizeof(serial_string) - 1);

id = usb_string_id(cdev);

if (id < 0)
return id;
strings_dev[STRING_SERIAL_IDX].id = id;
device_desc.iSerialNumber = id;


这一步跟多数的
struct usb_composite_driver
.bind()
所要做的工作一样,要去初始化USB设备描述符,不过此时的USB设备描述符还不是完整的。但是这里有一个很关键的地方就是没有初始化USB的configuration和为其添加usb function。正是因为这里没有做这项工作,所以当我们
#insmod g_androidadb.ko
的时候,此时androidadb还不是一个完整的USB设备,因为它还没有配置描述符和对应的usb function。所以还要通过 sys class中的属性文件做一些配置。

不清楚为啥androidadb不直接将configuration和usb function都初始化完毕和添加完毕,还要手动去做配置。

现在想想,因为Android usb支持很多function,都在
supported_functions[]
中明确的定义了。

static struct android_usb_function *supported_functions[] = {
//&ffs_function,
&adb_function,
//&acm_function,
//&mtp_function,
//&ptp_function,
//&rndis_function,
//&mass_storage_function,
//&accessory_function,
//&audio_source_function,
NULL
};


这里有可能选择多种function,使得驱动支持多种fucntion。但是至于要使用何种function,那么需要用户来选择,所以会提供
/sys/class/android_usb/android0/functions
接口让用户选择使用何种function,最后再使用
/sys/class/android_usb/android0/enable
使之与usb configuration绑定。此时这个USB设备的功能就已经明确下来了,可以正常的被枚举。

添加functions到list中

这一步需要用户手动配置,因为我们是使用adb的功能,因此需要输入以下命令:
#echo adb > /sys/class/android_usb/android0/functions


对应的驱动接口是
functions_store()
函数,这个函数的内容是先解析传进来的字符串,然后调用
android_enable_function()
,根据解析出来的字符串是否与之前

android_init_functions()
中设定的名字(也就是该驱动现在支持哪些function)是否有相匹配的,如果有,那么就将名字添加到enabled_list中。

static int android_enable_function(struct android_dev *dev, char *name)
{
struct android_usb_function **functions = dev->functions;
struct android_usb_function *f;
while ((f = *functions++)) {
if (!strcmp(name, f->name)) {
list_add_tail(&f->enabled_list,
&dev->enabled_functions);
return 0;
}
}
return -EINVAL;
}


使能androidadb

#echo 1 > /sys/class/android_usb/android0/enable


对应的驱动接口是
enable_store()
,在这个函数里面会去完善USB设备描述符,然后从enabled_list中找出与之对应的
struct android_usb_function
,并执行它的.enable()成员函数,这里当然是会去执行
adb_android_function_enable()
函数。注意,在
adb_android_function_enable()
函数中会去先执行一次
android_disable()
。执行完这一步还没绑定USB configuration和USB function。函数调用如下:

[  348.556864] [xxx-adb] in enable_store, line 561
[  348.561705] [xxx-adb] in adb_android_function_enable, line 278
[  348.567577] [xxx-adb] in android_disable, line 227
[  348.572379] [xxx-adb] in android_enable, line 215, disable_depth 2


if (enabled && !dev->enabled) {
/*
* Update values in composite driver's copy of
* device descriptor.
*/
cdev->desc.idVendor = device_desc.idVendor;
cdev->desc.idProduct = device_desc.idProduct;
cdev->desc.bcdDevice = device_desc.bcdDevice;
cdev->desc.bDeviceClass = device_desc.bDeviceClass;
cdev->desc.bDeviceSubClass = device_desc.bDeviceSubClass;
cdev->desc.bDeviceProtocol = device_desc.bDeviceProtocol;
list_for_each_entry(f, &dev->enabled_functions, enabled_list) {
if (f->enable)
f->enable(f);
}
android_enable(dev);
dev->enabled = true;
}

static void adb_android_function_enable(struct android_usb_function *f)
{
struct android_dev *dev = _android_dev;
struct adb_data *data = f->config;

data->enabled = true;

/* Disable the gadget until adbd is ready */
if (!data->opened)
android_disable(dev);
}


启动adbd进程

启动adbd进程,那么首先会去调用
adb_open()
,最终会调用
usb_add_config()
adb_bind_config()
函数将USB configuration和USB function绑定起来。此时,这个USB设备已经配置完整了,可以接受USB Host的枚举。

[  497.782451] adb_open
[  497.784725] [xxx-adb] in adb_open, line 366
[  497.788928] [xxx-adb] in adb_ready_callback, line 308
[  497.794358] [xxx-adb] in android_enable, line 215, disable_depth 1
[  497.800601] [xxx-adb] in android_enable, line 217, invoke usb_add_config()
[  497.807475] adb_bind_config
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: