Внешнее хранилище управляется комбинацией службы 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 и более поздних различные файлы fstab, используемые init, vold и recovery, были объединены в /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
: true, если у этого монтирования есть съемный носитель, например физическая SD-карта. -
emulated
: true, если это монтирование эмулируется и поддерживается внутренним хранилищем, возможно, с использованием демона FUSE. -
mtp-reserve
: количество МБ хранилища, которое MTP должен зарезервировать для бесплатного хранения. Используется только в том случае, если mount помечен как эмулируемый. -
allowMassStorage
: true, если это крепление можно использовать через USB-накопитель. -
maxFileSize
: максимальный размер файла в МБ.
Устройства могут предоставлять внешнее хранилище, эмулируя нечувствительную к регистру файловую систему без разрешений, поддерживаемую внутренним хранилищем. Одна из возможных реализаций предоставляется демоном FUSE в system/core/sdcard
, который можно добавить в качестве службы 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
подходящее запоминающее устройство, используйте encryptable=userdata
в поле fs_mgr_flags
. Вот типичное определение:
/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
для определения типов файловых систем перед монтированием, и пользователи могут выбрать форматирование носителя, если файловая система не поддерживается.