外部儲存空間由 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
:標記的選用逗號分隔清單,不得包含/
。可能的值包括nonremovable
和encryptable
。
針對 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_flags
:Vold
會忽略這個欄位,因此應將其設為defaults
fs_mgr_flags
:Vold
會忽略統一 fstab 中不含此欄位voldmanaged=
旗標的任何一行。這個旗標後面必須接著描述卡片的標籤,以及分區編號或auto
字詞。範例如下:voldmanaged=sdcard:auto
。其他可能的旗標為nonremovable
、encryptable=sdcard
、noemulatedsd
和encryptable=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
顯然屬於不同的檔案)。
- 開發人員可以根據用途,繼續以動態或靜態方式建構路徑。在路徑中加入 UUID 可識別每張資訊卡,讓開發人員更清楚瞭解位置。(例如,
- 硬式編碼的 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 加密,並視核心功能使用ext4
或f2fs
格式化。分割區類型 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
偵測檔案系統類型,使用者可以在檔案系統不相容時選擇格式化媒體。