Diseño de partición

En Android 10, el sistema de archivos raíz ya no está incluido en ramdisk.img y, en cambio, se fusiona en system.img (es decir, system.img siempre se crea como si se hubiera configurado BOARD_BUILD_SYSTEM_ROOT_IMAGE ). Dispositivos que se inician con Android 10:

  • Utilice un diseño de partición de sistema como raíz (aplicado automáticamente por la compilación sin opciones para cambiar el comportamiento).
  • Debe utilizar un disco RAM, que es necesario para dm-linear.
  • Debe establecer BOARD_BUILD_SYSTEM_ROOT_IMAGE en false . Esta configuración se usa solo para diferenciar entre dispositivos que usan un disco ram y dispositivos que no usan un disco ram (y en su lugar montan system.img directamente).

El significado de una configuración de sistema como raíz difiere entre Android 9 y Android 10. En una configuración de sistema como raíz de Android 9, BOARD_BUILD_SYSTEM_ROOT_IMAGE se establece en true , lo que obliga a la compilación a fusionar el sistema de archivos raíz en system.img y luego monte system.img como sistema de archivos raíz (rootfs). Esta configuración es obligatoria para dispositivos que se inician con Android 9, pero es opcional para dispositivos que se actualizan a Android 9 y para dispositivos que ejecutan versiones inferiores de Android. En una configuración de sistema como raíz de Android 10, la compilación siempre fusiona $TARGET_SYSTEM_OUT y $TARGET_ROOT_OUT en system.img ; esta configuración es el comportamiento predeterminado para todos los dispositivos que ejecutan Android 10.

Android 10 realiza más cambios para admitir particiones dinámicas , un sistema de partición del espacio de usuario que permite actualizaciones inalámbricas (OTA) para crear, cambiar el tamaño o destruir particiones. Como parte de este cambio, el kernel de Linux ya no puede montar la partición lógica del sistema en dispositivos que ejecutan Android 10, por lo que esta operación la maneja la primera etapa init.

Las siguientes secciones describen los requisitos del sistema como raíz para OTA solo del sistema y brindan orientación sobre cómo actualizar los dispositivos para usar el sistema como raíz (incluidos los cambios en el diseño de la partición y los requisitos del kernel dm-verity). Para obtener detalles sobre los cambios en ramdisk, consulte Particiones Ramdisk .

Acerca de las OTA exclusivas del sistema

Las OTA solo del sistema, que permiten que las versiones de Android actualicen system.img y product.img sin cambiar otras particiones, requieren un diseño de partición del sistema como raíz. Todos los dispositivos que ejecutan Android 10 deben usar un diseño de partición de sistema como raíz para habilitar OTA solo del sistema.

Para obtener detalles sobre dispositivos A/B y no A/B, consulte Actualizaciones del sistema A/B (sin interrupciones) .

Usando superposición de proveedores

La superposición de proveedores le permite superponer los cambios en la partición vendor en el momento del inicio del dispositivo. Una superposición de proveedor es un conjunto de módulos de proveedor en la partición product que se superponen en la partición vendor cuando se inicia el dispositivo, reemplazando y agregando módulos existentes.

Cuando se inicia el dispositivo, el proceso init completa el montaje de la primera etapa y lee las propiedades predeterminadas. Luego busca /product/vendor_overlay/<target_vendor_version> y monta cada subdirectorio en su directorio de partición vendor correspondiente, si se cumplen las siguientes condiciones:

  • /vendor/<overlay_dir> existe.
  • /product/vendor_overlay/<target_vendor_version>/<overlay_dir> tiene el mismo contexto de archivo que /vendor/<overlay_dir> .
  • init puede montarse en el contexto del archivo de /vendor/<overlay_dir> .

Implementación de superposición de proveedores

Instale los archivos de superposición del proveedor en /product/vendor_overlay/<target_vendor_version> . Esos archivos se superponen a la partición del vendor cuando se inicia el dispositivo, reemplazando archivos del mismo nombre y agregando archivos nuevos. La superposición de proveedores no puede eliminar archivos de la partición vendor .

Los archivos de superposición del proveedor deben tener el mismo contexto de archivo que los archivos de destino que reemplazan en la partición vendor . De forma predeterminada, los archivos en el directorio /product/vendor_overlay/<target_vendor_version> tienen el contexto vendor_file . Si hay discrepancias en el contexto de los archivos entre los archivos superpuestos del proveedor y los archivos que reemplazan, especifíquelo en la política específica del dispositivo. El contexto del archivo se establece en el nivel del directorio. Si el contexto del archivo de un directorio superpuesto del proveedor no coincide con el directorio de destino y no se especifica el contexto del archivo correcto en la política específica del dispositivo, ese directorio superpuesto del proveedor no se superpone al directorio de destino.

Para utilizar la superposición del proveedor, el kernel debe habilitar OverlayFS configurando CONFIG_OVERLAY_FS=y . Además, el kernel debe fusionarse desde el kernel común 4.4 o posterior, o parchearse con "overlayfs: override_creds=off option bypass creator_cred" .

Ejemplo de implementación de superposición de proveedores

