Android 9 introdujo un campo de versión en el encabezado de la imagen de inicio, lo que permite actualizar el encabezado y mantener la retrocompatibilidad. El bootloader debe verificar el campo de versión del encabezado y analizar el encabezado según corresponda. Dispositivos que se lanzan con los siguientes sistemas operativos:
- Android 13 puede usar la versión 3 o 4 del encabezado de inicio. En el caso de los dispositivos que admiten la arquitectura de imagen genérica del kernel (GKI), la versión 4 es la imagen de arranque principal y el campo
os_version
del encabezado de arranque debe ser cero. Se espera que el bootloader del dispositivo obtenga la información de la versión de las propiedades de Android Verified Boot (AVB). - Android 12 puede usar la versión 3 o 4 del encabezado de inicio. Para los dispositivos que admiten la arquitectura de imagen genérica de kernel (GKI), la versión 4 es la imagen de arranque principal.
- Android 11 puede usar la versión 3 del encabezado de inicio. En el caso de los dispositivos que admiten la arquitectura de imagen genérica del kernel (GKI), esta versión se debe usar para la imagen de arranque principal.
- Android 10 debe usar la versión 2 del encabezado de inicio.
- Android 9 debe usar la versión 1 del encabezado de inicio.
- Se considera que Android 8 y las versiones anteriores usan la versión 0 del encabezado de la imagen de inicio.
En todos los dispositivos que ejecutan Android 9 o versiones posteriores, el Vendor Test Suite (VTS) verifica el formato de la imagen boot/recovery
para garantizar que el encabezado de la imagen de inicio use la versión correcta. Para ver los detalles del AOSP sobre todos los encabezados de imágenes de arranque y de arranque del proveedor compatibles, consulta system/tools/mkbootimg/include/bootimg/bootimg.h
.
Implementa el control de versiones del encabezado de la imagen de arranque
La herramienta mkbootimg
acepta los siguientes argumentos.
Argumento | Descripción |
---|---|
header_version |
Establece la versión del encabezado de la imagen de arranque. Una imagen de arranque con una versión de encabezado:
|
recovery_dtbo |
Se usa para arquitecturas que usan DTB. Especifica la ruta de acceso a la imagen DTBO de recuperación. Es opcional para los dispositivos A/B, que no necesitan una imagen de recuperación.
Dispositivos que no son A/B y usan header_version :
|
recovery_acpio |
Se usa para arquitecturas que usan ACPI en lugar de DTB. Especifica la ruta de acceso a la imagen de ACPIO de recuperación. Es opcional para los dispositivos A/B, que no necesitan una imagen de recuperación. Dispositivos que no son A/B y usan header_version :
|
dtb |
Es la ruta de acceso a la imagen DTB que se incluye en las imágenes de inicio o recuperación. |
dtb_offset |
Cuando se agrega al argumento base , proporciona la dirección de carga física para el árbol de dispositivos final. Por ejemplo, si el argumento base es 0x10000000 y el argumento dtb_offset es 0x01000000 , el dtb_addr_field en el encabezado de la imagen de arranque se completa como 0x11000000 . |
El dispositivo BoardConfig.mk
usa la configuración BOARD_MKBOOTIMG_ARGS
para agregar header version
a los otros argumentos específicos de la placa de mkbootimg
. Por ejemplo:
BOARD_MKBOOTIMG_ARGS := --ramdisk_offset $(BOARD_RAMDISK_OFFSET) --tags_offset $(BOARD_KERNEL_TAGS_OFFSET) --header_version $(BOARD_BOOTIMG_HEADER_VERSION)
El sistema de compilación de Android usa la variable BoardConfig
BOARD_PREBUILT_DTBOIMAGE
para establecer el argumento recovery_dtbo
de la herramienta mkbootimg
durante la creación de la imagen de recuperación. Para obtener detalles sobre los cambios en el Proyecto de código abierto de Android (AOSP), revisa las listas de cambios asociadas para el control de versiones del encabezado de la imagen de arranque.
Encabezado de imagen de arranque, versión 4
Android 12 proporciona un boot_signature
en la versión 4 del encabezado de la imagen de arranque, que se puede usar para verificar la integridad del kernel y el ramdisk. La verificación se realiza en VtsSecurityAvbTest y es obligatoria para los dispositivos que usan la arquitectura de GKI. Sin embargo, boot_signature
no participa en el proceso de inicio verificado específico del dispositivo y solo se usa en VTS. Consulta Configuración de la placa boot.img de GKI y Configuración del arranque verificado de GKI para obtener más detalles.
La versión 4 del encabezado de la imagen de arranque del proveedor admite varios fragmentos de ramdisk del proveedor.
La versión 4 del encabezado de la imagen de arranque usa el siguiente formato.
struct boot_img_hdr
{
#define BOOT_MAGIC_SIZE 8
uint8_t magic[BOOT_MAGIC_SIZE];
uint32_t kernel_size; /* size in bytes */
uint32_t ramdisk_size; /* size in bytes */
uint32_t os_version;
uint32_t header_size; /* size of boot image header in bytes */
uint32_t reserved[4];
uint32_t header_version; /* offset remains constant for version check */
#define BOOT_ARGS_SIZE 512
#define BOOT_EXTRA_ARGS_SIZE 1024
uint8_t cmdline[BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE];
uint32_t signature_size; /* size in bytes */
};
Encabezado de imagen de arranque, versión 3
Android 11 actualiza el encabezado de la imagen de inicio a la versión 3, que quita los siguientes datos:
Bootloader de segunda etapa. Los campos
second_size
ysecond_addr
ya no aparecen en el encabezado de la imagen de inicio. Los dispositivos con un bootloader de segunda etapa deben almacenar ese bootloader en su propia partición.Imagen de recuperación. Se dejó de usar el requisito de especificar una imagen de recuperación, y los campos
recovery_dtbo_size
,recovery_dtbo_offset
,recovery_acpio_size
yrecovery_acpio_offset
ya no aparecen en el encabezado de la imagen de arranque.Los dispositivos A/B usan un esquema de actualización y recuperación que hace que no sea necesario especificar una imagen de DTBO o ACPIO para la recuperación.
Los dispositivos que no son A/B y que desean especificar una imagen de recuperación (DTBO o ACPIO) deben usar la versión 1 o 2 del encabezado de la imagen de inicio.
Blob del árbol de dispositivos (DTB): El DTB se almacena en la partición de inicio del proveedor, por lo que los campos
dtb_size
ydtb_addr
ya no aparecen en el encabezado de la imagen de inicio (pero están presentes en el encabezado de la imagen de inicio del proveedor).
Los dispositivos pueden usar la versión 3 del encabezado de la imagen de arranque para cumplir con la arquitectura de la imagen genérica del kernel (GKI), que unifica el kernel principal y mueve los módulos del proveedor que se requieren para el arranque a la partición vendor_boot
(lo que significa que la imagen de arranque solo contiene componentes de la GKI). Dispositivos que cumplen con las siguientes condiciones:
Si usas GKI (requiere el kernel android-4.19 o android-5.4), pero no usas actualizaciones A/B, puedes especificar una imagen de recuperación con la versión 3 de la imagen de arranque y la versión 2 de la imagen de recuperación.
Las particiones que no usan GKI ni actualizaciones A/B pueden especificar una imagen de recuperación con la versión 1 o 2 de la imagen de arranque para las imágenes de arranque y de recuperación.
La versión 3 del encabezado de la imagen de arranque usa el siguiente formato.
struct boot_img_hdr
{
#define BOOT_MAGIC_SIZE 8
uint8_t magic[BOOT_MAGIC_SIZE];
uint32_t kernel_size; /* size in bytes */
uint32_t ramdisk_size; /* size in bytes */
uint32_t os_version;
uint32_t header_size; /* size of boot image header in bytes */
uint32_t reserved[4];
uint32_t header_version; /* offset remains constant for version check */
#define BOOT_ARGS_SIZE 512
#define BOOT_EXTRA_ARGS_SIZE 1024
uint8_t cmdline[BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE];
};
Encabezado de imagen de arranque, versión 2
Android 10 actualiza el encabezado de imagen de inicio a la versión 2, que agrega una sección para la información de la imagen DTB de recuperación (tamaño de la imagen y dirección de carga física).
La versión 2 del encabezado de la imagen de arranque usa el siguiente formato.
struct boot_img_hdr
{
uint8_t magic[BOOT_MAGIC_SIZE];
uint32_t kernel_size; /* size in bytes */
uint32_t kernel_addr; /* physical load addr */
uint32_t ramdisk_size; /* size in bytes */
uint32_t ramdisk_addr; /* physical load addr */
uint32_t second_size; /* size in bytes */
uint32_t second_addr; /* physical load addr */
uint32_t tags_addr; /* physical addr for kernel tags */
uint32_t page_size; /* flash page size we assume */
uint32_t header_version;
uint32_t os_version;
uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */
uint8_t cmdline[BOOT_ARGS_SIZE];
uint32_t id[8]; /* timestamp / checksum / sha1 / etc */
uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
uint32_t recovery_[dtbo|acpio]_size; /* size of recovery image */
uint64_t recovery_[dtbo|acpio]_offset; /* offset in boot image */
uint32_t header_size; /* size of boot image header in bytes */
uint32_t dtb_size; /* size of dtb image */
uint64_t dtb_addr; /* physical load address */
};
Encabezado de imagen de arranque, versión 1
Android 9 convierte el campo unused
del encabezado de la imagen de inicio en un campo de versión del encabezado. Los dispositivos que se lanzan con Android 9 deben usar el encabezado de imagen de inicio con la versión del encabezado establecida en 1 o superior (esto lo verifica VTS).
La versión 1 del encabezado de la imagen de arranque usa el siguiente formato.
struct boot_img_hdr
{
uint8_t magic[BOOT_MAGIC_SIZE];
uint32_t kernel_size; /* size in bytes */
uint32_t kernel_addr; /* physical load addr */
uint32_t ramdisk_size; /* size in bytes */
uint32_t ramdisk_addr; /* physical load addr */
uint32_t second_size; /* size in bytes */
uint32_t second_addr; /* physical load addr */
uint32_t tags_addr; /* physical addr for kernel tags */
uint32_t page_size; /* flash page size we assume */
uint32_t header_version;
uint32_t os_version;
uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */
uint8_t cmdline[BOOT_ARGS_SIZE];
uint32_t id[8]; /* timestamp / checksum / sha1 / etc */
uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
uint32_t recovery_[dtbo|acpio]_size; /* size of recovery image */
uint64_t recovery_[dtbo|acpio]_offset; /* offset in boot image */
uint32_t header_size; /* size of boot image header in bytes */
};
Los dispositivos que no son A/B pueden especificar una imagen de superposición de DTB/ACPI para la recuperación para ayudar a mitigar las fallas de actualización inalámbrica (OTA). (Los dispositivos A/B no tienen este problema y no necesitan especificar una imagen de superposición). Puedes especificar una imagen DTBO o una imagen ACPIO, pero no ambas (porque las usan arquitecturas diferentes). Para configurar correctamente el encabezado de la imagen de arranque, haz lo siguiente:
Una imagen de DTBO para la recuperación, incluye los campos
recovery_dtbo_size
yrecovery_dtbo_offset
(y no incluye los camposrecovery_acpio_size
yrecovery_acpio_offset
).Una imagen de ACPIO para la recuperación, incluye los campos
recovery_acpio_size
yrecovery_acpio_offset
(y no incluye los camposrecovery_dtbo_size
yrecovery_dtbo_offset
).
El campo header_size
contiene el tamaño del encabezado de la imagen de inicio. Si la versión del encabezado de la imagen de arranque se establece en 1, el campo id
contiene el resumen SHA-1 para la sección recovery_[dtbo|acpio]
de la imagen de arranque, además de kernel
, ramdisk
y second sections
. Para obtener detalles sobre los campos recovery_[dtbo|acpio]_size
y recovery_[dtbo|acpio]_offset
, consulta Imágenes de recuperación.
Encabezado de imagen de arranque heredado, versión 0
Los dispositivos lanzados antes de Android 9 que usan el encabezado de imagen de arranque heredado se consideran como si usaran la versión 0 del encabezado de imagen de arranque.
struct boot_img_hdr
{
uint8_t magic[BOOT_MAGIC_SIZE];
uint32_t kernel_size; /* size in bytes */
uint32_t kernel_addr; /* physical load addr */
uint32_t ramdisk_size; /* size in bytes */
uint32_t ramdisk_addr; /* physical load addr */
uint32_t second_size; /* size in bytes */
uint32_t second_addr; /* physical load addr */
uint32_t tags_addr; /* physical addr for kernel tags */
uint32_t page_size; /* flash page size we assume */
uint32_t unused;
uint32_t os_version;
uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */
uint8_t cmdline[BOOT_ARGS_SIZE];
uint32_t id[8]; /* timestamp / checksum / sha1 / etc */
uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
};