Android SDCard Mount流程分析(一)

來源:互聯網
上載者:User

前段時間對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 執行相應的操作。

 

摘自  Terry_龍 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.