測試平台: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 {<br /> media_path /devices/platform/tegra-sdhci.3/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p4<br /> media_type mmc<br /> mount_point /sdcard<br />}<br />UMS的路徑沒有,個人經驗:一般可以在/sys/devices/platform/<br />下面找到一個叫包含"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 =<br />{<br />.name = "usb_mass_storage",<br />.id = -1,<br />};<br />static void __init tegra_machine_init(void)<br />{<br />....<br /> (void) platform_device_register(&fsg_platform_device);<br />....<br />}<br />加入這兩句okay
我們會發現/sys/devices/platform/usb_mass_storage/lun0這個目錄產生了
這些動作是和你的linux driver中mass-storage的驅動內容相對應的。
最後一步,就是需要將新建立的UMS(負責啟動usb mass-storage功能) Path加入到你的vold.conf中
volume_sdcard {<br /> media_path /devices/platform/tegra-sdhci.3/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p4<br /> media_type mmc<br /> mount_point /sdcard<br /> ums_path /devices/platform/usb_mass_storage/lun0<br />//加的代碼就是這個<br />}
===========================
開啟機器,灌入系統,啟動,發現還是不行,在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)<br />{<br /> ...<br /> if (!strcmp(cmd, VOLD_CMD_ENABLE_UMS))<br /> return volmgr_enable_ums(true);<br /> return volmgr_enable_ums(false);<br />}
它又調用了volmgr.c檔案中的volmgr_enable_ums(bool enable)
int volmgr_enable_ums(bool enable)<br />{<br /> ...<br /> volume_t *v = vol_root //鏈表,鏈表中儲存了每個存放裝置的相關資訊,如state. ums_path, mount_point這些來自於/etc/vold.conf<br /> while(v)<br /> {<br /> if(v->ums_path)<br /> if(enable){<br /> ...<br /> volmgr_shutdown_volume(v, _cb_volstopped_for_ums_enable_false);//程式執行到這句話 掛掉了<br /> ...<br /> }<br /> }<br />}
首先我們看看,程式是如何讀取/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)<br />{<br /> char* devdir_path<br /> ...<br /> devdir_path = blkdev_get_devpath(v->dev->disk);//掛了<br /> ...<br />}
繼續跟下去到blkdev.c
char *blkdev_get_devpath(blkdev_t *blk)<br />{<br /> ....<br /> char *dp = malloc(256);<br /> sprintf(dp, "%s/vold/%d:%d", blk->major, blk->minor);//掛掉<br />}<br />經過調試 發現blk是null 指標。<br />在看調用它的函數 _cb_volstopped_for_ums_enable<br />發現v->dev->disk空的指標<br />
繼續返回跟蹤 ,發現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是空的。正在繼續看。。估計這幾天應該能搞清除。
寫的不好,也不怎麼詳細,只是自己一點調試的看法和經驗希望能協助自己和大家,謝謝