El particionamiento dinámico se implementa con el módulo de asignación de dispositivos dm-linear en el kernel de Linux. La partición super
contiene metadatos que enumeran los nombres y los rangos de bloques de cada partición dinámica dentro de super
. Durante la primera etapa de init
, estos metadatos se analizan y validan, y se crean dispositivos de bloques virtuales para representar cada partición dinámica.
Cuando se aplica una OTA, las particiones dinámicas se crean automáticamente, se les cambia el tamaño o se borran según sea necesario. En el caso de los dispositivos A/B, hay dos copias de los metadatos y los cambios se aplican solo a la copia que representa la ranura de destino.
Dado que las particiones dinámicas se implementan en el espacio de usuario, las particiones que necesita el bootloader no pueden ser dinámicas. Por ejemplo, el bootloader lee boot
, dtbo
y vbmeta
, por lo que deben permanecer como particiones físicas.
Cada partición dinámica puede pertenecer a un grupo de actualizaciones. Estos grupos limitan el espacio máximo que pueden consumir las particiones de ese grupo.
Por ejemplo, system
y vendor
pueden pertenecer a un grupo que restringe el tamaño total de system
y vendor
.
Implementa particiones dinámicas en dispositivos nuevos
En esta sección, se explica cómo implementar particiones dinámicas en dispositivos nuevos que se lancen con Android 10 y versiones posteriores. Para actualizar dispositivos existentes, consulta Cómo actualizar dispositivos Android.
Cambios en las particiones
Para los dispositivos que se lanzan con Android 10, crea una partición llamada super
. La partición super
controla los ranuras A/B de forma interna, por lo que los dispositivos A/B no necesitan particiones super_a
y super_b
separadas.
Todas las particiones del AOSP de solo lectura que no use el bootloader deben ser dinámicas y se deben quitar de la tabla de particiones GUID (GPT).
Las particiones específicas del proveedor no tienen que ser dinámicas y se pueden colocar en el GPT.
Para estimar el tamaño de super
, agrega los tamaños de las particiones que se borrarán del GPT. En el caso de los dispositivos A/B, debe incluir el tamaño de ambas ranuras. En la Figura 1, se muestra un ejemplo de tabla de particiones antes y después de convertir a particiones dinámicas.
Las particiones dinámicas admitidas son las siguientes:
- Sistema
- Proveedor
- Producto
- Extensión del sistema
- ODM
En el caso de los dispositivos que se inician con Android 10, la opción de línea de comandos del kernel androidboot.super_partition
debe estar vacía para que el comando sysprop ro.boot.super_partition
esté vacío.
Alineación de particiones
Es posible que el módulo device-mapper funcione de manera menos eficiente si la partición super
no está alineada correctamente. La partición super
DEBE alinearse con el tamaño mínimo de la solicitud de E/S según lo determine la capa de bloques. De forma predeterminada, el sistema de compilación (a través de lpmake
, que genera la imagen de partición super
) supone que una alineación de 1 MiB es suficiente para cada partición dinámica. Sin embargo, los proveedores deben asegurarse de que la partición super
esté alineada de forma correcta.
Para determinar el tamaño de solicitud mínimo de un dispositivo de almacenamiento en bloques, puedes inspeccionar sysfs
. Por ejemplo:
# ls -l /dev/block/by-name/super lrwxrwxrwx 1 root root 16 1970-04-05 01:41 /dev/block/by-name/super -> /dev/block/sda17 # cat /sys/block/sda/queue/minimum_io_size 786432
Puedes verificar la alineación de la partición super
de una manera similar:
# cat /sys/block/sda/sda17/alignment_offset
El desplazamiento de alineación DEBE ser 0.
Cambios en la configuración del dispositivo
Para habilitar el particionamiento dinámico, agrega la siguiente marca en device.mk
:
PRODUCT_USE_DYNAMIC_PARTITIONS := true
Cambios en la configuración de la pizarra
Debes establecer el tamaño de la partición super
:
BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>
En los dispositivos A/B, el sistema de compilación muestra un error si el tamaño total de las imágenes de partición dinámica es más de la mitad del tamaño de la partición super
.
Puedes configurar la lista de particiones dinámicas de la siguiente manera. Para los dispositivos que usan grupos de actualización, enumera los grupos en la variable BOARD_SUPER_PARTITION_GROUPS
. Cada nombre de grupo tiene una variable BOARD_group_SIZE
y BOARD_group_PARTITION_LIST
.
En el caso de los dispositivos A/B, el tamaño máximo de un grupo debe cubrir solo un
espacio, ya que los nombres de los grupos tienen un sufijo de espacio de forma interna.
Este es un ejemplo de dispositivo que coloca todas las particiones en un grupo llamado example_dynamic_partitions
:
BOARD_SUPER_PARTITION_GROUPS := example_dynamic_partitions BOARD_EXAMPLE_DYNAMIC_PARTITIONS_SIZE := 6442450944 BOARD_EXAMPLE_DYNAMIC_PARTITIONS_PARTITION_LIST := system vendor product
Este es un ejemplo de dispositivo que coloca los servicios del sistema y del producto en group_foo
, y vendor
, product
y odm
en group_bar
:
BOARD_SUPER_PARTITION_GROUPS := group_foo group_bar BOARD_GROUP_FOO_SIZE := 4831838208 BOARD_GROUP_FOO_PARTITION_LIST := system product_services BOARD_GROUP_BAR_SIZE := 1610612736 BOARD_GROUP_BAR_PARTITION_LIST := vendor product odm
-
Para los dispositivos de lanzamiento de A/B virtual, la suma de los tamaños máximos de todos los grupos debe ser como máximo:
BOARD_SUPER_PARTITION_SIZE
- sobrecarga
Consulta Implementación de A/B virtual. -
Para los dispositivos de lanzamiento A/B, la suma de los tamaños máximos de todos los grupos debe ser:
BOARD_SUPER_PARTITION_SIZE
/ 2 - sobrecarga -
Para dispositivos que no son A/B y dispositivos A/B retroadaptados, la suma de los tamaños máximos de todos los grupos debe ser:
BOARD_SUPER_PARTITION_SIZE
- sobrecarga - En el tiempo de compilación, la suma de los tamaños de las imágenes de cada partición en un grupo de actualización no debe exceder el tamaño máximo del grupo.
- Se requiere sobrecarga en el procesamiento para tener en cuenta los metadatos, las alineaciones, etcétera. Una sobrecarga razonable es de 4 MiB, pero puedes elegir una sobrecarga mayor según las necesidades del dispositivo.
Cómo cambiar el tamaño de las particiones dinámicas
Antes de las particiones dinámicas, los tamaños de las particiones se asignaban en exceso a fin de garantizar que hubieran espacio suficiente para actualizaciones futuras. El tamaño real se tomó tal como estaba, y la mayoría de las particiones de solo lectura tenían cierta cantidad de espacio libre en su sistema de archivos. En las particiones dinámicas, ese espacio libre es inutilizable y se puede usar para aumentar las particiones durante una actualización OTA. Es fundamental asegurarse de que las particiones no desperdicien espacio y se asignen al tamaño mínimo posible.
Para las imágenes ext4 de solo lectura, el sistema de compilación asigna automáticamente el tamaño mínimo si no se especifica un tamaño de partición codificado. El sistema de compilación se ajusta a la imagen para que el sistema de archivos tenga el menor espacio sin usar posible. Esto garantiza que el dispositivo no desperdicie espacio que se puede usar para las actualizaciones OTA.
Además, las imágenes ext4 se pueden comprimir aún más si se habilita la anulación de duplicación a nivel de bloque. Para habilitar esta opción, usa la siguiente configuración:
BOARD_EXT4_SHARE_DUP_BLOCKS := true
Si no deseas la asignación automática de un tamaño mínimo de partición,
hay dos maneras de controlar el tamaño de la partición. Puedes especificar una cantidad mínima de espacio libre con BOARD_partitionIMAGE_PARTITION_RESERVED_SIZE
, o bien puedes especificar BOARD_partitionIMAGE_PARTITION_SIZE
para forzar particiones dinámicas a un tamaño específico. No se recomienda ninguna de estas opciones, a menos que sea necesario.
Por ejemplo:
BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800
Esto obliga al sistema de archivos en product.img
a tener 50 MiB de espacio sin usar.
Cambios de System-as-root
Los dispositivos que se lanzan con Android 10 no deben usar el sistema como raíz.
Los dispositivos con particiones dinámicas (ya sea que se inicien con particiones dinámicas o se adapten a ellas) no deben usar system-as-root. El kernel de Linux no puede interpretar la partición super
y, por lo tanto, no puede activar system
. system
ahora está activado por init
de primera etapa, que reside en el disco RAM.
No configures BOARD_BUILD_SYSTEM_ROOT_IMAGE
. En Android 10, la marca BOARD_BUILD_SYSTEM_ROOT_IMAGE
solo se usa para diferenciar si el sistema está activado por el kernel o por el init
de primera etapa en el disco RAM.
Configurar BOARD_BUILD_SYSTEM_ROOT_IMAGE
como true
provoca un error de compilación cuando PRODUCT_USE_DYNAMIC_PARTITIONS
también es true
.
Cuando BOARD_USES_RECOVERY_AS_BOOT
se establece como verdadero, la imagen de recuperación se compila como boot.img, que contiene el ramdisk de la recuperación. Anteriormente, el bootloader usaba el parámetro de línea de comandos del kernel skip_initramfs
para decidir en qué modo iniciar. En el caso de los dispositivos con Android 10, el bootloader NO DEBE pasar skip_initramfs
a la línea de comandos del kernel. En su lugar, el bootloader debe pasar androidboot.force_normal_boot=1
para omitir la recuperación e iniciar Android con normalidad. Los dispositivos que se lanzan con Android 12 o versiones posteriores deben usar bootconfig para pasar androidboot.force_normal_boot=1
.
Cambios en la configuración de AVB
Cuando se usa el inicio verificado de Android 2.0, si el dispositivo no usa descriptores de particiones encadenadas, no es necesario ningún cambio. Sin embargo, si se usan particiones en cadena y una de las particiones verificadas es dinámica, se deben realizar cambios.
A continuación, te mostramos una configuración de ejemplo para un dispositivo que encadena vbmeta
para las particiones system
y vendor
.
BOARD_AVB_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_SYSTEM_ALGORITHM := SHA256_RSA2048 BOARD_AVB_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_SYSTEM_ROLLBACK_INDEX_LOCATION := 1 BOARD_AVB_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_VENDOR_ALGORITHM := SHA256_RSA2048 BOARD_AVB_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_VENDOR_ROLLBACK_INDEX_LOCATION := 1
Con esta configuración, el bootloader espera encontrar un pie de página de vbmeta al final de las particiones system
y vendor
. Debido a que estas particiones ya no son visibles para el bootloader (residen en super
), se necesitan dos cambios.
-
Agrega las particiones
vbmeta_system
yvbmeta_vendor
a la tabla de particiones del dispositivo. Para dispositivos A/B, agregavbmeta_system_a
,vbmeta_system_b
,vbmeta_vendor_a
yvbmeta_vendor_b
. Si agregas una o más de estas particiones, deben tener el mismo tamaño que la particiónvbmeta
. -
Para cambiar el nombre de las marcas de configuración, agrega
VBMETA_
y especifica a qué particiones se extiende el encadenamiento:BOARD_AVB_VBMETA_SYSTEM := system BOARD_AVB_VBMETA_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_VBMETA_SYSTEM_ALGORITHM := SHA256_RSA2048 BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX_LOCATION := 1 BOARD_AVB_VBMETA_VENDOR := vendor BOARD_AVB_VBMETA_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_VBMETA_VENDOR_ALGORITHM := SHA256_RSA2048 BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX_LOCATION := 1
Un dispositivo puede usar una, ambas o ninguna de estas particiones. Los cambios solo son necesarios cuando se encadenan a una partición lógica.
Cambios en el bootloader de AVB
Si el bootloader tiene incorporada libavb, incluye los siguientes parches:
- 818cf56740775446285466eda984acedd4baeac0 — "libavb: Solo consulta los GUID de partición cuando la línea de comandos los necesite".
- 5abd6bc2578968d24406d834471adfd995a0c2e9 — "Permitir que no haya partición del sistema"
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 — “Corregir AvbSlotVerifyData->cmdline might be NULL”
Si usas particiones encadenadas, incluye un parche adicional:
- 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: Admite BLOBs de vbmeta al comienzo de la partición".
Cambios en la línea de comandos del kernel
Se debe agregar un parámetro nuevo, androidboot.boot_devices
, a la línea de comandos del kernel. init
lo usa para habilitar los symlinks de /dev/block/by-name
. Debe ser el componente de ruta de acceso del dispositivo al symlink subyacente por nombre que crea ueventd
, es decir, /dev/block/platform/device-path/by-name/partition-name
.
Los dispositivos que se lanzan con Android 12 o versiones posteriores deben usar bootconfig para pasar androidboot.boot_devices
a init
.
Por ejemplo, si el symlink por nombre de superpartición es /dev/block/platform/soc/100000.ufshc/by-name/super
, puedes agregar el parámetro de línea de comandos en el archivo BoardConfig.mk de la siguiente manera:
BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshc
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc
cambios fstab
El árbol de dispositivos y las superposiciones del árbol de dispositivos no deben contener entradas de fstab. Usa un archivo fstab que forme parte del ramdisk.
Se deben realizar cambios en el archivo fstab para las particiones lógicas:
-
El campo de marcas fs_mgr debe incluir la marca
logical
y la marcafirst_stage_mount
, que se introdujo en Android 10, que indica que se debe activar una partición en la primera etapa. -
Una partición puede especificar
avb=vbmeta partition name
como una marcafs_mgr
y, luego, la particiónvbmeta
especificada se inicializa en la primera etapa deinit
antes de intentar activar cualquier dispositivo. -
El campo
dev
debe ser el nombre de la partición.
Las siguientes entradas fstab establecen el sistema, el proveedor y el producto como particiones lógicas según las reglas anteriores.
#<dev> <mnt_point> <type> <mnt_flags options> <fs_mgr_flags> system /system ext4 ro,barrier=1 wait,slotselect,avb=vbmeta,logical,first_stage_mount vendor /vendor ext4 ro,barrier=1 wait,slotselect,avb,logical,first_stage_mount product /product ext4 ro,barrier=1 wait,slotselect,avb,logical,first_stage_mount
Copia el archivo fstab en el disco RAM de la primera etapa.
Cambios de SELinux
El dispositivo de bloques de superpartición debe estar marcado con la etiqueta super_block_device
. Por ejemplo, si el symlink de la superpartición por nombre es /dev/block/platform/soc/100000.ufshc/by-name/super
, agrega la siguiente línea a file_contexts
:
/dev/block/platform/soc/10000\.ufshc/by-name/super u:object_r:super_block_device:s0
fastbootd
El bootloader (o cualquier herramienta de actualización que no sea de espacio de usuario) no comprende las particiones dinámicas, por lo que no puede actualizarlas. Para solucionar este problema, los dispositivos deben usar una implementación del protocolo fastboot en el espacio de usuario, llamada fastbootd.
Para obtener más información sobre cómo implementar fastbootd, consulta Cómo mover Fastboot al espacio del usuario.
adb remount
Para los desarrolladores que usan compilaciones eng o userdebug, adb remount
es muy útil para la iteración rápida. Las particiones dinámicas representan un problema para adb remount
porque ya no hay espacio libre dentro de cada sistema de archivos. Para solucionar este problema, los dispositivos pueden habilitar overlayfs. Siempre que haya espacio libre dentro de la superpartición,
adb remount
crea automáticamente una partición dinámica
temporal y usa overlayfs para las operaciones de escritura. La partición temporal se llama scratch
, por lo que no debes usar este nombre para otras particiones.
Para obtener más información sobre cómo habilitar superposicionesfs, consulta el archivo overlayfs README en el AOSP.
Cómo actualizar dispositivos Android
Si actualizas un dispositivo a Android 10 y quieres incluir compatibilidad con particiones dinámicas en la actualización inalámbrica, no es necesario que cambies la tabla de particiones integrada. Se requiere configuración adicional.
Cambios en la configuración del dispositivo
Para adaptar el particionamiento dinámico, agrega las siguientes marcas en
device.mk
:
PRODUCT_USE_DYNAMIC_PARTITIONS := true PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true
Cambios en la configuración de la pizarra
Debes configurar las siguientes variables de la placa:
- Establece
BOARD_SUPER_PARTITION_BLOCK_DEVICES
en la lista de dispositivos de almacenamiento en bloque que se usan para almacenar extensiones de particiones dinámicas. Esta es la lista de nombres de las particiones físicas existentes en el dispositivo. - Establece
BOARD_SUPER_PARTITION_partition_DEVICE_SIZE
en los tamaños de cada dispositivo de almacenamiento en bloque enBOARD_SUPER_PARTITION_BLOCK_DEVICES
, respectivamente. Esta es la lista de los tamaños de las particiones físicas existentes en el dispositivo. Por lo general, esBOARD_partitionIMAGE_PARTITION_SIZE
en los parámetros de configuración de la placa existentes. - Anula el
BOARD_partitionIMAGE_PARTITION_SIZE
existente para todas las particiones enBOARD_SUPER_PARTITION_BLOCK_DEVICES
. - Establece
BOARD_SUPER_PARTITION_SIZE
en la suma deBOARD_SUPER_PARTITION_partition_DEVICE_SIZE
. - Establece
BOARD_SUPER_PARTITION_METADATA_DEVICE
en el dispositivo de almacenamiento en bloques en el que se almacenan los metadatos de la partición dinámica. Debe ser uno deBOARD_SUPER_PARTITION_BLOCK_DEVICES
. Por lo general, está configurado ensystem
. - Establece
BOARD_SUPER_PARTITION_GROUPS
,BOARD_group_SIZE
yBOARD_group_PARTITION_LIST
, respectivamente. Consulta Cambios en la configuración de la placa en dispositivos nuevos para obtener más información.
Por ejemplo, si el dispositivo ya tiene particiones del sistema y del proveedor, y deseas convertirlas en particiones dinámicas y agregar una partición de producto nueva durante la actualización, establece esta configuración de la placa:
BOARD_SUPER_PARTITION_BLOCK_DEVICES := system vendor BOARD_SUPER_PARTITION_METADATA_DEVICE := system # Rename BOARD_SYSTEMIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE. BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE := <size-in-bytes> # Rename BOARD_VENDORIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE := <size-in-bytes> # This is BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE + BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE BOARD_SUPER_PARTITION_SIZE := <size-in-bytes> # Configuration for dynamic partitions. For example: BOARD_SUPER_PARTITION_GROUPS := group_foo BOARD_GROUP_FOO_SIZE := <size-in-bytes> BOARD_GROUP_FOO_PARTITION_LIST := system vendor product
Cambios de SELinux
Los dispositivos de bloque de superpartición deben marcarse con el atributo super_block_device_type
. Por ejemplo, si el dispositivo ya tiene particiones system
y vendor
, quieres usarlas como dispositivos de almacenamiento en bloque para almacenar extensiones de particiones dinámicas, y sus symlinks por nombre están marcados como system_block_device
:
/dev/block/platform/soc/10000\.ufshc/by-name/system u:object_r:system_block_device:s0 /dev/block/platform/soc/10000\.ufshc/by-name/vendor u:object_r:system_block_device:s0
Luego, agrega la siguiente línea a device.te
:
typeattribute system_block_device super_block_device_type;
Para otras configuraciones, consulta Cómo implementar particiones dinámicas en dispositivos nuevos.
Para obtener más información sobre las actualizaciones de retrocompatibilidad, consulta OTA para dispositivos A/B sin particiones dinámicas.
Imágenes de fábrica
Para que un dispositivo se inicie con compatibilidad con particiones dinámicas, evita usar fastboot de espacio de usuario para escribir imágenes de fábrica, ya que el inicio en el espacio de usuario es más lento que otros métodos de escritura.
Para solucionar este problema, make dist
ahora compila una imagen super.img
adicional que se puede escribir directamente en la partición superior. Agrupa automáticamente el contenido de las particiones lógicas, lo que significa que contiene system.img
, vendor.img
, etcétera, además de los metadatos de la partición super
. Esta imagen se puede escribir directamente en la memoria flash de la partición super
sin ninguna herramienta adicional ni usar fastboot. Después de la compilación, super.img
se coloca en ${ANDROID_PRODUCT_OUT}
.
En el caso de los dispositivos A/B que se inician con particiones dinámicas, super.img
contiene imágenes en el espacio A. Después de escribir directamente en la memoria flash la superimagen, marca la ranura A como que se puede iniciar antes de reiniciar el dispositivo.
En el caso de los dispositivos de reacondicionamiento, make dist
compila un conjunto de imágenes super_*.img
que se pueden escribir directamente en las particiones físicas correspondientes. Por ejemplo, make dist
compila super_system.img
y super_vendor.img
cuando BOARD_SUPER_PARTITION_BLOCK_DEVICES
es el proveedor del sistema. Estas imágenes se colocan en la carpeta OTA en target_files.zip
.
Ajuste de dispositivo de almacenamiento del asignador de dispositivos
El particionamiento dinámico admite una serie de objetos de asignador de dispositivos no deterministas. Es posible que no se creen instancias de todos como se espera, por lo que debes hacer un seguimiento de todos los activaciones y actualizar las propiedades de Android de todas las particiones asociadas con sus dispositivos de almacenamiento subyacentes.
Un mecanismo dentro de init
realiza un seguimiento de las activaciones y actualiza de forma asíncrona las propiedades de Android. No se garantiza que el tiempo que esto tome sea dentro de un período específico, por lo que debes proporcionar suficiente tiempo para que todos los activadores de on property
reaccionen. Las propiedades son dev.mnt.blk.<partition>
, donde <partition>
es root
, system
, data
o vendor
, por ejemplo. Cada propiedad está asociada con el nombre del dispositivo de almacenamiento básico, como se muestra en estos ejemplos:
taimen:/ % getprop | grep dev.mnt.blk [dev.mnt.blk.data]: [sda] [dev.mnt.blk.firmware]: [sde] [dev.mnt.blk.metadata]: [sde] [dev.mnt.blk.persist]: [sda] [dev.mnt.blk.root]: [dm-0] [dev.mnt.blk.vendor]: [dm-1] blueline:/ $ getprop | grep dev.mnt.blk [dev.mnt.blk.data]: [dm-4] [dev.mnt.blk.metadata]: [sda] [dev.mnt.blk.mnt.scratch]: [sda] [dev.mnt.blk.mnt.vendor.persist]: [sdf] [dev.mnt.blk.product]: [dm-2] [dev.mnt.blk.root]: [dm-0] [dev.mnt.blk.system_ext]: [dm-3] [dev.mnt.blk.vendor]: [dm-1] [dev.mnt.blk.vendor.firmware_mnt]: [sda]
El lenguaje init.rc
permite que las propiedades de Android se expandan como parte de las reglas, y la plataforma puede ajustar los dispositivos de almacenamiento según sea necesario con comandos como los siguientes:
write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb 128 write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb 128
Una vez que se inicia el procesamiento de comandos en init
de segunda etapa, epoll loop
se activa y los valores comienzan a actualizarse. Sin embargo, debido a que los activadores de propiedades no están activos hasta finales de init
, no se pueden usar en las etapas de inicio iniciales para controlar root
, system
o vendor
. Es posible que el read_ahead_kb
predeterminado del kernel sea suficiente hasta que las secuencias de comandos init.rc
puedan anularse en early-fs
(cuando se inician varios demonios y servicios). Por lo tanto, Google recomienda que uses la función on property
, junto con una propiedad controlada por init.rc
, como sys.read_ahead_kb
, para controlar el tiempo de las operaciones y evitar condiciones de carrera, como en estos ejemplos:
on property:dev.mnt.blk.root=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on property:dev.mnt.blk.system=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.system}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on property:dev.mnt.blk.vendor=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.vendor}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on property:dev.mnt.blk.product=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.system_ext}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on property:dev.mnt.blk.oem=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.oem}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on property:dev.mnt.blk.data=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on early-fs: setprop sys.read_ahead_kb ${ro.read_ahead_kb.boot:-2048} on property:sys.boot_completed=1 setprop sys.read_ahead_kb ${ro.read_ahead_kb.bootcomplete:-128}