Mover Fastboot al espacio de usuario

Android 10 y versiones posteriores admiten particiones redimensionables mediante la reubicación de la implementación de fastboot del gestor de arranque al espacio de usuario. Esta reubicación permite mover el código intermitente a una ubicación común comprobable y mantenible con solo las partes específicas del proveedor de fastboot implementadas por una capa de abstracción de hardware (HAL). Además, Android 12 y versiones posteriores admiten ramdisks flash a través de un comando fastboot agregado.

Unificación de arranque rápido y recuperación

Debido a que el inicio rápido y la recuperación del espacio de usuario son similares, puede fusionarlos en una partición o binario. Esto proporciona ventajas como usar menos espacio, tener menos particiones en general y hacer que fastboot y recovery compartan su kernel y bibliotecas.

Para admitir fastbootd , el cargador de arranque debe implementar un nuevo comando de bloque de control de arranque (BCB) de boot-fastboot . Para ingresar al modo fastbootd , el cargador de arranque escribe boot-fastboot en el campo de comando del mensaje BCB y deja el campo de recovery de BCB sin cambios (para permitir reiniciar cualquier tarea de recuperación interrumpida). Los campos de status , stage y reserved también permanecen sin cambios. El cargador de arranque carga y arranca en la imagen de recuperación al ver boot-fastboot en el campo de comando BCB. Luego, la recuperación analiza el mensaje BCB y cambia al modo fastbootd .

Comandos BAD

Esta sección describe el comando adb para integrar fastbootd . El comando tiene diferentes resultados, dependiendo de si es ejecutado por sistema o por recuperación.

Mando Descripción
reboot fastboot
  • Reinicia en fastbootd (sistema).
  • Ingresa fastbootd directamente sin reiniciar (recuperación).

Comandos de arranque rápido

Esta sección describe los comandos de fastboot para integrar fastbootd , incluidos los nuevos comandos para flashear y administrar particiones lógicas. Algunos comandos tienen resultados diferentes, dependiendo de si han sido ejecutados por bootloader o fastbootd .

Mando Descripción
reboot recovery
  • Se reinicia en recuperación (gestor de arranque).
  • Entra en la recuperación directamente sin reiniciar ( fastbootd ).
reboot fastboot Reinicia en fastbootd .
getvar is-userspace
  • Devuelve yes ( fastbootd ).
  • Devuelve no (gestor de arranque).
getvar is-logical: <partition> Devuelve yes si la partición dada es una partición lógica, no de lo contrario. Las particiones lógicas admiten todos los comandos que se enumeran a continuación.
getvar super-partition-name Devuelve el nombre de la superpartición. El nombre incluye el sufijo de ranura actual si la súper partición es una partición A/B (normalmente no lo es).
create-logical-partition <partition> <size> Crea una partición lógica con el nombre y el tamaño indicados. El nombre no debe existir ya como una partición lógica.
delete-logical-partition <partition> Elimina la partición lógica dada (borra efectivamente la partición).
resize-logical-partition <partition> <size> Cambia el tamaño de la partición lógica al nuevo tamaño sin cambiar su contenido. Falla si no hay suficiente espacio disponible para realizar el cambio de tamaño.
update-super <partition> Fusiona los cambios en los metadatos de la superpartición. Si no es posible una combinación (por ejemplo, el formato en el dispositivo es una versión no compatible), este comando falla. Un parámetro de wipe opcional sobrescribe los metadatos del dispositivo, en lugar de realizar una combinación.
flash <partition> [ <filename> ] Escribe un archivo en una partición flash. El dispositivo debe estar en estado desbloqueado.
erase <partition> Borra una partición (no es necesario que sea un borrado seguro). El dispositivo debe estar en estado desbloqueado.
getvar <variable> | all Muestra una variable del gestor de arranque o todas las variables. Si la variable no existe, devuelve un error.
set_active <slot>

Establece la ranura de arranque A/B dada como active . En el próximo intento de arranque, el sistema arranca desde la ranura especificada.

Para compatibilidad con A/B, las ranuras son conjuntos duplicados de particiones que se pueden iniciar de forma independiente. Las ranuras se denominan a , b , etc., y se diferencian agregando los sufijos _a , _b , etc. al nombre de la partición.

reboot Reinicia el dispositivo normalmente.
reboot-bootloader (o reboot bootloader ) Reinicia el dispositivo en el gestor de arranque.
fastboot fetch vendor_boot <out.img>

Úselo en Android 12 y versiones posteriores para admitir ramdisks de proveedores flash.

Obtiene el tamaño completo de la partición y el tamaño del fragmento. Obtiene datos para cada fragmento, luego une los datos a <out.img>

Para obtener más información, consulte fastboot fetch vendor_boot <out.img> .

