Androidadb驱动实现原理
2017-07-23 18:36
92 查看
Androidadb的驱动由androidadb.c和f_adb.c实现,androidadb.c的开头会
这里涉及到Linux USB Composite Framework的知识,下次再整理一下这方面的知识。
创建
Androidadb属于USB复合设备,注册这样的设备需要使用到USB Composite Framework,因此首先必须要创建一个
在
其中
functions_show()/functions_store()
enable_show()/enable_store()
state_show()
当
在
接下来就会调用
在
这一步跟多数的
不清楚为啥androidadb不直接将configuration和usb function都初始化完毕和添加完毕,还要手动去做配置。
现在想想,因为Android usb支持很多function,都在
这里有可能选择多种function,使得驱动支持多种fucntion。但是至于要使用何种function,那么需要用户来选择,所以会提供
对应的驱动接口是
对应的驱动接口是
#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
相关文章推荐
- Android自动化测试初探(二): Hierarchyviewer 捕获Element的实现原理
- Android中悬浮窗口的实现原理和示例代码
- Android游戏开发之检测游戏碰撞的原理实现(九)
- android下实现framebuffer独占的原理
- Android游戏开发之检测游戏碰撞的原理实现(四)
- Android游戏开发之飞行射击类游戏原理实现(二十)
- android实现原理说明之一_application Intent Task Activity
- Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析(1)
- Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析(4)
- Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析
- Android中悬浮窗口的实现原理和示例代码
- Android 实现书籍翻页效果----原理篇
- Android 实现书籍翻页效果----原理篇
- Android游戏开发之飞行射击类游戏原理实现(十)
- Android中悬浮窗口的实现原理和示例代码
- Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析
- Android中悬浮窗口的实现原理和示例代码
- Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析(2)
- Android中悬浮窗口的实现原理和示例代码
- Android游戏开发之检测游戏碰撞的原理实现(九)