我最近在调试Android系统的gadget功能,通过make menuconfig发现gadget是编译成module模式的。里面有很多可选项,其中有个Android的选项,其实就是提供ADB和Storage的功能的。

具体查看代码在/drivers/usb/gadget下,三个文件:android.c f_adb.c f_mass_storage.c

g_android.ko 是由这三个文件而来,其中android.c 依赖于f_adb.c 和f_mass_storage.c(这两个文件之间无依赖关系)

可以在android.c中的

static int __init android_bind_config(struct usb_configuration *c) { struct android_dev *dev = _android_dev; int ret; printk(KERN_DEBUG "android_bind_config/n"); ret = mass_storage_function_add(dev->cdev, c, dev->nluns); if (ret) return ret; return adb_function_add(dev->cdev, c); }

看到关系

============================================================

下面说说我的问题,

1.当我将Android编译成module模式,既g_android.ko时候,然后放入rootfs中手动加载,Okay, no problem!非常happy。但是,当我关闭adb进程,rmmod g_android的时候,出现死锁状态,打开代码进行查询,发现问题出现在

struct usb_request *req_get(struct adb_dev *dev, struct list_head *head, int DD) { unsigned long flags; struct usb_request *req; spin_lock_irqsave(&dev->lock, flags);//被锁了,郁闷 if (list_empty(head)) { req = 0; } else { req = list_first_entry(head, struct usb_request, list); list_del(&req->list); } spin_unlock_irqrestore(&dev->lock, flags); return req; }

一直死锁,通过打开kernel hacking中的spinlock debug发现 是自己把自己锁了,找阿找阿。。。。

看了下rmmod时候 函数调用过程当我rmmod的时候,首先会去执行__exit cleanup(void)中的usb_composite_unregister(&android_usb_driver)这句话中还调用composite.c中的函数 (不细说),反正最后会调到f_adb.c中的

adb_function_unbind(struct usb_configuration *c, struct usb_function *f)

看看这个函数

static void adb_function_unbind(struct usb_configuration *c, struct usb_function *f) { struct adb_dev *dev = func_to_dev(f); struct usb_request *req; spin_lock_irq(&dev->lock);//锁死你个req_get,谁叫我们共用一个dev->lock while ((req=req_get(dev, &dev->rx_idle,0)))//被所到死 { adb_request_free(req, dev->ep_out); } while ((req=req_get(dev, &dev->tx_idle,0))) { adb_request_free(req, dev->ep_in); } dev->online = 0; dev->error = 1; spin_unlock_irq(&dev->lock); misc_deregister(&adb_device); kfree(_adb_dev); _adb_dev = NULL; }

所以感觉 req_get代码中的spinlock有问题,没办法,只能写了个req_get_free_lock(不加锁)替代while循环中的req_get函数

rebuild 内核,Okay 卸载g_android.ko 没问题 哈哈。正当自己高兴的时候,发现乐极生悲了。。。

===========================================================

卸载完了g_android.ko 我再次insmod g_android.ko 挂了,不过不是kernel panic而是提示

"sysfs: duplicate filename 'usb_mass_storage' can not be created"

恩 这次出在f_mass_storage.c这个文件中,根据信息提示应该是没因为上次没卸载完全。没办法,在几个与insmod和rmmod的函数中加入打印信息。主要是mass_storage_function_add, fsg_function_bind,fsg_function_unbind三个函数,前两个是跟insmod有关,后者跟rmmod有关。

通过打印信息发现一个Android开发者的 小纰漏 导致的问题,就是在

int __init mass_storage_function_add(struct usb_composite_dev *cdev, struct usb_configuration *c, int nluns) { int rc; struct fsg_dev *fsg; printk(KERN_INFO "mass_storage_function_add/n"); rc = fsg_alloc(); if (rc) return rc; fsg = the_fsg; fsg->nluns = nluns; spin_lock_init(&fsg->lock); init_rwsem(&fsg->filesem); kref_init(&fsg->ref); init_completion(&fsg->thread_notifier); the_fsg->buf_size = BULK_BUFFER_SIZE; the_fsg->sdev.name = DRIVER_NAME; the_fsg->sdev.print_name = print_switch_name; the_fsg->sdev.print_state = print_switch_state; rc = switch_dev_register(&the_fsg->sdev);//卸载的时候没有swith_dev_unregister if (rc < 0) goto err_switch_dev_register; wake_lock_init(&the_fsg->wake_lock, WAKE_LOCK_SUSPEND, "usb_mass_storage"); fsg->cdev = cdev; fsg->function.name = shortname; fsg->function.descriptors = fs_function; fsg->function.bind = fsg_function_bind; fsg->function.unbind = fsg_function_unbind; fsg->function.setup = fsg_function_setup; fsg->function.set_alt = fsg_function_set_alt; fsg->function.disable = fsg_function_disable; rc = usb_add_function(c, &fsg->function); if (rc != 0) goto err_usb_add_function; return 0; err_usb_add_function: switch_dev_unregister(&the_fsg->sdev); err_switch_dev_register: kref_put(&the_fsg->ref, fsg_release); return rc; }

在掉用过/drivers/switch/class_switch.c 中的 switch_dev_register后,除了出错处理再也没作擦屁股的动作(unregister)汗,这不是占着XX不拉什么吗?没办法,去fsg_function_unbind函数中的

for (i = 0; i < fsg->nluns; ++i) { curlun = &fsg->luns[i]; if (curlun->registered) { switch_dev_unregister(&the_fsg->sdev);//加入擦屁股的一句 device_remove_file(&curlun->dev, &dev_attr_file); device_unregister(&curlun->dev); curlun->registered = 0; } }

Okay 万事Okay 主阿!其实都不是什么大的问题拉。但是导致的现象确很恐怖。android developer太忙了,毕竟也是人阿。呵呵,以前都不敢改他们代码,总是推敲自己是不是哪边错了。想报bug去android开发者论坛,但是被该死的河蟹给和谐了,打不开report issue界面。感谢伟大的政府让我们这些P民,成为白痴和弱智。

草泥马的 !

Android usb驱动模块 g_android.ko rmmod issues相关推荐

  1. Android USB Accessory分析

    转自:https://blog.csdn.net/yingzhao80/article/details/45511351 Android下USB Accessory的实现分析 摘要:本文介绍了USB ...

  2. Android USB驱动源码分析(-)

    Android USB驱动中,上层应用协议里最重要的一个文件是android/kernel/drivers/usb/gadget/android.c.这个文件实现USB的上层应用协议. 首先包含了一些 ...

  3. Android USB驱动源码分析

    Android USB驱动中,上层应用协议里最重要的一个文件是android/kernel/drivers/usb/gadget/android.c.这个文件实现USB的上层应用协议. 首先包含了一些 ...

  4. Android USB gadget

    Android USB驱动中,上层应用协议里最重要的一个文件是android/kernel/drivers/usb/gadget/android.c.这个文件实现USB的上层应用协议. 首先包含了一些 ...

  5. 基于AOA协议的android USB通信

    摘 要:AOA协议是Google公司推出的用于实现Android设备与外围设备之间USB通信的协议.该协议拓展了Android设备USB接口的功能,为基于Android系统的智能设备应用于数据采集和设 ...

  6. android挂载usb设备,android usb挂载分析---MountService启动

    在android usb挂载分析----vold启动,我们的vold模块已经启动了,通信的机制也已经建立起来了,接下来我们分析一下MountService的启动,也就是我们FrameWork层的启动, ...

  7. Android USB Host与HID通讯

    Android USB Host与HID通讯 (一) Android USB Host与HID通讯 (二) Android USB Host与HID通讯Demo android usb host 读写 ...

  8. Android USB转串口编程

    安卓手机的对外通信接口就只有USB跟音频口,我们可采用其进行与外设进行通信.今天,我们来讲讲安卓手机利用USB接口与外设进行通信.此时,有两种情况. 第一:USB(手机)<--->USB( ...

  9. Android USB 开发详解

    Android USB 开发详解 先附上 Android USB 官方文档 Android通过两种模式支持各种 USB 外设和 Android USB 附件(实现Android附件协议的硬件):USB ...

最新文章

  1. moia调度mysql到hive_创立打车软件Moia后,“不安分”的大众又收购一家移动支付公司PayByPhone...
  2. 判断是否是数组的方法
  3. 从0到1写RT-Thread内核——空闲线程与阻塞延时的实现
  4. git忽略某个文件夹
  5. es的分片数量和扩展性分析
  6. 菜鸟评python,F#,Go
  7. 05、应用程序数据操作(下)
  8. GBK字库集测试求助
  9. datax(27):不太常见配置项querySql、preSql、postSql、splitPk
  10. Kafka实战之整合Flume和Kafka完成实时数据采集
  11. jQuery图像照片剪裁插件Jcrop中文演示
  12. 以自动化为“遮羞布”,亚马逊掩盖了惊人的工伤记录
  13. c语言.jpg图片转成数组_电脑使用图片转换器打开heic图片方法
  14. 微信小程序入门与实战笔记
  15. 【Vue工程】001-Vite 创建 Vue-TypeScript 项目
  16. 【AWS+Drupal应用案例】如何让一个千万级流量网站从一直挂机到起死回生?
  17. 异常、信息国际化样例
  18. oracle中sql查询增加自增序列号
  19. 《Python深度学习》读书笔记:第1章 什么是深度学习
  20. 获取当前时间戳减去昨天的时间戳

热门文章

  1. 135编辑器元旦微信模板更新啦,赶快用起来吧!
  2. evo工具使用问题——Degenerate covariance rank, Umeyama alignment is not possible
  3. 【web3实践 | 以太坊开发框架Truffle使用】
  4. python练习题-基础巩固-第一周
  5. 杰理之播正弦波按键音及注意点2【篇】
  6. 小马哥--高仿红米note m8207主板 2015新版单卡4G 详细拆机主板图与开机识别图 主板摄像头出双排线
  7. 区分interupt()和 notify().
  8. windows 电脑笔记本相机突然变成了黑白色
  9. 10.CSS3弹性布局、响应式布局、PS
  10. Section与Segment间的区别