Android usb client mass-storage不能自动挂载到主机端的问题(1)

测试平台:Nvidia ARM架构

操作系统:Andorid(Nvidia修改)

 

       最近在搞Android usb client,发现当将client线分别接上Android系统机器的client端以及主机Host端的时候,Android的USB client两大功能中的ADB可以使用,而mass-storage无法使用,即装有Android系统的机器不能将自己的sdhc卡,以及自身的内存卡挂到host主机端,并且显示。

       输入 ls -l /dev/sd*

       发现终端显示了个叫/dev/sdb 的节点,尝试mount ,提示 无法mount 未知的文件系统。

 

       Okay,查看Android系统端的init.rc发现 挂载方式是vold.

 

       查看vold原代码,发现需要读取vold.conf,并且检测UMS

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

       那么大致猜测下和问题有关的可能是Android系统的这么几个:

       1.rootfs  /etc/vold.conf配置可能有问题

       2.vold 的程序可能有问题

       3.linux driver  /driver/usb/gadget/f_mass_storage.c有问题

       4.UMS功能可能有问题

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

 

大致猜测了问题的所在,那么下一 步就是一步一步确认了。

1.先看看/etc/vold.conf文件,代码在/out/target/product/XX/system/etc/vold.conf

 

 

      volume_sdcard { media_path /devices/platform/tegra-sdhci.3/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p4 media_type mmc mount_point /sdcard } UMS的路径没有,个人经验:一般可以在/sys/devices/platform/ 下面找到一个叫包含"udc"字符的节点,进入它的子目录,会看到lun0的节点。 

进入/sys/devices/platform

这时候会有两种现象出现:1,就是有相应的节点;2,没有

1.如果有,则应该确定该节点是否和你的f_mass_storage驱动相对应,也就是说,这个节点是你的mass_storage驱动创建的,如果不是需要你去创建。

2.如果没有,那么需要在f_mass_storage.c里面去创建它。

 

我的情况是第一个,目录下有个叫shdc-udc.0/lun0的节点,但是并没有和我的g_android中的mass-storage驱动对应,所以我必须重新创建个。

在nvidia提供给我门的/arch/arm/mach-XXX/nvodm_board.c中会有一系列的device_register的动作

创建/sys/devices/platform下的节点 在这需要加入两句

static struct platform_device fsg_platform_device = { .name = "usb_mass_storage", .id = -1, }; static void __init tegra_machine_init(void) { .... (void) platform_device_register(&fsg_platform_device); .... } 加入这两句okay 

我们会发现/sys/devices/platform/usb_mass_storage/lun0这个目录产生了

这些动作是和你的linux driver中mass-storage的驱动内容相对应的。

最后一步,就是需要将新创建的UMS(负责启动usb mass-storage功能) Path加入到你的vold.conf中

volume_sdcard { media_path /devices/platform/tegra-sdhci.3/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p4 media_type mmc mount_point /sdcard ums_path /devices/platform/usb_mass_storage/lun0 //加的代码就是这个 } 

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

 

打开机器,灌入系统,启动,发现还是不行,在ADB终端中输入sdutil ums enabel 启动ums 实际上我机器已经在开机就启动了UMS功能

logcat显示UMS 挂掉了 一大堆的 堆栈问题 stack 什么的。

估计和内存分配或者指针有关。

估计是vold的代码有问题。

进入android源代码目录/system/core/vold

打开该目录下所有代码,加入打印语句,进行跟踪。

发现当你ums enable时候

1.会进入cmd_dispatch.c执行do_set_ums_enable函数

static int do_set_ums_enable(char *cmd) { ... if (!strcmp(cmd, VOLD_CMD_ENABLE_UMS)) return volmgr_enable_ums(true); return volmgr_enable_ums(false); } 

它又调用了volmgr.c文件中的volmgr_enable_ums(bool enable)

 

int volmgr_enable_ums(bool enable) { ... volume_t *v = vol_root //链表,链表中存储了每个存储设备的相关信息,如state. ums_path, mount_point这些来自于/etc/vold.conf while(v) { if(v->ums_path) if(enable){ ... volmgr_shutdown_volume(v, _cb_volstopped_for_ums_enable_false);//程序执行到这句话 挂掉了 ... } } } 

首先我们看看,程序是如何读取/etc/vold.conf配置信息并存储的

主要是这么几个函数volmgr_readconfig, volmgr_config_volume,等等,这里不详细讲,只是大概讲下,

首先 会建立一个大的链表,通过比配vold.conf中volume_XX来确定有多少成员 如volum_sdcard1 volum_sdcard2

表示有两个成员

然后,会在每个成员里在建一个链表,用于存储ums_path mount_point这些

最后再将这些东西重新在组织成个链表v。

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

继续上面的代码说

跟踪volmgr_shutdown_volume()--->volmgr_stop_volume()--->_cb_volstopped_for_ums_enable()

staitc void _cb_volstopped_for_ums_enable(volume_t *v, void *arg) { char* devdir_path ... devdir_path = blkdev_get_devpath(v->dev->disk);//挂了 ... } 

继续跟下去到blkdev.c

char *blkdev_get_devpath(blkdev_t *blk) { .... char *dp = malloc(256); sprintf(dp, "%s/vold/%d:%d", blk->major, blk->minor);//挂掉 } 经过调试 发现blk是空指针。 在看调用它的函数 _cb_volstopped_for_ums_enable 发现v->dev->disk空的指针  

继续返回跟踪 ,发现v->dev->disk始终是空

怪不得,马的又没作异常处理,草了

在其他地方 发现v->dev和v->dev->disk是相同类型,有的地方用v->dev->major,有的地方用v->dev->disk->major

看了 下没见到v->dev->disk的初始化,悲剧阿。。。

于是尝试将v->dev作形参传入,而不是v->dev->disk

发现okay.汗查看/dev/vold/下面的设备号 和v->dev->major:v->dev->minor打出来的一致。

当机器启动时,插入usb client cable.主机端可以自动挂载mass-storage。

 

 

Oh, yeah success! 

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

不知道为什么v->dev->disk是空的。正在继续看。。估计这几天应该能搞清除。

写的不好,也不怎么详细,只是自己一点调试的看法和经验希望能帮助自己和大家,谢谢

 

你可能感兴趣的:(android,struct,cmd,存储,Path,终端)