設備配置

外部存儲由vold init 服務和StorageManagerService系統服務組合管理。物理外部存儲卷的安裝由vold處理,它在將媒體公開給應用程序之前執行暫存操作以準備媒體。

注意:在 Android 8.0 中, MountService類已重命名為StorageManagerService

文件映射

對於 Android 4.2.2 及更早版本,設備特定的vold.fstab配置文件定義了從 sysfs 設備到文件系統掛載點的映射,每一行都遵循以下格式:

dev_mount <label> <mount_point> <partition> <sysfs_path> [flags]
  • label :卷的標籤。
  • mount_point :應該安裝卷的文件系統路徑。
  • partition : 分區號(基於 1),或“自動”用於第一個可用分區。
  • sysfs_path :一個或多個可以提供此掛載點的設備的 sysfs 路徑。用空格分隔,每個必須以/開頭。
  • flags :可選的逗號分隔的標誌列表,不能包含/ 。可能的值包括nonremovableencryptable

對於 Android 4.3 及更高版本,init、vold 和 recovery 使用的各種 fstab 文件統一在/fstab.<device>文件中。對於由vold管理的外部存儲卷,條目應具有以下格式:

<src> <mnt_point> <type> <mnt_flags> <fs_mgr_flags>
  • src : sysfs 下的路徑(通常安裝在 /sys)到可以提供安裝點的設備。路徑必須以/開頭。
  • mount_point :應該安裝卷的文件系統路徑。
  • type :卷上文件系統的類型。對於外部卡,這通常是vfat
  • mnt_flagsVold忽略此字段,應將其設置為defaults
  • fs_mgr_flagsVold忽略統一 fstab 中不包括該字段中的voldmanaged=標誌的任何行。這個標誌後面必須跟一個描述卡的標籤,以及一個分區號或單詞auto 。這是一個示例: voldmanaged=sdcard:auto 。其他可能的標誌是nonremovableencryptable=sdcardnoemulatedsdencryptable=userdata

配置詳情

框架級別及以上的外部存儲交互通過StorageManagerService處理。由於 Android 6.0 中的配置更改(如刪除 storage_list.xml 資源覆蓋),配置詳細信息分為兩類。

Android 5.x 及更早版本

設備特定的storage_list.xml配置文件,通常通過frameworks/base覆蓋提供,定義存儲設備的屬性和約束。 <StorageList>元素包含一個或多個<storage>元素,其中一個應標記為主要元素。 <storage>屬性包括:

  • mountPoint :此掛載的文件系統路徑。
  • storageDescription :描述此掛載的字符串資源。
  • primary :如果此掛載是主外部存儲,則為 true。
  • removable :如果此掛載具有可移動媒體,例如物理 SD 卡,則為 true。
  • emulated :如果此掛載是模擬的並且由內部存儲支持,則為 true,可能使用 FUSE 守護程序。
  • mtp-reserve :MTP 應為免費存儲預留的 MB 存儲空間。僅在 mount 標記為 emulated 時使用。
  • allowMassStorage : 如果此掛載可以通過 USB 大容量存儲共享,則為 true。
  • maxFileSize :最大文件大小,以 MB 為單位。

設備可以通過模擬由內部存儲支持的不區分大小寫、無需許可的文件系統來提供外部存儲。 system/core/sdcard中的 FUSE 守護進程提供了一種可能的實現,它可以作為特定於設備的init.rc服務添加:

# virtual sdcard daemon running as media_rw (1023)
service sdcard /system/bin/sdcard <source_path> <dest_path> 1023 1023
    class late_start

其中source_path是後備內部存儲,而dest_path是目標掛載點。

配置特定於設備的init.rc腳本時,必須將EXTERNAL_STORAGE環境變量定義為主外部存儲的路徑。 /sdcard路徑也必須解析到相同的位置,可能通過符號鏈接。如果設備在平台更新之間調整了外部存儲的位置,則應創建符號鏈接,以便舊路徑繼續工作。

安卓6.0

存儲子系統的配置現在集中在特定於設備的fstab文件中,並且刪除了幾個歷史靜態配置文件/變量以支持更多動態行為:

  • storage_list.xml資源覆蓋已被移除,框架不再使用。存儲設備現在在被vold檢測到時動態配置。
  • EMULATED_STORAGE_SOURCE/TARGET環境變量已被刪除,Zygote 不再使用它來配置用戶特定的掛載點。取而代之的是,現在使用特定於用戶的 GID 強制執行用戶分離,並且主共享存儲在運行時由vold安裝到位。
    • 開發人員可以根據他們的用例繼續動態或靜態地構建路徑。在路徑中包含 UUID 可標識每張卡片,以便開發人員更清楚地了解位置。 (例如, /storage/ABCD-1234/report.txt顯然是與/storage/DCBA-4321/report.txt不同的文件。)
  • 硬編碼的 FUSE 服務已從特定於設備的init.rc文件中刪除,而是在需要時從vold動態分叉。

除了這些配置更改之外,Android 6.0 還包括可採用存儲的概念。對於 Android 6.0 設備,任何未採用的物理媒體都被視為可移植的。

可採用的存儲

要在fstab中指示可採用的存儲設備,請在fs_mgr_flags字段中使用encryptable=userdata屬性。這是一個典型的定義:

/devices/platform/mtk-msdc.1/mmc_host*           auto      auto     defaults
voldmanaged=sdcard1:auto,encryptable=userdata

採用存儲設備時,平台擦除內容並寫入定義兩個分區的GUID分區表:

  • 一個小的空android_meta分區,保留供將來使用。分區類型 GUID 為 19A710A2-B3CA-11E4-B026-10604B889DCF。
  • 使用 dm-crypt 加密並根據內核功能使用ext4f2fs格式化的大型android_ext分區。分區類型 GUID 為 193D1EA4-B3CA-11E4-B075-10604B889DCF。

便攜式存儲

fstab中,默認情況下,具有voldmanaged屬性的存儲設備被認為是可移植的,除非定義了另一個屬性,例如encryptable=userdata 。例如,以下是 USB OTG 設備的典型定義:

/devices/*/xhci-hcd.0.auto/usb*             auto            auto    defaults
                                                    voldmanaged=usb:auto

平台在掛載前使用blkid檢測文件系統類型,當文件系統不支持時,用戶可以選擇格式化媒體。