fastboot flash vendor_boot:default <vendor-ramdisk.img>

Úselo en Android 12 y versiones posteriores para admitir ramdisks de proveedores flash.

Esta es una variante especial del comando flash. Realiza una función de fetch vendor_boot , como si se fastboot fetch de arranque rápido. La nueva imagen de vendor_boot que parpadea depende de si la versión del encabezado de arranque es la versión 3 o la versión 4.

Para obtener más información, consulte fastboot flash vendor_boot:default <vendor-ramdisk.img> .

fastboot flash vendor_boot: <foo> <vendor-ramdisk.img> Úselo en Android 12 y versiones posteriores para admitir ramdisks de proveedores flash.

Obtiene la imagen de vendor_boot . Devuelve un error si el encabezado de inicio del proveedor es la versión 3. Si es la versión 4, encuentra el fragmento de ramdisk del proveedor correcto (si está disponible). Reemplaza eso con la imagen dada, vuelve a calcular los tamaños y las compensaciones, y muestra la nueva vendor_boot image .

Para obtener detalles, consulte fastboot flash vendor_boot: <foo> <vendor-ramdisk.img>

Fastboot y gestor de arranque

El cargador de arranque muestra las particiones del cargador de bootloader , radio y boot/recovery , después de lo cual el dispositivo se inicia en fastboot (espacio de usuario) y muestra todas las demás particiones. El gestor de arranque debe admitir los siguientes comandos.

Mando Descripción
download Descarga la imagen a flash.
flash recovery <image> / flash boot <image> / flash bootloader <image> / Flashea la partición recovery/boot y el gestor de arranque.
reboot Reinicia el dispositivo.
reboot fastboot Reinicia a fastboot.
reboot recovery Se reinicia para la recuperación.
getvar Obtiene una variable del gestor de arranque necesaria para actualizar la imagen de recuperación/arranque (por ejemplo, current-slot y max-download-size ).
oem <command> Comando definido por OEM.

Particiones dinámicas

El cargador de arranque no debe permitir el flasheo o el borrado de particiones dinámicas y debe devolver un error si se intentan estas operaciones. Para dispositivos de partición dinámica reacondicionados, la herramienta fastboot (y el cargador de arranque) admite un modo forzado para flashear directamente una partición dinámica mientras está en modo de cargador de arranque. Por ejemplo, si el system es una partición dinámica en el dispositivo actualizado, el uso del fastboot --force flash system permite que el cargador de arranque (en lugar de fastbootd ) actualice la partición.

Carga fuera de modo

Si un dispositivo admite la carga en modo desactivado o se inicia automáticamente en un modo especial cuando se aplica energía, una implementación del fastboot oem off-mode-charge 0 debe omitir estos modos especiales, de modo que el dispositivo se inicie como si el usuario hubiera presionado el botón de encendido.

HAL OEM de arranque rápido

Para reemplazar completamente el cargador de arranque fastboot, fastboot debe manejar todos los comandos fastboot existentes. Muchos de estos comandos provienen de OEM y están documentados, pero requieren una implementación personalizada. Muchos comandos específicos de OEM no están documentados. Para manejar dichos comandos, fastboot HAL especifica los comandos OEM requeridos. Los OEM también pueden implementar sus propios comandos.

La definición de fastboot HAL es la siguiente:

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);

};

Habilitando fastbootd

Para habilitar fastbootd en un dispositivo:

  1. Agregue fastbootd a PRODUCT_PACKAGES en device.mk : PRODUCT_PACKAGES += fastbootd .

  2. Asegúrese de que fastboot HAL, boot control HAL y health HAL estén empaquetados como parte de la imagen de recuperación.

  3. Agregue cualquier permiso de SEPolicy específico del dispositivo requerido por fastbootd . Por ejemplo, fastbootd requiere acceso de escritura a una partición específica del dispositivo para actualizar esa partición. Además, la implementación de Fastboot HAL también puede requerir permisos específicos del dispositivo.

Para validar el arranque rápido del espacio de usuario, ejecute Vendor Test Suite (VTS) .

Discos RAM intermitentes del proveedor

Android 12 y versiones posteriores brindan soporte para flashear ramdisks con un comando de arranque rápido adicional que extrae la imagen de vendor_boot de proveedor completa de un dispositivo. El comando solicita a la herramienta de arranque rápido del lado del host que lea el encabezado de arranque del proveedor, vuelva a crear la imagen y actualice la nueva imagen.

Para extraer la imagen completa vendor_boot , se agregó el comando fetch:vendor_boot tanto al protocolo fastboot como a la implementación fastbootd del protocolo en Android 12. Tenga en cuenta que fastbootd implementa esto, pero es posible que el cargador de arranque no lo haga . Los OEM pueden agregar el comando fetch:vendor_boot a la implementación del protocolo en su cargador de arranque. Sin embargo, si el comando no se reconoce en el modo de cargador de arranque, entonces la actualización de ramdisks de proveedores individuales en el modo de cargador de arranque no es una opción compatible con el proveedor.

Cambios en el cargador de arranque

Los comandos getvar:max-fetch-size y fetch:name se implementan en fastbootd . Para admitir la actualización de ramdisks de proveedores en el gestor de arranque, debe implementar estos dos comandos.

Cambios de arranque rápido

getvar:max-fetch-size es similar a max-download-size . Especifica el tamaño máximo que el dispositivo puede enviar en una respuesta DATA. El controlador no debe buscar un tamaño mayor que este valor.

fetch:name[:offset[:size]] realiza una serie de comprobaciones en el dispositivo. Si todo lo siguiente es verdadero, el comando fetch:name[:offset[:size]] devuelve datos:

  • El dispositivo está ejecutando una compilación depurable.
  • El dispositivo está desbloqueado (estado de arranque naranja).
  • El nombre de la partición obtenida es vendor_boot .
  • El valor del size se encuentra dentro de 0 < size <= tamaño max-fetch-size .

Cuando se verifican, fetch:name[:offset[:size]] devuelve el tamaño y el desplazamiento de la partición. Tenga en cuenta lo siguiente:

  • fetch:name es equivalente a fetch:name:0 , que es equivalente a fetch:name:0:partition_size .
  • fetch:name:offset es equivalente a fetch:name:offset:(partition_size - offset)

Por lo tanto fetch:name[:offset[:size]] = fetch:name:offset:(partition_size - offset)

Cuando no se especifica el offset o el partition_size (o ambos), se utilizan los valores predeterminados, que para el offset es 0 y para el size es el valor calculado de partition_size - offset .

  • Desplazamiento especificado, tamaño no especificado: size = partition_size - offset
  • Ninguno especificado: valores predeterminados utilizados para ambos, size = partition_size - 0.

Por ejemplo, fetch:foo obtiene la partición foo completa en el desplazamiento 0.

Cambios de controlador

Se agregaron comandos a la herramienta fastboot para implementar cambios de controlador. Cada uno está vinculado a su definición completa en la tabla de comandos de Fastboot .

  • fastboot fetch vendor_boot out.img

    • Llama getvar max-fetch-size para determinar el tamaño del fragmento.
    • Llama getvar partition-size:vendor_boot[_a] para determinar el tamaño de toda la partición.
    • Llama fastboot fetch vendor_boot[_a]:offset:size para cada fragmento. (El tamaño del fragmento es mayor que el tamaño del vendor_boot , por lo que normalmente solo hay un fragmento).
    • Une los datos en out.img .
  • fastboot flash vendor_boot:default vendor-ramdisk.img

    Esta es una variante especial del comando flash. Obtiene la imagen de vendor_boot , como si se fastboot fetch .

    • Si el arranque del proveedor es la versión de encabezado 3 , hace lo siguiente:
      • Reemplaza el ramdisk del proveedor con la imagen dada.
      • Parpadea la nueva imagen vendor_boot .
    • Si el encabezado de arranque del proveedor es la versión 4 , hace lo siguiente:
      • Reemplaza todo el ramdisk del proveedor con la imagen dada para que la imagen dada se convierta en el único fragmento de ramdisk del proveedor en la imagen de vendor_boot .
      • Vuelve a calcular el tamaño y el desplazamiento en la tabla ramdisk del proveedor.
      • Parpadea la nueva imagen vendor_boot .
  • fastboot flash vendor_boot:foo vendor-ramdisk.img

    Obtiene vendor_boot image , como si se hubiera llamado fastboot fetch .

    • Si el encabezado de inicio del proveedor es la versión 3, devuelve un error.
    • Si el encabezado de inicio del proveedor es la versión 4, hace lo siguiente:

      • Encuentra el fragmento ramdisk del proveedor con el nombre foo . Si no se encuentra, o si hay varias coincidencias, devuelve un error.
      • Reemplaza el fragmento de ramdisk del proveedor con la imagen dada.
      • Vuelve a calcular cada tamaño y compensación en la tabla ramdisk del proveedor.
      • Parpadea la nueva imagen vendor_boot .

mkbootimg

El nombre default está reservado para nombrar fragmentos de ramdisk de proveedores en Android 12 y versiones posteriores. Si bien la semántica fastboot flash vendor_boot:default sigue siendo la misma, no debe nombrar sus fragmentos ramdisk como default .

Cambios de SELinux

Se realizó un cambio en fastbootd.te para admitir ramdisks de proveedores flash.