裝置設定

外部儲存空間由 vold 初始服務和 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 為基底),或「auto」表示第一個可用分區。
  • 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:如果此掛載點為模擬的,且由內部儲存空間提供支援 (可能會使用 FUSE 守護程式),則為 true。
  • mtp-reserve:MTP 應為可用儲存空間保留的 MB 數量。只有在掛載點標示為模擬時才會使用。
  • 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 路徑也必須解析至相同位置,可能會透過符號連結。如果裝置在平台更新期間調整外部儲存空間的位置,應建立符號連結,以便舊路徑繼續運作。

Android 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。
  • 大型 android_ext 分區,使用 dm-crypt 加密,並視核心功能使用 ext4f2fs 格式化。分割區類型 GUID 為 193D1EA4-B3CA-11E4-B075-10604B889DCF。

可攜式儲存空間

fstab 中,如果沒有定義 encryptable=userdata 等其他屬性,系統會將具有 voldmanaged 屬性的儲存裝置視為可攜式裝置。舉例來說,以下是 USB OTG 裝置的一般定義:

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

平台會在掛載前使用 blkid 偵測檔案系統類型,使用者可以在檔案系統不相容時選擇格式化媒體。