外部儲存由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 開始),或第一個可用分區的「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
路徑也必須解析到相同位置(可能透過符號連結)。如果裝置在平台更新之間調整外部儲存的位置,則應建立符號鏈接,以便舊路徑繼續工作。
安卓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
中,預設情況下,具有voldmanaged
屬性的儲存設備被認為是可移植的,除非定義了另一個屬性(例如encryptable=userdata
。例如,以下是 USB OTG 裝置的典型定義:
/devices/*/xhci-hcd.0.auto/usb* auto auto defaults voldmanaged=usb:auto
此平台在掛載前使用blkid
來偵測檔案系統類型,當檔案系統不支援時,使用者可以選擇格式化媒體。