Android SDCard Mount 流程分析(一)
點(diǎn)擊打開(kāi)鏈接
前段時(shí)間對(duì)Android 的SDCard unmount 流程進(jìn)行了幾篇簡(jiǎn)短的分析,由于當(dāng)時(shí)只是紙上談兵,沒(méi)有實(shí)際上的跟進(jìn),可能會(huì)有一些誤導(dǎo)人或者小錯(cuò)誤。今天重新梳理了頭緒,針對(duì)mount的流程再重新分析一次。
?本篇大綱
- android 系統(tǒng)如何開(kāi)機(jī)啟動(dòng)監(jiān)聽(tīng)mount服務(wù)
- 默認(rèn)設(shè)備節(jié)點(diǎn)在Android 系統(tǒng)的哪個(gè)目錄
- vold.fstab 配置文件的分析?
- vold 里面啟動(dòng)頁(yè)面main做了些什么
android 系統(tǒng)如何開(kāi)機(jī)啟動(dòng)監(jiān)聽(tīng)mount服務(wù)
android sdcard 熱插拔監(jiān)測(cè)和執(zhí)行操作是由一個(gè)啟動(dòng)文件vold ?所統(tǒng)領(lǐng)的,系統(tǒng)開(kāi)機(jī)會(huì)讀取初始化配置文件init.rc,該文件位于比如我的板子是:device/ti/omap3evm/init.rc,具體根據(jù)自己平臺(tái)查找。里面有一個(gè)是默認(rèn)啟動(dòng)vold 服務(wù)的代碼,如下:
service?vold?/system/bin/vold????socket?vold?stream?0660?root?mount
? ? ioprio?be?2?
?如果要對(duì)該文件做出修改之類,要重新編一下boot.img 鏡像文件,燒錄進(jìn)android 系統(tǒng),之后可以在android的文件系統(tǒng)根目錄找到init.rc文件。上述代碼為啟動(dòng)vold 啟動(dòng)文件,也可以在init.rc 增加多一些我們想要的文件目錄,比如增加一個(gè)可以存放多分區(qū)掛載的目錄等,這個(gè)是后話。
?
?默認(rèn)設(shè)備節(jié)點(diǎn)在Android 系統(tǒng)的哪個(gè)目錄
?usbdisk 或者 sdcard 熱插拔的時(shí)候,kernel 會(huì)發(fā)出命令執(zhí)行mount或者unmount 操作,但這都是驅(qū)動(dòng)級(jí)的。而mount 目錄會(huì)在android 的文件系統(tǒng)目錄下:/dev/block/vold 這個(gè)目錄由vold 生成,用來(lái)存放所有的usbdisk 或者 sdcard 的設(shè)備節(jié)點(diǎn)。代碼位于main里面最優(yōu)先執(zhí)行:
?
mkdir("/dev/block/vold",?0755);??
?可以根據(jù)這個(gè)目錄找到如下節(jié)點(diǎn):
sh-4.1#?ls?/dev/block/vold/179:0??179:1??8:0????8:1????8:2????8:3????8:4?
節(jié)點(diǎn)的小介紹:
0代表當(dāng)前的整個(gè)設(shè)備,1代碼當(dāng)前設(shè)備的分區(qū)名稱代號(hào)。
所以你會(huì)發(fā)現(xiàn),sdcard只有一個(gè)分區(qū)它卻生成了兩個(gè)如:179:0 179:1
而usbdisk 有四個(gè)分區(qū),它會(huì)生成五個(gè)設(shè)備節(jié)點(diǎn):?8:0????8:1????8:2????8:3????8:4 ?就是這個(gè)原因。
?
?
?vold.fstab 配置文件的分析
vold 里面會(huì)通過(guò)指定文件來(lái)讀取預(yù)先配置好的sdcard或者多分區(qū)配置文件,該文件位于
/system/core/rootdir/etc/vold.fstab如以下的配置文件為:
dev_mount?sdcard?/mnt/sdcard?auto?/devices/platform/goldfish_mmc.0?/devices/platform/msm_sdcc.2/mmc_host/mmc1?
?dev_mount 代表掛載格式
?sdcard 代表掛載的標(biāo)簽
/mnt/sdcard 代表掛載點(diǎn)
?auto 為自定義選項(xiàng)可以為任何,但必須在main 里面自己判斷比如這里的意思為自動(dòng)掛載
后面兩個(gè)目錄為設(shè)備路徑,第一個(gè)如果被占用會(huì)選擇第二個(gè)
?
配置文件可以根據(jù)自己的需要編寫,并不是固定的,但最好遵循google vold 啟動(dòng)文件代碼的格式編寫,要不然會(huì)給我們修改代碼或者增加多分區(qū)功能帶來(lái)不小的麻煩,如以下我自己編寫的多分區(qū)掛載支持vold.fstab 配置文件:
?
dev_mount?sdcard?external?/mnt/sdcard?auto?/devices/platform/mmci-omap-hs.0/mmc_host/mmc0?/devices/platform/mmci-omap-hs.0/mmc_host/mmc1dev_mount?usb1?external?/mnt/usbdisk/usb1-disk%d?all?/devices/platform/ehci-omap.0/usb1/1-2/1-2.1/
dev_mount?usb2?external?/mnt/usbdisk/usb2-disk%d?all?/devices/platform/ehci-omap.0/usb1/1-2/1-2.2/
dev_mount?usb3?external?/mnt/usbdisk/usb3-disk%d?all?/devices/platform/ehci-omap.0/usb1/1-2/1-2.3/
?該文件修改后經(jīng)系統(tǒng)編譯會(huì)在android 系統(tǒng)目錄里/system/etc/vold.fstab找到。
?/devices/platform/ehci-omap.0/usb1/1-2/1-2.1/ ?代表要掛載的USB口。
vold.fstab 只是一個(gè)單純的配置文件,具體的讀取和取數(shù)據(jù)還 是要靠main里面的process_config函數(shù)??创a,里面正有一段用來(lái)讀取配置文件:
if?(!(fp?=?fopen("/etc/vold.fstab",?"r")))?{????????return?-1;
????}
在這個(gè)函數(shù)里面會(huì)根據(jù)讀取到的數(shù)據(jù)存放起來(lái),然后滿足條件時(shí)執(zhí)行操作。比如代碼里面的:
?
if?(!strcmp(type,?"dev_mount"))?{????????????DirectVolume?*dv?=?NULL;
????????????char?*part;
????????????if?(!(part?=?strtok_r(NULL,?delim,?&save_ptr)))?{
????????????????SLOGE("Error?parsing?partition");
????????????????goto?out_syntax;
????????????}
????????????if?(strcmp(part,?"auto")?&&?atoi(part)?==?0)?{
????????????????SLOGE("Partition?must?either?be?'auto'?or?1?based?index?instead?of?'%s'",?part);
????????????????goto?out_syntax;
????????????}
????????????if?(!strcmp(part,?"auto"))?{
????????????????dv?=?new?DirectVolume(vm,?label,?mount_point,?-1);
????????????}?else?{
????????????????dv?=?new?DirectVolume(vm,?label,?mount_point,?atoi(part));
????????????}
????????????while?((sysfs_path?=?strtok_r(NULL,?delim,?&save_ptr)))?{
????????????????if?(*sysfs_path?!=?'/')?{
????????????????????/*?If?the?first?character?is?not?a?'/',?it?must?be?flags?*/
????????????????????break;
????????????????}
????????????????if?(dv->addPath(sysfs_path))?{
????????????????????SLOGE("Failed?to?add?devpath?%s?to?volume?%s",?sysfs_path,
?????????????????????????label);
????????????????????goto?out_fail;
????????????????}
????????????}
????????????/*?If?sysfs_path?is?non-null?at?this?point,?then?it?contains
?????????????*?the?optional?flags?for?this?volume
?????????????*/
????????????if?(sysfs_path)
????????????????flags?=?parse_mount_flags(sysfs_path);
????????????else
????????????????flags?=?0;
????????????dv->setFlags(flags);
????????????vm->addVolume(dv);
????????}
?
DirectVolume后面會(huì)講到,執(zhí)行mount 和unmount 都是它在做。
另外,有時(shí)后讀取配置文件會(huì)有問(wèn)題,這是因?yàn)樗x取是通過(guò)指標(biāo)下標(biāo)遞增的方式在讀,如果有問(wèn)題可以跟蹤打印一下配置文件,看哪里需要修改。
main 主要是初始化socket 連接監(jiān)聽(tīng)數(shù)據(jù)變化,在系統(tǒng)起來(lái)時(shí)第一時(shí)間啟動(dòng),并且通過(guò)讀取配置文件來(lái)識(shí)別usb口或者sdcard 的設(shè)備地址,來(lái)mount 或者unmount 。其它執(zhí)行mount 、 unmount ?或者刪除節(jié)點(diǎn)等操作都是由上層或者framework 發(fā)送命令給main讓其通知volumeManage 執(zhí)行相應(yīng)的操作。總結(jié)
以上是生活随笔為你收集整理的Android SDCard Mount 流程分析(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 通过init.rc中的property实
- 下一篇: recovery的init.rc中挂载s