В Android 10 корневая файловая система больше не включается в ramdisk.img и вместо этого объединяется с system.img (то есть system.img всегда создается так, как если бы был установлен BOARD_BUILD_SYSTEM_ROOT_IMAGE ). Устройства, запускаемые с Android 10:
- Используйте макет раздела «система от имени корня» (автоматически применяется сборкой без параметров для изменения поведения).
- Должен использоваться виртуальный диск, необходимый для dm-linear.
- Необходимо установить для
BOARD_BUILD_SYSTEM_ROOT_IMAGEзначениеfalse. Этот параметр используется только для того, чтобы различать устройства, которые используют виртуальный диск, и устройства, которые не используют виртуальный диск (и вместо этого монтируютsystem.imgнапрямую).
Значение конфигурации system-as-root различается в Android 9 и Android 10. В конфигурации system-as-root Android 9 для параметра BOARD_BUILD_SYSTEM_ROOT_IMAGE установлено значение true , что заставляет сборку объединить корневую файловую систему с system.img , а затем смонтировать system.img как корневую файловую систему (rootfs). Эта конфигурация обязательна для устройств, запускаемых с Android 9, но необязательна для устройств, обновляющихся до Android 9, и для устройств с более ранними версиями Android. В конфигурации системы Android 10 как root сборка всегда объединяет $TARGET_SYSTEM_OUT и $TARGET_ROOT_OUT в system.img ; эта конфигурация является поведением по умолчанию для всех устройств под управлением Android 10.
В Android 10 внесены дополнительные изменения для поддержки динамических разделов — системы разделения пользовательского пространства, которая позволяет выполнять беспроводные (OTA) обновления для создания, изменения размера или уничтожения разделов. В рамках этого изменения ядро Linux больше не может монтировать логический системный раздел на устройствах под управлением Android 10, поэтому эта операция выполняется на первом этапе инициализации.
В следующих разделах описываются требования системы от имени пользователя root для системных OTA, а также рекомендации по обновлению устройств для использования системы от имени пользователя root (включая изменения макета раздела и требования к ядру dm-verity). Подробнее об изменениях виртуального диска см. Разделы виртуального диска .
О системных OTA
OTA только для системы, которые позволяют выпускам Android обновлять system.img и product.img без изменения других разделов, требуют расположения системы как корневого раздела. Все устройства под управлением Android 10 должны использовать макет раздела «система как корневой», чтобы включить OTA только для системы.
- Устройства A/B, которые монтируют
systemраздел как rootfs, уже используют систему как root и не требуют изменений для поддержки системных OTA. - Устройства, отличные от A/B, которые монтируют
systemраздел в/system, должны быть обновлены, чтобы использовать макет раздела «система-как-корневой » для поддержки системных OTA.
Подробнее об устройствах A/B и других устройствах см. в разделе Обновления системы A/B (бесшовные) .
Использование наложения поставщика
Наложение поставщика позволяет накладывать изменения на раздел vendor во время загрузки устройства. Наложение поставщика — это набор модулей поставщика в разделе product , которые накладываются на раздел vendor при загрузке устройства, заменяя и добавляя существующие модули.
Когда устройство загружается, процесс init завершает монтирование первого этапа и считывает свойства по умолчанию. Затем он ищет /product/vendor_overlay/<target_vendor_version> и монтирует каждый подкаталог в соответствующем каталоге раздела vendor , если выполняются следующие условия:
-
/vendor/<overlay_dir>существует. -
/product/vendor_overlay/<target_vendor_version>/<overlay_dir>имеет тот же файловый контекст, что и/vendor/<overlay_dir>. -
initразрешено монтировать в контексте файла/vendor/<overlay_dir>.
Реализация наложения поставщиков
Установите файлы наложения поставщика в /product/vendor_overlay/<target_vendor_version> . Эти файлы перекрывают раздел vendor при загрузке устройства, заменяя файлы с тем же именем и добавляя новые файлы. Оверлей поставщика не может удалять файлы из раздела vendor .
Файлы наложения поставщика должны иметь тот же файловый контекст, что и целевые файлы, которые они заменяют в разделе vendor . По умолчанию файлы в каталоге /product/vendor_overlay/<target_vendor_version> имеют контекст vendor_file . Если существуют несоответствия файлового контекста между файлами наложения поставщика и файлами, которые они заменяют, укажите это в политике sepolicy для конкретного устройства. Контекст файла задается на уровне каталога. Если контекст файла в каталоге наложения поставщика не соответствует целевому каталогу, а правильный контекст файла не указан в политике sepolicy для конкретного устройства, этот каталог наложения поставщика не накладывается на целевой каталог.
Чтобы использовать наложение поставщика, ядро должно включить OverlayFS, установив CONFIG_OVERLAY_FS=y . Также ядро должно быть слито из общего ядра 4.4 или новее, либо пропатчено с помощью "overlayfs: override_creds=off option bypass creator_cred" .
Пример реализации наложения поставщика
Эта процедура демонстрирует реализацию наложения поставщика, которое перекрывает каталоги /vendor/lib/* , /vendor/etc/* и /vendor/app/* .
Добавьте готовые файлы поставщиков в
device/<vendor>/<target>/vendor_overlay/<target_vendor_version>/:device/google/device/vendor_overlay/28/lib/libfoo.so device/google/device/vendor_overlay/28/lib/libbar.so device/google/device/vendor_overlay/28/etc/baz.xml device/google/device/vendor_overlay/28/app/qux.apk
Установите готовые файлы поставщиков в
product/vendor_overlayвdevice/google/device/device.mk:PRODUCT_COPY_FILES += \ $(call find-copy-subdir-files,*,device/google/device/vendor_overlay,$(TARGET_COPY_OUT_PRODUCT)/vendor_overlay)Определите файловые контексты, если файлы разделов целевого
vendorимеют контексты, отличные отvendor_file. Поскольку/vendor/lib/*использует контекстvendor_file, в этом примере этот каталог не используется.Добавьте следующее в
device/google/device-sepolicy/private/file_contexts:/(product|system/product)/vendor_overlay/[0-9]+/etc(/.*)? u:object_r:vendor_configs_file:s0 /(product|system/product)/vendor_overlay/[0-9]+/app(/.*)? u:object_r:vendor_app_file:s0
Разрешить процессу
initмонтировать оверлей поставщика в контекстах файлов, отличных отvendor_file. Поскольку процессinitуже имеет разрешение на монтирование в контекстеvendor_file, в этом примере политика дляvendor_fileне определяется.Добавьте следующее в
device/google/device-sepolicy/public/init.te:allow init vendor_configs_file:dir mounton; allow init vendor_app_file:dir mounton;
Проверка наложения поставщика
Чтобы проверить конфигурацию наложения поставщика, добавьте файлы в /product/vendor_overlay/<target_vendor_version>/<overlay_dir> и проверьте, накладываются ли файлы на файлы в /vendor/<overlay_dir> .
Для сборок userdebug есть тестовый модуль для Atest :
$ atest -v fs_mgr_vendor_overlay_test
Обновление до системы от имени root
Чтобы обновить устройства, отличные от A/B, для использования системы от имени root, вы должны обновить схему разбиения на разделы для boot.img и system.img , настроить dm-verity и удалить все зависимости загрузки от корневых папок конкретного устройства.
Обновление разделов
В отличие от устройств A/B, которые переназначают /boot в качестве раздела восстановления , устройства, отличные от A/B, должны хранить раздел /recovery отдельно, поскольку у них нет раздела резервного слота (например, из boot_a в boot_b ). Если /recovery удалить на устройстве, отличном от A/B, и сделать его похожим на схему A/B, режим восстановления может прерваться во время неудачного обновления раздела /boot . По этой причине раздел /recovery должен быть отдельным разделом от /boot для устройств, отличных от A/B, что означает, что образ восстановления будет по-прежнему обновляться отложенным образом (то есть так же, как на устройствах под управлением Android). 8.1.0 или ниже).
В следующей таблице перечислены различия в разделах образа для устройств, отличных от A/B, до и после Android 9.
| Изображение | Рамдиск (до 9) | Система от имени root (после 9) |
|---|---|---|
boot.img | Содержит ядро и ramdisk.img : ramdisk.img
-/
- init.rc
- init
- etc -> /system/etc
- system/ (mount point)
- vendor/ (mount point)
- odm/ (mount point)
... | Содержит только обычное загрузочное ядро. |
recovery.img | Содержит ядро восстановления и файл восстановления ramdisk.img . | |
system.img | Содержит следующее: system.img
-/
- bin/
- etc
- vendor -> /vendor
- ... | Содержит объединенное содержимое исходного system.img и ramdisk.img : system.img
-/
- init.rc
- init
- etc -> /system/etc
- system/
- bin/
- etc/
- vendor -> /vendor
- ...
- vendor/ (mount point)
- odm/ (mount point)
... |
Сами разделы не меняются; и виртуальный диск, и система от имени пользователя root используют следующую схему разделов:
-
/boot -
/system -
/system -
/recovery -
/vendorи т.д.
Настройка dm-verity
В системе от имени root ядро должно монтировать system.img в / (точка монтирования) с помощью dm-verity . AOSP поддерживает следующие реализации dm-verity для system.img .
vboot 1.0
Для vboot 1.0 ядро должно проанализировать специфичные для Android метаданные в /system , а затем преобразовать в параметры dm-verity для настройки dm-verity (требуются эти исправления ядра ). В следующем примере показаны настройки, связанные с dm-verity, для системы от имени пользователя root в командной строке ядра:
ro root=/dev/dm-0 rootwait skip_initramfs init=/init dm="system none ro,0 1 android-verity /dev/sda34" veritykeyid=id:7e4333f9bba00adfe0ede979e28ed1920492b40f
vboot 2.0
Для vboot 2.0 ( AVB ) загрузчик должен интегрировать external/avb/libavb , который затем анализирует дескриптор хеш -дерева для /system , преобразует его в параметры dm-verity и, наконец, передает параметры ядру через командную строку ядра. (Хэш-дескрипторы /system могут находиться в /vbmeta или в самой /system .)
vboot 2.0 требует следующих исправлений ядра:
- https://android-review.googlesource.com/#/c/kernel/common/+/158491/
- патчи для ядра 4.4, патчи для ядра 4.9 и т. д.
В следующем примере показаны настройки, связанные с dm-verity, для системы от имени пользователя root в командной строке ядра:
ro root=/dev/dm-0 rootwait skip_initramfs init=/init dm="1 vroot none ro 1,0 5159992 verity 1 PARTUUID=00000016-0000-0000-0000-000000000000 PARTUUID=00000016-0000-0000-0000-000000000000 4096 4096 644999 644999 sha1 d80b4a8be3b58a8ab86fad1b498640892d4843a2 8d08feed2f55c418fb63447fec0d32b1b107e42c 10 restart_on_corruption ignore_zero_blocks use_fec_from_device PARTUUID=00000016-0000-0000-0000-000000000000 fec_roots 2 fec_blocks 650080 fec_start 650080"
Использование корневых папок для конкретных устройств
При использовании system-as-root после того, как общий образ системы (GSI) прошивается на устройстве (и перед запуском тестов Vendor Test Suite ), любые корневые папки для конкретного устройства, добавленные с помощью BOARD_ROOT_EXTRA_FOLDERS , исчезают, поскольку все содержимое корневого каталога было заменено. GSI системы от имени root. Удаление этих папок может привести к тому, что устройство перестанет загружаться, если существует зависимость от корневых папок устройства (например, они используются в качестве точек подключения).
Чтобы избежать этой проблемы, не используйте BOARD_ROOT_EXTRA_FOLDERS для добавления корневых папок для конкретных устройств. Если вам нужно указать точки монтирования для конкретного устройства, используйте /mnt/vendor/<mount point> (добавлено в эти списки изменений ). Эти точки монтирования, зависящие от поставщика, могут быть указаны напрямую как в дереве устройств fstab (для монтирования на первом этапе), так и в файле /vendor/etc/fstab.{ro.hardware} без дополнительной настройки (поскольку fs_mgr создает их в /mnt/vendor/* автоматически).