O particionamento dinâmico é implementado usando o módulo dm-linear device-mapper
no kernel do Linux. A partição super
contém
metadados que listam os nomes e intervalos de blocos de cada partição dinâmica
em super
. Durante a primeira etapa do init
, esses metadados são analisados e validados, e dispositivos de bloco virtual são criados para representar cada partição dinâmica.
Ao aplicar uma atualização OTA, as partições dinâmicas são criadas, redimensionadas ou excluídas automaticamente conforme necessário. Para dispositivos A/B, há duas cópias dos metadados, e as mudanças são aplicadas apenas à cópia que representa o slot de destino.
Como as partições dinâmicas são implementadas no espaço do usuário, as partições necessárias
pelo carregador de inicialização não podem ser dinâmicas. Por exemplo, boot
, dtbo
e vbmeta
são lidos pelo carregador de inicialização e, portanto, precisam permanecer como partições físicas.
Cada partição dinâmica pode pertencer a um grupo de atualização. Esses grupos limitam o espaço máximo que as partições podem consumir.
Por exemplo, system
e vendor
podem pertencer a um grupo que restringe o tamanho total de system
e vendor
.
Implementar partições dinâmicas em novos dispositivos
Esta seção detalha como implementar partições dinâmicas em novos dispositivos lançados com o Android 10 e versões mais recentes. Para atualizar dispositivos atuais, consulte Atualizar dispositivos Android.
Mudanças de partição
Para dispositivos lançados com o Android 10, crie
uma partição chamada super
. A partição super
processa slots A/B internamente. Por isso, os dispositivos A/B não precisam
de partições super_a
e super_b
separadas.
Todas as partições somente leitura do AOSP que não são usadas pelo carregador de inicialização precisam
ser dinâmicas e removidas da tabela de partição GUID (GPT).
As partições específicas do fornecedor não precisam ser dinâmicas e podem ser colocadas na GPT.
Para estimar o tamanho de super
, adicione os tamanhos das partições que estão sendo excluídas da GPT. Para dispositivos A/B, isso
inclui o tamanho dos dois slots. A Figura 1 mostra um exemplo de tabela de partição antes e depois da conversão para partições dinâmicas.

