Fastboot é o nome de um módulo e modo do carregador de inicialização. O Android 10 e versões mais recentes oferecem suporte a partições redimensionáveis realocando a implementação do fastboot do carregador de inicialização para o espaço do usuário. Essa realocação permite mover o código de atualização para um local comum que pode ser mantido e testado, com apenas as partes específicas do fornecedor do fastboot implementadas por uma camada de abstração de hardware (HAL, na sigla em inglês). Além disso, o Android 12 e versões mais recentes oferecem suporte à atualização de ramdisks usando um comando fastboot adicionado.
Unificar fastboot e recuperação
Como o fastboot e a recuperação do espaço do usuário são semelhantes, é possível mesclá-los em uma partição ou binário. Isso oferece vantagens, como usar menos espaço, ter menos partições no geral e compartilhar o kernel e as bibliotecas do fastboot e da recuperação.
Fastbootd é o nome de um daemon e modo do espaço do usuário.
Para oferecer suporte ao fastbootd, o carregador de inicialização precisa implementar um novo comando de bloco de controle de inicialização (BCB, na sigla em inglês) de boot-fastboot. Para entrar no modo fastbootd, o carregador de inicialização grava boot-fastboot no campo de comando da mensagem BCB e deixa o campo recovery do BCB inalterado (para permitir a reinicialização de tarefas de recuperação interrompidas). Os campos status, stage e reserved também permanecem inalterados.
O carregador de inicialização carrega e inicializa a imagem de recuperação ao encontrar boot-fastboot no campo de comando do BCB. Em seguida, a recuperação analisa a mensagem BCB e muda para o modo fastbootd.
Comandos ADB
Esta seção descreve o comando adb para integrar o fastbootd. O comando tem resultados diferentes, dependendo de quem o executa: o sistema ou a recuperação.
| Comando | Descrição |
|---|---|
reboot fastboot |
|
Comandos fastboot
Esta seção descreve os comandos fastboot para integrar o fastbootd, incluindo novos comandos para atualizar e gerenciar partições lógicas. Alguns comandos têm resultados diferentes, dependendo de quem os executa: o carregador de inicialização ou o fastbootd.
| Comando | Descrição |
|---|---|
reboot recovery |
|
reboot fastboot |
Reinicializa no fastbootd. |
getvar is-userspace |
|
getvar is-logical:<partition> |
Retorna yes se a partição fornecida for lógica.
no Caso contrário.
As partições lógicas oferecem suporte a todos os comandos listados abaixo. |
getvar super-partition-name |
Retorna o nome da superpartição. O nome inclui o sufixo do slot atual se a superpartição for uma partição A/B (geralmente não é). |
create-logical-partition <partition> <size> |
Cria uma partição lógica com o nome e o tamanho especificados. O nome não pode existir como uma partição lógica. |
delete-logical-partition <partition> |
Exclui a partição lógica especificada (limpa a partição). |
resize-logical-partition <partition> <size> |
Redimensiona a partição lógica para o novo tamanho sem alterar o conteúdo. Falha se não houver espaço suficiente disponível para realizar o redimensionamento. |
flash <partition> [ <filename> ] |
Grava um arquivo em uma partição flash. O dispositivo precisa estar desbloqueado. |
erase <partition> |
Apaga uma partição (não é necessário que seja uma exclusão segura). O dispositivo precisa estar desbloqueado. |
getvar <variable> | all |
Mostra uma variável do carregador de inicialização ou todas as variáveis. Se a variável não existir, retorna um erro. |
set_active <slot> |
Define o slot de inicialização A/B especificado como Para oferecer suporte a A/B, os slots são conjuntos duplicados de partições que podem ser inicializadas de forma independente. Os slots são chamados de |
reboot |
Reinicializa o dispositivo normalmente. |
reboot-bootloader (ou reboot bootloader) |
Reinicializa o dispositivo no carregador de inicialização. |
fastboot fetch vendor_boot <out.img> |
Use no Android 12 e versões mais recentes para oferecer suporte à atualização de ramdisks do fornecedor.
Recebe o tamanho total da partição e o tamanho do bloco. Recebe dados de cada bloco,
e os une a
Para mais detalhes, consulte |
fastboot flash vendor_boot:default <vendor-ramdisk.img> |
Use no Android 12 e versões mais recentes para oferecer suporte à atualização de ramdisks do fornecedor. Essa é uma variante especial do comando flash. Ele executa uma função de imagem
Para mais detalhes, consulte
|
fastboot flash vendor_boot:<foo> <vendor-ramdisk.img> |
Use no Android 12 e versões mais recentes para
oferecer suporte à atualização de ramdisks do fornecedor. Busca a imagem Para mais detalhes, consulte
|
Fastboot e carregador de inicialização
O carregador de inicialização atualiza as partições bootloader, radio e boot/recovery. Depois disso, o dispositivo é inicializado no fastboot (espaço do usuário) e atualiza todas as outras partições. O carregador de inicialização precisa oferecer suporte aos comandos a seguir.
| Comando | Descrição |
|---|---|
download |
Faz o download da imagem para atualizar. |
flash recovery <image>/ flash boot <image>/ flash
bootloader <image>/ |
Atualiza a partição recovery/boot e o carregador de inicialização. |
reboot |
Reinicializa o dispositivo. |
reboot fastboot |
Reinicializa no fastboot. |
reboot recovery |
Reinicializa na recuperação. |
getvar |
Recebe uma variável do carregador de inicialização necessária para a atualização da imagem de recuperação/inicialização (por exemplo, current-slot e max-download-size). |
oem <command> |
Comando definido pelo OEM. |
Partições dinâmicas
O carregador de inicialização não pode permitir a atualização ou exclusão de partições dinâmicas e precisa retornar um erro se essas operações forem tentadas. Para dispositivos com partições dinâmicas adaptadas, a ferramenta fastboot (e o carregador de inicialização) oferece suporte a um modo forçado para atualizar diretamente uma partição dinâmica no modo do carregador de inicialização. Por
exemplo, se system for uma partição dinâmica no dispositivo adaptado,
o uso do comando fastboot --force flash system vai permitir que o carregador de inicialização
(em vez de fastbootd) atualize a partição.
Carregamento no modo off
Se um dispositivo oferecer suporte ao carregamento no modo off ou for inicializado automaticamente em um modo especial quando a energia é aplicada, uma implementação do comando fastboot oem off-mode-charge 0 precisará ignorar esses modos especiais para que o dispositivo seja inicializado como se o usuário tivesse pressionado o botão liga/desliga.
HAL do OEM do fastboot
Para substituir completamente o fastboot do carregador de inicialização, o fastboot precisa processar todos os comandos fastboot atuais. Muitos desses comandos são de OEMs e estão documentados, mas exigem uma implementação personalizada. Muitos comandos específicos do OEM não estão documentados. Para processar esses comandos, o HAL do fastboot especifica os comandos OEM necessários. Os OEMs também podem implementar os próprios comandos.
A definição do HAL do fastboot é a seguinte:
import IFastbootLogger;
/**
* IFastboot interface implements vendor specific fastboot commands.
*/
interface IFastboot {
/**
* Returns a bool indicating whether the bootloader is enforcing verified
* boot.
*
* @return verifiedBootState True if the bootloader is enforcing verified
* boot and False otherwise.
*/
isVerifiedBootEnabled() generates (bool verifiedBootState);
/**
* Returns a bool indicating the off-mode-charge setting. If off-mode
* charging is enabled, the device autoboots into a special mode when
* power is applied.
*
* @return offModeChargeState True if the setting is enabled and False if
* not.
*/
isOffModeChargeEnabled() generates (bool offModeChargeState);
/**
* Returns the minimum battery voltage required for flashing in mV.
*
* @return batteryVoltage Minimum battery voltage (in mV) required for
* flashing to be successful.
*/
getBatteryVoltageFlashingThreshold() generates (int32_t batteryVoltage);
/**
* Returns the file system type of the partition. This is only required for
* physical partitions that need to be wiped and reformatted.
*
* @return type Can be ext4, f2fs or raw.
* @return result SUCCESS if the operation is successful,
* FAILURE_UNKNOWN if the partition is invalid or does not require
* reformatting.
*/
getPartitionType(string partitionName) generates (FileSystemType type, Result result);
/**
* Executes a fastboot OEM command.
*
* @param oemCmd The oem command that is passed to the fastboot HAL.
* @response result Returns the status SUCCESS if the operation is
* successful,
* INVALID_ARGUMENT for bad arguments,
* FAILURE_UNKNOWN for an invalid/unsupported command.
*/
doOemCommand(string oemCmd) generates (Result result);
};
Ativar o fastbootd
Para ativar o fastbootd em um dispositivo:
Adicione
fastbootdaPRODUCT_PACKAGESemdevice.mk:PRODUCT_PACKAGES += fastbootd.Verifique se o HAL do fastboot, o HAL de controle de inicialização e o HAL de integridade estão empacotados como parte da imagem de recuperação.
Adicione as permissões SEPolicy específicas do dispositivo exigidas pelo
fastbootd. Por exemplo, ofastbootdexige acesso de gravação a uma partição específica do dispositivo para atualizar essa partição. Além disso, a implementação do HAL do fastboot também pode exigir permissões específicas do dispositivo.
Para validar o fastboot do espaço do usuário, execute o Vendor Test Suite (VTS).
Atualizar ramdisks do fornecedor
O Android 12 e versões mais recentes oferecem suporte à atualização de ramdisks com um comando fastboot adicionado que extrai a imagem vendor_boot completa de um dispositivo. O comando solicita que a ferramenta fastboot no lado do host leia o cabeçalho de inicialização do fornecedor, recrie a imagem e a atualize.
Para extrair a imagem vendor_boot completa, o comando fetch:vendor_boot foi adicionado
ao protocolo fastboot e à implementação fastbootd do protocolo
no Android 12. O fastbootd implementa isso, mas o carregador de inicialização em si pode não fazer isso. Os OEMs podem adicionar o comando fetch:vendor_boot à implementação do protocolo do carregador de inicialização. No entanto, se o comando não for reconhecido no modo do carregador de inicialização, a atualização de ramdisks individuais do fornecedor nesse modo não será uma opção com suporte do fornecedor.
Mudanças no carregador de inicialização
Os comandos getvar:max-fetch-size e fetch:name são implementados no fastbootd. Para oferecer suporte à atualização de ramdisks do fornecedor no carregador de inicialização, é necessário implementar esses dois comandos.
Mudanças no fastbootd
getvar:max-fetch-size é semelhante a max-download-size. Ele especifica o tamanho máximo que o dispositivo pode enviar em uma resposta DATA. O driver não pode buscar um tamanho maior que esse valor.
fetch:name[:offset[:size]] realiza uma série de verificações no dispositivo. Se todas as condições a seguir forem verdadeiras, o comando fetch:name[:offset[:size]] vai retornar dados:
- O dispositivo está executando um build depurável.
- O dispositivo está desbloqueado (estado de inicialização laranja).
- O nome da partição buscada é
vendor_boot. - O valor
sizeestá dentro de 0 <size<=max-fetch-size.
Quando esses valores são verificados, fetch:name[:offset[:size]] retorna o tamanho e o deslocamento da partição.
Observe o seguinte:
fetch:nameé equivalente afetch:name:0, que é equivalente afetch:name:0:partition_size.fetch:name:offseté equivalente afetch:name:offset:(partition_size - offset)
Portanto, fetch:name[:offset[:size]] = fetch:name:offset:(partition_size - offset).
Quando offset ou partition_size (ou ambos) não são especificados, os
valores padrão são usados. Para offset, o valor é 0 e, para size, o
valor calculado de partition_size - offset.
- Deslocamento especificado, tamanho não especificado:
size = partition_size - offset - Nenhum especificado: valores padrão usados para ambos,
size = partition_size- 0.
Por exemplo, fetch:foo busca a partição foo inteira no deslocamento 0.
Mudanças no driver
Comandos foram adicionados à ferramenta fastboot para implementar mudanças no driver. Cada um está vinculado à definição completa na tabela de comandos fastboot.
fastboot fetch vendor_boot out.img- Chama
getvar max-fetch-sizepara determinar o tamanho do bloco. - Chama
getvar partition-size:vendor_boot[_a]para determinar o tamanho da partição inteira. - Chama
fastboot fetch vendor_boot[_a]:offset:sizepara cada bloco. (O tamanho do bloco é maior que o tamanhovendor_boot, então normalmente há apenas um bloco.) - Une os dados a
out.img.
- Chama
fastboot flash vendor_boot:default vendor-ramdisk.imgEssa é uma variante especial do comando flash. Ele busca a
vendor_bootimagem, como sefastboot fetchfosse chamado.- Se a inicialização do fornecedor for a versão 3
do cabeçalho,
ela vai fazer o seguinte:
- Substitui o ramdisk do fornecedor pela imagem fornecida.
- Atualiza a nova imagem
vendor_boot.
- Se a inicialização do fornecedor for a versão 3
do cabeçalho,
ela vai fazer o seguinte:
- Se o cabeçalho de inicialização do fornecedor for a versão
4,
ele vai fazer o seguinte:
- Substitui todo o ramdisk do fornecedor pela imagem fornecida para que a imagem fornecida se torne o único fragmento de ramdisk do fornecedor na imagem
vendor_boot. - Recalcula o tamanho e o deslocamento na tabela de ramdisk do fornecedor.
- Atualiza a nova imagem
vendor_boot.
- Substitui todo o ramdisk do fornecedor pela imagem fornecida para que a imagem fornecida se torne o único fragmento de ramdisk do fornecedor na imagem
fastboot flash vendor_boot:foo vendor-ramdisk.img
Busca a vendor_boot image, como se fastboot fetch fosse chamado.
- Se o cabeçalho de inicialização do fornecedor for a versão 3, ele vai retornar um erro.
Se o cabeçalho de inicialização do fornecedor for a versão 4, ele vai fazer o seguinte:
- Encontra o fragmento de ramdisk do fornecedor com o nome
ramdisk_<var><foo></var>. Se não for encontrado ou se houver várias correspondências, retorna um erro. - Substitui o fragmento de ramdisk do fornecedor pela imagem fornecida.
- Recalcula cada tamanho e deslocamento na tabela de ramdisk do fornecedor.
- Atualiza a nova imagem
vendor_boot.
- Encontra o fragmento de ramdisk do fornecedor com o nome
Se <foo> não for especificado, ele vai tentar encontrar
ramdisk_.
mkbootimg
O nome default é reservado para nomear fragmentos de ramdisk do fornecedor no Android 12 e versões mais recentes. Embora a flash vendor_boot:default
semântica do fastboot permaneça a mesma, você não nomeie os fragmentos de ramdisk como
default.
Mudanças no SELinux
Uma mudança foi feita em
fastbootd.te
para oferecer suporte à atualização de ramdisks do fornecedor.