В Android 10 корневая файловая система больше не включается в ramdisk.img , а вместо этого объединяется с system.img (то есть system.img всегда создается так, как если бы был установлен параметр BOARD_BUILD_SYSTEM_ROOT_IMAGE ). Устройства, на которых установлена Android 10:
- Используйте разметку разделов "система как корневой раздел" (автоматически устанавливается процессом сборки без возможности изменения этого поведения).
- Необходимо использовать виртуальный диск в оперативной памяти (ramdisk), который требуется для работы dm-linear.
- Необходимо установить параметр
BOARD_BUILD_SYSTEM_ROOT_IMAGEвfalse. Этот параметр используется только для различения устройств, использующих образ оперативной памяти (ramdisk), и устройств, которые не используют образ оперативной памяти (ramdisk) (и вместо этого монтируют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. В конфигурации "system-as-root" для Android 10 сборка всегда объединяет $TARGET_SYSTEM_OUT и $TARGET_ROOT_OUT в system.img ; эта конфигурация является поведением по умолчанию для всех устройств, работающих под управлением Android 10.
В Android 10 внесены дополнительные изменения для поддержки динамических разделов — системы разделения пользовательского пространства, которая позволяет создавать, изменять размер или удалять разделы при обновлениях по беспроводной сети (OTA). В рамках этого изменения ядро Linux больше не может монтировать логический системный раздел на устройствах под управлением Android 10, поэтому эта операция обрабатывается на первом этапе инициализации.
В следующих разделах описаны требования к системе как root для обновлений OTA только для системных устройств, а также даны рекомендации по обновлению устройств для использования системы как root (включая изменения в структуре разделов и требования к ядру dm-verity). Подробную информацию об изменениях в ramdisk см. в разделе «Разделы Ramdisk» .
О системных OTA-обновлениях
Для обновления системы по воздуху (OTA) только до системных файлов, позволяющего обновлять system.img и product.img без изменения других разделов, требуется разметка разделов с правами root (system-as-root). Все устройства под управлением Android 10 должны использовать разметку разделов с правами root (system-as-root), чтобы включить обновление только до системных файлов.
- Устройства A/B, которые монтируют
systemраздел как корневую файловую систему, уже используют режим "система от имени root" и не требуют изменений для поддержки обновлений системы по воздуху (OTA). - Устройства, не относящиеся к классам A/B, которые монтируют
systemраздел в/system, должны быть обновлены для использования схемы расположения разделов "system-as-root" для поддержки обновлений системы по воздуху (OTA).
Подробную информацию об устройствах с поддержкой A/B и без нее см. в разделе « Обновления системы A/B (Seamless)» .
Используйте наложение поставщика (<=AOSP 14)
Функция наложения модулей поставщика позволяет накладывать изменения в раздел 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 . Если между файлами наложения поставщика и файлами, которые они заменяют, есть несоответствия контекста файлов, укажите это в политике безопасности для конкретного устройства. Контекст файла устанавливается на уровне каталога. Если контекст файла каталога наложения поставщика не совпадает с целевым каталогом, и правильный контекст файла не указан в политике безопасности для конкретного устройства, этот каталог наложения поставщика не будет наложен на целевой каталог.
Для использования наложения файловой системы необходимо включить 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, для использования system-as-root необходимо обновить схему разметки для boot.img и system.img , настроить dm-verity и удалить все зависимости загрузки от корневых папок, специфичных для устройства.
Обновить разделы
В отличие от устройств A/B, которые используют /boot в качестве раздела восстановления , устройства, не относящиеся к схеме A/B, должны сохранять раздел /recovery отдельным, поскольку у них нет резервного слота (например, с boot_a на boot_b ). Если на устройстве, не относящемся к схеме A/B, раздел /recovery будет удален и сделан аналогичным схеме A/B, режим восстановления может нарушиться при неудачном обновлении раздела /boot . По этой причине раздел /recovery должен быть отдельным разделом от /boot для устройств, не относящихся к схеме A/B, что означает, что образ восстановления продолжает обновляться отложенным образом (то есть так же, как на устройствах под управлением Android 8.1.0 или ниже).
В таблице ниже приведены различия в разделении изображений для устройств, не поддерживающих формат A/B, до и после обновления до Android 9.
| Изображение | Ramdisk (до Android 9) | Система с правами root (после Android 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)
... |
Сами разделы не меняются; как ramdisk, так и system-as-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 для system-as-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"
Используйте корневые папки, специфичные для вашего устройства.
При использовании режима "система как 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/* автоматически).