Android SDCard Mount 流程分析(一)


前段時間對Android 的SDCard unmount 流程進行了幾篇簡短的分析,由於當時只是紙上談兵,沒有實際上的跟進,可能會有一些誤導人或者小錯誤。今天重新梳理了頭緒,針對mount的流程再重新分析一次。

 本篇大綱

  • android 系統如何開機啟動監聽mount服務
  • 默認設備節點在Android 系統的哪個目錄
  • vold.fstab 配置文件的分析 
  • vold 里面啟動頁面main做了些什么

android 系統如何開機啟動監聽mount服務

android sdcard 熱插拔監測和執行操作是由一個啟動文件vold  所統領的,系統開機會讀取初始化配置文件init.rc,該文件位於比如我的板子是:device/ti/omap3evm/init.rc,具體根據自己平台查找。里面有一個是默認啟動vold 服務的代碼,如下:

service vold /system/bin/vold
    socket vold stream 0660 root mount
    ioprio be 2 

 如果要對該文件做出修改之類,要重新編一下boot.img 鏡像文件,燒錄進android 系統,之后可以在android的文件系統根目錄找到init.rc文件。上述代碼為啟動vold 啟動文件,也可以在init.rc 增加多一些我們想要的文件目錄,比如增加一個可以存放多分區掛載的目錄等,這個是后話。

 

 默認設備節點在Android 系統的哪個目錄

 usbdisk 或者 sdcard 熱插拔的時候,kernel 會發出命令執行mount或者unmount 操作,但這都是驅動級的。而mount 目錄會在android 的文件系統目錄下:/dev/block/vold 這個目錄由vold 生成,用來存放所有的usbdisk 或者 sdcard 的設備節點。代碼位於main里面最優先執行:

 

mkdir("/dev/block/vold", 0755) ;  

 

 可以根據這個目錄找到如下節點:

sh-4.1# ls /dev/block/vold/
179:0  179:1  8:0    8:1    8:2    8:3    8:4 

節點的小介紹:

0代表當前的整個設備,1代碼當前設備的分區名稱代號。

所以你會發現,sdcard只有一個分區它卻生成了兩個如:179:0 179:1

而usbdisk 有四個分區,它會生成五個設備節點: 8:0    8:1    8:2    8:3    8:4  就是這個原因。

 

 

 vold.fstab 配置文件的分析

vold 里面會通過指定文件來讀取預先配置好的sdcard或者多分區配置文件,該文件位於

/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 代表掛載的標簽

/mnt/sdcard 代表掛載點

 auto 為自定義選項可以為任何,但必須在main 里面自己判斷比如這里的意思為自動掛載

后面兩個目錄為設備路徑,第一個如果被占用會選擇第二個

 

配置文件可以根據自己的需要編寫,並不是固定的,但最好遵循google vold 啟動文件代碼的格式編寫,要不然會給我們修改代碼或者增加多分區功能帶來不小的麻煩,如以下我自己編寫的多分區掛載支持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/mmc1
dev_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/

 該文件修改后經系統編譯會在android 系統目錄里/system/etc/vold.fstab找到。

 /devices/platform/ehci-omap.0/usb1/1-2/1-2.1/  代表要掛載的USB口。

vold.fstab 只是一個單純的配置文件,具體的讀取和取數據還 是要靠main里面的process_config函數。看代碼,里面正有一段用來讀取配置文件:

  if (!(fp = fopen("/etc/vold.fstab", "r"))) {
        return -1 ;
    }

在這個函數里面會根據讀取到的數據存放起來,然后滿足條件時執行操作。比如代碼里面的:

 

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后面會講到,執行mount 和unmount 都是它在做。

另外,有時后讀取配置文件會有問題,這是因為它讀取是通過指標下標遞增的方式在讀,如果有問題可以跟蹤打印一下配置文件,看哪里需要修改。

 

 vold 里面啟動頁面main做了些什么

main 主要是初始化socket 連接監聽數據變化,在系統起來時第一時間啟動,並且通過讀取配置文件來識別usb口或者sdcard 的設備地址,來mount 或者unmount 。其它執行mount 、 unmount  或者刪除節點等操作都是由上層或者framework 發送命令給main讓其通知volumeManage 執行相應的操作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM