Cómo mover fastboot al espacio de usuario

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

Unifica el inicio rápido y la recuperación

Debido a que el inicio rápido y la recuperación del espacio del usuario son similares, puedes combinarlos en una un objeto binario o partición de partición. Esto ofrece ventajas como usar menos espacio, menos particiones en general, y que el inicio rápido y la recuperación compartan el kernel y las bibliotecas.

Para admitir fastbootd, el bootloader debe implementar un nuevo bloque de control de inicio. (BCB) de boot-fastboot. Para ingresar al modo fastbootd, inicia el bootloader Escribe boot-fastboot en el campo de comando del mensaje BCB y deja la El campo recovery de la BBC no se modificó (para habilitar el reinicio de cualquier recuperación interrumpida tareas). Los campos status, stage y reserved tampoco se modifican. El bootloader se carga y se inicia en la imagen de recuperación luego de ver boot-fastboot en el campo de comando de BCB. La recuperación luego analiza el mensaje de la BBC y cambia al modo fastbootd.

Comandos de ADB

En esta sección, se describe el comando adb para integrar fastbootd. El tiene resultados diferentes, dependiendo de si lo ejecuta el sistema o por recuperación.

Comando Descripción
reboot fastboot
  • Se reinicia en fastbootd (sistema).
  • Ingresa a fastbootd directamente sin reiniciarlo (recuperación).

Comandos de fastboot

En esta sección, se describen los comandos de fastboot para integrar fastbootd, incluidos comandos nuevos para escribir en la memoria flash y administrar particiones lógicas. Algunos comandos tienen resultados diferentes, dependiendo de si fueron ejecutados por por el bootloader o por fastbootd.

Comando Descripción
reboot recovery
  • Se reinicia en la recuperación (bootloader).
  • Inicia la recuperación directamente sin reiniciar el dispositivo (fastbootd).
reboot fastboot Se reinicia en fastbootd.
getvar is-userspace
  • Muestra yes (fastbootd).
  • Muestra no (bootloader).
getvar is-logical:<partition> Muestra yes si la partición dada es una partición lógica. De lo contrario, no. Las particiones lógicas admiten todos los comandos que se indican a continuación.
getvar super-partition-name Muestra el nombre de la superpartición. El nombre incluye el horario disponible actual. si la superpartición es una partición A/B (por lo general, no lo es).
create-logical-partition <partition> <size> Crea una partición lógica con el nombre y el tamaño especificados. El nombre no debe ya existen como una partición lógica.
delete-logical-partition <partition> Borra la partición lógica determinada (borra la partición con eficacia).
resize-logical-partition <partition> <size> Cambia el tamaño de la partición lógica al tamaño nuevo sin cambiar su contenido. Falla si no hay suficiente espacio disponible para cambiar el tamaño.
update-super <partition> Combina los cambios en los metadatos de la superpartición. Si no es posible realizar una combinación (por ejemplo, si el formato del dispositivo es no compatible), este falla. Un parámetro wipe opcional reemplaza el valor metadatos, en lugar de realizar una combinación.
flash <partition><filename> ] Escribe un archivo en una partición flash. El dispositivo debe estar desbloqueado.
erase <partition> Borra una partición (no es necesario para un borrado seguro). El dispositivo debe estar en estado desbloqueado.
getvar <variable> | all Muestra una variable de bootloader o todas las variables. Si la variable no existe, se muestra un error.
set_active <slot>

Establece la ranura de inicio A/B determinada como active. El próximo de inicio, el sistema se iniciará desde la ranura especificada.

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

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

Úsalo en Android 12 y versiones posteriores para lo siguiente: admiten la escritura en la memoria flash de ramdisks del proveedor.

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

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

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

Úsalo en Android 12 y versiones posteriores para admitir la escritura en la memoria flash de ramdisks del proveedor.

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

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

fastboot flash vendor_boot:<foo> <vendor-ramdisk.img> Úsalo en Android 12 y versiones posteriores para admitir la escritura en la memoria flash de ramdisks del proveedor.

Recupera la imagen vendor_boot. Devuelve un error si el proveedor boot es de la versión 3. Si es la versión 4, encuentra la respuesta fragmento del ramdisk del proveedor (si está disponible). Lo reemplaza por la imagen dada, vuelve a calcular los tamaños y las compensaciones, y escribe el nuevo vendor_boot image en la memoria flash.

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

Fastboot y bootloader

El bootloader escribe bootloader, radio y boot/recovery en la memoria flash particiones, después de las cuales el dispositivo se inicia en fastboot (espacio de usuario) e instala todas las demás particiones. El bootloader debe admitir los siguientes comandos.

Comando Descripción
download Descarga la imagen para escribirla en la memoria flash.
flash recovery <image>/ flash boot <image>/ flash bootloader <image>/ Escribe la partición recovery/boot y el bootloader en la memoria flash.
reboot Reinicia el dispositivo.
reboot fastboot Reinicia en fastboot.
reboot recovery Reinicios a la recuperación.
getvar Obtiene una variable del bootloader que es necesaria para la escritura en la memoria flash de la recuperación o el inicio. imagen (por ejemplo, current-slot y max-download-size).
oem <command> Comando definido por el OEM.

Particiones dinámicas

El bootloader no debe permitir la escritura en la memoria flash ni el borrado de particiones dinámicas y debe mostrar un error si se intentan realizar estas operaciones. Para reacondicionados dispositivos de partición dinámica, la herramienta fastboot (y el bootloader) admite una configuración de para escribir directamente una partición dinámica en la memoria flash mientras se usa el modo de bootloader. Para Por ejemplo, si system es una partición dinámica en el dispositivo actualizado, con el comando fastboot --force flash system habilita el bootloader (en lugar de fastbootd) para escribir la partición en la memoria flash.

Carga fuera del modo

Si un dispositivo admite la carga fuera del modo o se inicia automáticamente en una estación cuando se aplica energía, una implementación del El comando 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 de OEM de fastboot

Para reemplazar por completo el bootloader de fastboot, fastboot debe controlar todos los archivos existentes. fastboot. Muchos de estos comandos son de OEM y están documentados, pero una implementación personalizada. Muchos comandos específicos de OEM no documentados. Para controlar estos comandos, la HAL de fastboot especifica la Comandos de OEM. Los OEM también pueden implementar sus propios comandos.

La definición de la HAL de fastboot 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);

};

Habilitar fastbootd

Para habilitar fastbootd en un dispositivo, haz lo siguiente:

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

  2. Asegúrate de que la HAL de fastboot, la HAL de control de inicio y la HAL de estado estén empaquetados. como parte de la imagen de recuperación.

  3. Agrega los permisos de SEPolicy específicos del dispositivo que requiera fastbootd. Para Por ejemplo, fastbootd requiere acceso de escritura a una partición específica del dispositivo para escribe esa partición en la memoria flash. Además, la implementación de la HAL de fastboot también puede requieren permisos específicos del dispositivo.

Para validar el inicio rápido del espacio del usuario, ejecuta el Conjunto de pruebas de proveedores (VTS).

Escritura en la memoria flash de discos RAM del proveedor

Android 12 y las versiones posteriores admiten lo siguiente: escribir ramdisks en la memoria flash con un comando fastboot agregado que extrae la Imagen vendor_boot de un dispositivo. El comando solicita el fastboot del host para leer el encabezado de inicio del proveedor, cambiar la imagen y escribir en la memoria flash la nueva imagen.

Para extraer la imagen vendor_boot completa, se agregó el comando fetch:vendor_boot. al protocolo fastboot y a la implementación fastbootd del protocolo en Android 12. Ten en cuenta que fastbootd pero es posible que el bootloader no. Los OEM pueden agregar el comando fetch:vendor_boot a su implementación del bootloader del protocolo. Sin embargo, si el comando no se reconoce en el modo bootloader, El proveedor no admite la escritura en la memoria flash de ramdisks del proveedor individuales en el modo de bootloader. de 12 a 1 con la nueva opción de compresión.

Cambios en el bootloader

Los comandos getvar:max-fetch-size y fetch:name se implementan en fastbootd Para admitir la escritura en la memoria flash de ramdisks del proveedor en el bootloader, debes implementar estos dos comandos.

Cambios de fastbootd

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 conductor no debe recupera un tamaño mayor que este valor.

fetch:name[:offset[:size]] realiza una serie de verificaciones en el dispositivo. Si todas de las siguientes afirmaciones son verdaderas, el comando fetch:name[:offset[:size]] muestra datos:

  • El dispositivo está ejecutando una compilación depurable.
  • El dispositivo está desbloqueado (estado de inicio en naranja).
  • El nombre de la partición recuperada es vendor_boot.
  • El valor de size se encuentra entre 0 y < size <= max-fetch-size.

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

  • fetch:name es igual a fetch:name:0, que es lo siguiente: fetch:name:0:partition_size
  • fetch:name:offset equivale a fetch:name:offset:(partition_size - offset)

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

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

  • Desplazamiento especificado, tamaño sin especificar: size = partition_size - offset
  • Sin especificar: Valores predeterminados usados para ambos, size = partition_size - 0.

Por ejemplo, fetch:foo recupera toda la partición foo con el desplazamiento 0.

Cambios en los controladores

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

  • fastboot fetch vendor_boot out.img

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

    Esta es una variante especial del comando flash. Recupera la Imagen vendor_boot, como si se llamara a fastboot fetch.

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

    Recupera vendor_boot image, como si se llamara a fastboot fetch.

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

      • Busca el fragmento de ramdisk del proveedor con el nombre foo. Si no se encuentra, o si hay varias coincidencias, muestra un error.
      • Reemplaza el fragmento del ramdisk del proveedor por la imagen determinada.
      • Vuelve a calcular cada tamaño y desplazamiento en la tabla del ramdisk del proveedor.
      • Escribe en la memoria flash la nueva imagen vendor_boot.

mkbootimg

El nombre default está reservado para nombrar fragmentos de ramdisk del proveedor en Android 12 y versiones posteriores Mientras que el fastboot flash vendor_boot:default la semántica se mantiene igual, no debes nombrar los fragmentos de ramdisk como default

Cambios de SELinux

Se hizo un cambio en fastbootd.te para admitir la escritura en la memoria flash de ramdisks del proveedor.