As partições dinâmicas compatíveis são:
- Sistema
- Fornecedor
- Produto
- System Ext
- ODM
Para dispositivos lançados com o Android 10, a
opção de linha de comando do kernel androidboot.super_partition
precisa estar vazia para que a sysprop de comando
ro.boot.super_partition
também esteja vazia.
Alinhamento de partições
O módulo device-mapper pode operar com menos eficiência se a
partição super
não estiver alinhada corretamente. A partição super
precisa estar alinhada ao tamanho mínimo da solicitação de E/S, conforme determinado pela camada de bloco. Por padrão, o sistema de build (via lpmake
, que gera a imagem de partição super
) pressupõe que um alinhamento de 1 MiB é suficiente para todas as partições dinâmicas. No entanto, os fornecedores precisam garantir que a partição super
esteja alinhada corretamente.
Para determinar o tamanho mínimo da solicitação de um dispositivo de bloco, inspecione sysfs
. Exemplo:
# 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
Você pode verificar o alinhamento da partição super
de maneira semelhante:
# cat /sys/block/sda/sda17/alignment_offset
O deslocamento de alinhamento PRECISA ser 0.
Mudanças na configuração do dispositivo
Para ativar o particionamento dinâmico, adicione a seguinte flag em
device.mk
:
PRODUCT_USE_DYNAMIC_PARTITIONS := true
Mudanças na configuração do board
É necessário definir o tamanho da partição super
:
BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>
Em dispositivos A/B, o sistema de build gera um erro se o tamanho total
das imagens de partição dinâmica for mais da metade do tamanho da partição
super
.
É possível configurar a lista de partições dinâmicas da seguinte maneira. Para
dispositivos que usam grupos de atualização, liste os grupos na
variável BOARD_SUPER_PARTITION_GROUPS
. Cada nome de grupo tem uma variável BOARD_group_SIZE
e BOARD_group_PARTITION_LIST
.
Para dispositivos A/B, o tamanho máximo de um grupo deve abranger apenas um slot, já que os nomes dos grupos têm um sufixo de slot internamente.
Confira um exemplo de dispositivo que coloca todas as partições em um grupo
chamado 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
Confira um exemplo de dispositivo que coloca serviços de sistema e de produto em
group_foo
e vendor
, product
,
e odm
em 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 dispositivos de lançamento do A/B virtual, a soma dos tamanhos máximos de todos os grupos precisa ser, no máximo:
BOARD_SUPER_PARTITION_SIZE
- overhead
. Consulte Como implementar o A/B virtual. -
Para dispositivos de lançamento A/B, a soma dos tamanhos máximos de todos os grupos precisa ser:
BOARD_SUPER_PARTITION_SIZE
/ 2 - overhead -
Para dispositivos não A/B e A/B adaptados, a soma dos tamanhos máximos de todos os grupos precisa ser:
BOARD_SUPER_PARTITION_SIZE
- sobrecarga - No momento da build, a soma dos tamanhos das imagens de cada partição em um grupo de atualização não pode exceder o tamanho máximo do grupo.
- O overhead é necessário no cálculo para considerar metadados, alinhamentos e assim por diante. Um overhead razoável é de 4 MiB, mas você pode escolher um overhead maior conforme necessário para o dispositivo.
Dimensionar partições dinâmicas
Antes das partições dinâmicas, os tamanhos eram alocados em excesso para garantir espaço suficiente para atualizações futuras. O tamanho real foi usado como está, e a maioria das partições somente leitura tinha algum espaço livre no sistema de arquivos. Em partições dinâmicas, esse espaço livre é inutilizável e pode ser usado para aumentar as partições durante uma OTA. É fundamental garantir que as partições não estejam desperdiçando espaço e que sejam alocadas para um tamanho mínimo possível.
Para imagens ext4 somente leitura, o sistema de build aloca automaticamente o tamanho mínimo se nenhum tamanho de partição codificado for especificado. O sistema de build ajusta a imagem para que o sistema de arquivos tenha o menor espaço livre possível. Isso garante que o dispositivo não desperdice espaço que pode ser usado para OTAs.
Além disso, as imagens ext4 podem ser ainda mais compactadas ativando a deduplicação no nível do bloco. Para ativar isso, use a seguinte configuração:
BOARD_EXT4_SHARE_DUP_BLOCKS := true
Se a alocação automática de um tamanho mínimo de partição não for desejável, há duas maneiras de controlar o tamanho da partição. É possível especificar um
valor mínimo de espaço livre com
BOARD_partitionIMAGE_PARTITION_RESERVED_SIZE
,
ou especificar
BOARD_partitionIMAGE_PARTITION_SIZE
para forçar
partições dinâmicas a um tamanho específico. Nenhuma delas é recomendada, a menos que seja necessário.
Exemplo:
BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800
Isso força o sistema de arquivos em product.img
a ter 50 MiB de espaço não utilizado.
Mudanças no sistema como raiz
Os dispositivos lançados com o Android 10 não podem usar o sistema como raiz.
Dispositivos com partições dinâmicas (seja no lançamento ou em adaptações
de partições dinâmicas) não podem usar o sistema como raiz. O kernel do Linux não consegue interpretar a partição super
e, portanto, não pode ativar system
. Agora, system
é montado pelo
init
da primeira etapa, que reside no ramdisk.
Não defina BOARD_BUILD_SYSTEM_ROOT_IMAGE
. No Android 10, a flag BOARD_BUILD_SYSTEM_ROOT_IMAGE
é usada apenas para diferenciar se o sistema é montado pelo kernel ou pelo init
de primeiro estágio no ramdisk.
Definir BOARD_BUILD_SYSTEM_ROOT_IMAGE
como true
causa um erro de build quando
PRODUCT_USE_DYNAMIC_PARTITIONS
também é true
.
Quando BOARD_USES_RECOVERY_AS_BOOT
é definido como "true", a imagem de recuperação é criada como boot.img, contendo o ramdisk de recuperação. Antes, o carregador de inicialização usava o parâmetro de linha de comando do kernel skip_initramfs
para decidir em qual modo inicializar. Para
dispositivos Android 10, o carregador de inicialização NÃO PODE transmitir
skip_initramfs
para a linha de comando do kernel. Em vez disso, o carregador de inicialização
precisa transmitir androidboot.force_normal_boot=1
para pular a recuperação
e inicializar o Android normalmente. Os dispositivos lançados com o Android 12
ou versões mais recentes precisam usar o bootconfig para transmitir androidboot.force_normal_boot=1
.
Mudanças na configuração do AVB
Ao usar a Inicialização verificada do Android 2.0, se o dispositivo não estiver usando descritores de partição encadeados, não será necessário fazer nenhuma mudança. No entanto, se você estiver usando partições encadeadas e uma das partições verificadas for dinâmica, será necessário fazer mudanças.
Confira um exemplo de configuração para um dispositivo que encadeia
vbmeta
para as partições system
e
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
Com essa configuração, o carregador de inicialização espera encontrar um rodapé vbmeta no final das partições system
e vendor
. Como essas partições não estão mais visíveis para o carregador de inicialização (elas residem em super
), duas mudanças são necessárias.
-
Adicione as partições
vbmeta_system
evbmeta_vendor
à tabela de partições do dispositivo. Para dispositivos A/B, adicionevbmeta_system_a
,vbmeta_system_b
,vbmeta_vendor_a
evbmeta_vendor_b
. Se você adicionar uma ou mais dessas partições, elas precisarão ter o mesmo tamanho da partiçãovbmeta
. -
Renomeie as flags de configuração adicionando
VBMETA_
e especifique a quais partições o encadeamento se estende: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
Um dispositivo pode usar uma, ambas ou nenhuma dessas partições. As mudanças só são necessárias ao encadear a uma partição lógica.
Mudanças no carregador de inicialização do AVB
Se o carregador de inicialização tiver o libavb incorporado, inclua os seguintes patches:
- 818cf56740775446285466eda984acedd4baeac0 — "libavb: Only query partition GUIDs when the cmdline needs them."
- 5abd6bc2578968d24406d834471adfd995a0c2e9 — "Permitir que a partição do sistema esteja ausente"
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 — "Fix AvbSlotVerifyData->cmdline might be NULL"
Se você estiver usando partições encadeadas, inclua outro patch:
- 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: Support vbmeta blobs in beginning of partition."
Mudanças na linha de comando do kernel
Um novo parâmetro, androidboot.boot_devices
, precisa ser adicionado
à linha de comando do kernel. Usado por init
para
ativar symlinks /dev/block/by-name
. Ele precisa ser o
componente de caminho do dispositivo para o link simbólico subjacente criado por
ueventd
, ou seja,
/dev/block/platform/device-path/by-name/partition-name
.
Os dispositivos lançados com o Android 12 ou versões mais recentes precisam usar
o bootconfig para transmitir androidboot.boot_devices
para init
.
Por exemplo, se o symlink da superpartição por nome for
/dev/block/platform/soc/100000.ufshc/by-name/super
,
adicione o parâmetro de linha de comando no arquivo BoardConfig.mk da seguinte forma:
BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshc
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc
mudanças no fstab
A árvore de dispositivos e as sobreposições da árvore de dispositivos não podem conter entradas fstab. Use um arquivo fstab que fará parte do ramdisk.
As mudanças precisam ser feitas no arquivo fstab para partições lógicas:
-
O campo de flags do fs_mgr precisa incluir a flag
logical
e a flagfirst_stage_mount
, introduzida no Android 10, que indica que uma partição será montada na primeira etapa. -
Uma partição pode especificar
avb=vbmeta partition name
como uma flagfs_mgr
. Em seguida, a partiçãovbmeta
especificada é inicializada pela primeira etapainit
antes de tentar montar qualquer dispositivo. -
O campo
dev
precisa ser o nome da partição.
As entradas fstab a seguir definem o sistema, o fornecedor e o produto como partições lógicas de acordo com as regras acima.
#<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
Copie o arquivo fstab para o ramdisk da primeira etapa.
Mudanças no SELinux
O dispositivo de bloco de superpartição precisa ser marcado com o rótulo
super_block_device
. Por exemplo, se o link simbólico da superpartição por nome for
/dev/block/platform/soc/100000.ufshc/by-name/super
,
adicione a seguinte linha a file_contexts
:
/dev/block/platform/soc/10000\.ufshc/by-name/super u:object_r:super_block_device:s0
fastbootd
O carregador de inicialização (ou qualquer ferramenta de atualização não relacionada ao espaço do usuário) não entende partições dinâmicas e, portanto, não pode atualizá-las. Para resolver isso, os dispositivos precisam usar uma implementação do protocolo fastboot no espaço do usuário, chamada fastbootd.
Para mais informações sobre como implementar o fastbootd, consulte Como mover o fastboot para o espaço do usuário.
adb remount
Para desenvolvedores que usam builds eng ou userdebug, adb remount
é extremamente útil para iteração rápida. As partições dinâmicas causam um problema para o adb remount
porque não há mais espaço livre em cada sistema de arquivos. Para resolver isso, os dispositivos podem ativar o overlayfs. Enquanto houver espaço livre na superpartição, o
adb remount
vai criar automaticamente uma partição
dinâmica temporária e usar o overlayfs para gravações. A partição temporária é chamada de scratch
. Não use esse nome para outras partições.
Para mais informações sobre como ativar o overlayfs, consulte o README do overlayfs (link em inglês) no AOSP.
Fazer upgrade de dispositivos Android
Se você fizer upgrade de um dispositivo para o Android 10 e quiser incluir suporte a partições dinâmicas no OTA, não será necessário mudar a tabela de partição integrada. É necessário fazer algumas configurações extras.
Mudanças na configuração do dispositivo
Para adaptar a partição dinâmica, adicione as seguintes flags em
device.mk
:
PRODUCT_USE_DYNAMIC_PARTITIONS := true PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true
Mudanças na configuração do board
É necessário definir as seguintes variáveis de placa:
- Defina
BOARD_SUPER_PARTITION_BLOCK_DEVICES
como a lista de dispositivos de bloco usados para armazenar extensões de partições dinâmicas. Esta é a lista de nomes das partições físicas existentes no dispositivo. - Defina
BOARD_SUPER_PARTITION_partition_DEVICE_SIZE
como os tamanhos de cada dispositivo de bloco emBOARD_SUPER_PARTITION_BLOCK_DEVICES
, respectivamente. Esta é a lista de tamanhos das partições físicas atuais no dispositivo. Geralmente, éBOARD_partitionIMAGE_PARTITION_SIZE
nas configurações de quadro atuais. - Remova o
BOARD_partitionIMAGE_PARTITION_SIZE
atual de todas as partições emBOARD_SUPER_PARTITION_BLOCK_DEVICES
. - Defina
BOARD_SUPER_PARTITION_SIZE
como a soma deBOARD_SUPER_PARTITION_partition_DEVICE_SIZE
. - Defina
BOARD_SUPER_PARTITION_METADATA_DEVICE
como o dispositivo de bloco em que os metadados de partição dinâmica são armazenados. Ele precisa ser um dosBOARD_SUPER_PARTITION_BLOCK_DEVICES
. Normalmente, isso é definido comosystem
. - Defina
BOARD_SUPER_PARTITION_GROUPS
,BOARD_group_SIZE
eBOARD_group_PARTITION_LIST
, respectivamente. Consulte Mudanças na configuração da placa em novos dispositivos para mais detalhes.
Por exemplo, se o dispositivo já tiver partições do sistema e do fornecedor, e você quiser convertê-las em partições dinâmicas e adicionar uma nova partição de produto durante a atualização, defina esta configuração de 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
Mudanças no SELinux
Os dispositivos de bloco de superpartição precisam ser marcados com o atributo
super_block_device_type
. Por exemplo, se o dispositivo já tiver partições
system
e vendor
, use-as como dispositivos
de bloco para armazenar extensões de partições dinâmicas, e os symlinks por nome delas serão 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
Em seguida, adicione a seguinte linha a device.te
:
typeattribute system_block_device super_block_device_type;
Para outras configurações, consulte Implementar partições dinâmicas em novos dispositivos.
Para mais informações sobre atualizações de adaptação, consulte OTA para dispositivos A/B sem partições dinâmicas.
Imagens de fábrica
Para um dispositivo lançado com suporte a partições dinâmicas, evite usar o fastboot do espaço do usuário para atualizar imagens de fábrica, já que a inicialização no espaço do usuário é mais lenta do que outros métodos de atualização.
Para resolver isso, o make dist
agora cria uma imagem super.img
adicional que pode ser gravada diretamente na partição super. Ele agrupa automaticamente o conteúdo das partições lógicas, ou seja, contém system.img
, vendor.img
e assim por diante, além dos metadados de partição super
. Essa imagem pode ser gravada diretamente na partição
super
sem ferramentas adicionais ou usando
fastbootd. Depois do build, super.img
é colocado em
${ANDROID_PRODUCT_OUT}
.
Para dispositivos A/B lançados com partições dinâmicas,
super.img
contém imagens no slot A. Depois de fazer o flash da imagem
diretamente, marque o slot A como inicializável antes de reiniciar o
dispositivo.
Para dispositivos de adaptação, o make dist
cria um conjunto de
imagens super_*.img
que podem ser atualizadas diretamente para
partições físicas correspondentes. Por exemplo, make dist
cria super_system.img
e super_vendor.img
quando BOARD_SUPER_PARTITION_BLOCK_DEVICES
é o fornecedor
do sistema. Essas imagens são colocadas na pasta OTA em
target_files.zip
.
Ajuste do dispositivo de armazenamento do mapeador de dispositivos
O particionamento dinâmico acomoda vários objetos não determinísticos do mapeador de dispositivos. Nem todos podem ser instanciados como esperado. Por isso, é necessário rastrear todas as montagens e atualizar as propriedades do Android de todas as partições associadas com os dispositivos de armazenamento subjacentes.
Um mecanismo dentro de init
rastreia as montagens e atualiza de forma assíncrona
as propriedades do Android. O tempo necessário para isso não é garantido em um período específico. Portanto, você precisa dar tempo suficiente para que todos os gatilhos on property
reajam. As propriedades são
dev.mnt.blk.<partition>
em que
<partition>
é root
,
system
, data
ou
vendor
, por exemplo. Cada propriedade está associada ao nome do dispositivo de armazenamento base, conforme mostrado nestes exemplos:
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]
A linguagem init.rc
permite que as propriedades do Android sejam expandidas como parte das regras, e os dispositivos de armazenamento podem ser ajustados pela plataforma conforme necessário com comandos como estes:
write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb 128 write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb 128
Quando o processamento de comandos começa no init
de segunda etapa, o
epoll loop
fica ativo, e os valores começam a ser atualizados. No entanto, como os gatilhos de propriedade não ficam ativos até o final do init
, eles não podem ser usados nas etapas iniciais de inicialização para processar root
, system
ou vendor
. Você pode esperar que o read_ahead_kb
padrão do kernel seja suficiente até que os scripts init.rc
possam substituir em early-fs
(quando vários daemons e recursos são iniciados). Portanto, o Google recomenda que você use o recurso on property
, juntamente com uma propriedade controlada por init.rc
, como sys.read_ahead_kb
, para lidar com o tempo das operações e evitar condições de corrida, como nestes exemplos:
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}