Este procedimiento demuestra la implementación de una superposición de proveedor que superpone los directorios /vendor/lib/* , /vendor/etc/* y /vendor/app/* .

  1. Agregue archivos de proveedor prediseñados en 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. Instale los archivos de proveedor prediseñados en product/vendor_overlay en 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. Defina contextos de archivos si los archivos de partición vendor de destino tienen contextos distintos de vendor_file . Debido a que /vendor/lib/* usa el contexto vendor_file , este ejemplo no incluye ese directorio.

    Agregue lo siguiente a 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. Permita que el proceso init monte la superposición del proveedor en contextos de archivos distintos del vendor_file . Debido a que el proceso init ya tiene permiso para montarse en el contexto vendor_file , este ejemplo no define la política para vendor_file .

    Agregue lo siguiente a device/google/device-sepolicy/public/init.te :

    allow init vendor_configs_file:dir mounton;
    allow init vendor_app_file:dir mounton;
    

Validación de superposición de proveedores

Para validar la configuración de superposición del proveedor, agregue archivos en /product/vendor_overlay/<target_vendor_version>/<overlay_dir> y verifique si los archivos están superpuestos en los archivos en /vendor/<overlay_dir> .

Para compilaciones userdebug , hay un módulo de prueba para Atest :

$ atest -v fs_mgr_vendor_overlay_test

Actualización al sistema como raíz

Para actualizar dispositivos que no son A/B para usar system-as-root, debe actualizar el esquema de partición para boot.img y system.img , configurar dm-verity y eliminar cualquier dependencia de inicio en las carpetas raíz específicas del dispositivo.

Actualizando particiones

A diferencia de los dispositivos A/B que reutilizan /boot como partición de recuperación , los dispositivos que no son A/B deben mantener la partición /recovery separada ya que no tienen la partición de ranura alternativa (por ejemplo, de boot_a a boot_b ). Si /recovery se elimina en un dispositivo que no es A/B y se hace similar al esquema A/B, el modo de recuperación podría interrumpirse durante una actualización fallida de la partición /boot . Por este motivo, la partición /recovery debe ser una partición separada de /boot para dispositivos que no sean A/B, lo que implica que la imagen de recuperación seguirá actualizándose de forma diferida (es decir, igual que en los dispositivos que ejecutan Android). 8.1.0 o inferior).

La siguiente tabla enumera las diferencias de partición de imágenes para dispositivos que no son A/B antes y después de Android 9.

Imagen Disco RAM (antes del 9) Sistema como raíz (después de 9)
boot.img Contiene un kernel y un ramdisk.img :
ramdisk.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/ (mount point)
    - vendor/ (mount point)
    - odm/ (mount point)
    ...
Contiene únicamente un kernel de arranque normal.
recovery.img Contiene un kernel de recuperación y un ramdisk.img de recuperación.
system.img Contiene lo siguiente:
system.img
  -/
    - bin/
    - etc
    - vendor -> /vendor
    - ...
Contiene el contenido combinado de system.img y ramdisk.img originales:
system.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/
      - bin/
      - etc/
      - vendor -> /vendor
      - ...
    - vendor/ (mount point)
    - odm/ (mount point)
    ...

Las particiones en sí no cambian; Tanto el disco RAM como el sistema como raíz utilizan el siguiente esquema de partición:

  • /boot
  • /system
  • /system
  • /recovery
  • /vendor , etc.

Configurando dm-verity

En system-as-root, el kernel debe montar system.img en / (punto de montaje) con dm-verity . AOSP admite las siguientes implementaciones de dm-verity para system.img .

vboot 1.0

Para vboot 1.0 , el kernel debe analizar los metadatos específicos de Android en /system y luego convertirlos a parámetros dm-verity para configurar dm-verity (requiere estos parches del kernel ). El siguiente ejemplo muestra la configuración relacionada con dm-verity para system-as-root en la línea de comando del kernel:

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

Para vboot 2.0 ( AVB ), el gestor de arranque debe integrar external/avb/libavb , que luego analiza el descriptor de hashtree para /system , lo convierte a dm-verity params y finalmente pasa los parámetros al kernel a través de la línea de comando del kernel. (Los descriptores de Hashtree de /system pueden estar en /vbmeta o en el propio /system ).

vboot 2.0 requiere los siguientes parches del kernel:

El siguiente ejemplo muestra la configuración relacionada con dm-verity para system-as-root en la línea de comando del kernel:

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"

Usar carpetas raíz específicas del dispositivo

Con el sistema como raíz, después de que la imagen genérica del sistema (GSI) se muestra en el dispositivo (y antes de ejecutar las pruebas de Vendor Test Suite ), todas las carpetas raíz específicas del dispositivo agregadas con BOARD_ROOT_EXTRA_FOLDERS desaparecen porque se reemplaza todo el contenido del directorio raíz. por el GSI del sistema como raíz. La eliminación de estas carpetas puede hacer que el dispositivo no pueda iniciarse si existe una dependencia de las carpetas raíz específicas del dispositivo (por ejemplo, se usan como puntos de montaje).

Para evitar este problema, no utilice BOARD_ROOT_EXTRA_FOLDERS para agregar carpetas raíz específicas del dispositivo. Si necesita especificar puntos de montaje específicos del dispositivo, use /mnt/vendor/<mount point> (agregado en estas listas de cambios ). Estos puntos de montaje específicos del proveedor se pueden especificar directamente tanto en el árbol de dispositivos fstab (para montaje de primera etapa) como en el archivo /vendor/etc/fstab.{ro.hardware} sin configuración adicional (ya que fs_mgr los crea en /mnt/vendor/* automáticamente).