Расположение разделов

В 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/* .

  1. Добавьте предварительно собранные файлы поставщика в 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
  2. Установите предварительно собранные файлы поставщика в папку 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)
  3. Укажите контексты файлов, если файлы разделов целевого 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
  4. Разрешить процессу 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 требуются следующие патчи ядра:

В следующем примере показаны настройки 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/* автоматически).