Android 11 introdujo el concepto de kernel genérico
Imagen (GKI). Para habilitar el inicio de un dispositivo arbitrario con el GKI, Android
11 dispositivos pueden usar la versión 3 del encabezado de imagen de arranque. En
versión 3, toda la información específica del proveedor se excluye de la boot
.
y se trasladó a una nueva partición vendor_boot
. Un dispositivo ARM64
lanzar con Android 11 en el kernel de Linux 5.4 debe
admitir la partición vendor_boot
y el formato de partición boot
actualizado para
aprobar las pruebas con el GKI.
Los dispositivos con Android 12 pueden usar la versión 4 del encabezado de imagen de arranque,
que admite la inclusión de varios ramdisks del proveedor en el archivo vendor_boot
por cada partición. Se concatenan varios fragmentos de ramdisk del proveedor uno tras otro.
en la sección ramdisk del proveedor. Se usa una tabla de ramdisk del proveedor para describir el
diseño de la sección del ramdisk del proveedor y los metadatos de cada uno de ellos
en ese fragmento.
Estructura de partición
La partición de inicio del proveedor es de tipo A/B con A/B virtual y está protegida por Android Inicio verificado.
Versión 3
La partición consta de un encabezado, el ramdisk del proveedor y el BLOB del árbol de dispositivos (DTB).
Sección | Cantidad de páginas |
---|---|
Encabezado de inicio del proveedor (n páginas) | n = (2112 + page_size - 1) / page_size |
ramdisk del proveedor (o páginas) | o = (vendor_ramdisk_size + page_size - 1) / page_size |
DTB (p páginas) | p = (dtb_size + page_size - 1) / page_size |
Versión 4
La partición consta de un encabezado, la sección del ramdisk del proveedor (que consiste en todos los fragmentos de ramdisk del proveedor, concatenados), el BLOB del árbol de dispositivos (DTB) y del ramdisk del proveedor.
Sección | Cantidad de páginas |
---|---|
Encabezado de inicio del proveedor (n páginas) | n = (2128 + page_size - 1) / page_size |
Fragmentos de ramdisk del proveedor (o páginas) | o = (vendor_ramdisk_size + page_size - 1) / page_size |
DTB (p páginas) | p = (dtb_size + page_size - 1) / page_size |
Tabla de ramdisk del proveedor (páginas q) | q = (vendor_ramdisk_table_size + page_size - 1) / page_size |
Bootconfig (r páginas) | r = (bootconfig_size + page_size - 1) / page_size |
Encabezado de inicio del proveedor
El contenido del encabezado de la partición de inicio del proveedor consta principalmente de datos que se trasladó allí desde el encabezado de imagen de arranque. Integra también contiene información sobre el ramdisk del proveedor.
Versión 3
struct vendor_boot_img_hdr_v3
{
#define VENDOR_BOOT_MAGIC_SIZE 8
uint8_t magic[VENDOR_BOOT_MAGIC_SIZE];
uint32_t header_version;
uint32_t page_size; /* flash page size we assume */
uint32_t kernel_addr; /* physical load addr */
uint32_t ramdisk_addr; /* physical load addr */
uint32_t vendor_ramdisk_size; /* size in bytes */
#define VENDOR_BOOT_ARGS_SIZE 2048
uint8_t cmdline[VENDOR_BOOT_ARGS_SIZE];
uint32_t tags_addr; /* physical addr for kernel tags */
#define VENDOR_BOOT_NAME_SIZE 16
uint8_t name[VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */
uint32_t header_size; /* size of vendor boot image header in
* bytes */
uint32_t dtb_size; /* size of dtb image */
uint64_t dtb_addr; /* physical load address */
};
Versión 4
struct vendor_boot_img_hdr_v4
{
#define VENDOR_BOOT_MAGIC_SIZE 8
uint8_t magic[VENDOR_BOOT_MAGIC_SIZE];
uint32_t header_version;
uint32_t page_size; /* flash page size we assume */
uint32_t kernel_addr; /* physical load addr */
uint32_t ramdisk_addr; /* physical load addr */
uint32_t vendor_ramdisk_size; /* size in bytes */
#define VENDOR_BOOT_ARGS_SIZE 2048
uint8_t cmdline[VENDOR_BOOT_ARGS_SIZE];
uint32_t tags_addr; /* physical addr for kernel tags */
#define VENDOR_BOOT_NAME_SIZE 16
uint8_t name[VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */
uint32_t header_size; /* size of vendor boot image header in
* bytes */
uint32_t dtb_size; /* size of dtb image */
uint64_t dtb_addr; /* physical load address */
uint32_t vendor_ramdisk_table_size; /* size in bytes for the vendor ramdisk table */
uint32_t vendor_ramdisk_table_entry_num; /* number of entries in the vendor ramdisk table */
uint32_t vendor_ramdisk_table_entry_size; /* size in bytes for a vendor ramdisk table entry */
uint32_t bootconfig_size; /* size in bytes for the bootconfig section */
};
#define VENDOR_RAMDISK_TYPE_NONE 0
#define VENDOR_RAMDISK_TYPE_PLATFORM 1
#define VENDOR_RAMDISK_TYPE_RECOVERY 2
#define VENDOR_RAMDISK_TYPE_DLKM 3
struct vendor_ramdisk_table_entry_v4
{
uint32_t ramdisk_size; /* size in bytes for the ramdisk image */
uint32_t ramdisk_offset; /* offset to the ramdisk image in vendor ramdisk section */
uint32_t ramdisk_type; /* type of the ramdisk */
#define VENDOR_RAMDISK_NAME_SIZE 32
uint8_t ramdisk_name[VENDOR_RAMDISK_NAME_SIZE]; /* asciiz ramdisk name */
#define VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE 16
// Hardware identifiers describing the board, soc or platform which this
// ramdisk is intended to be loaded on.
uint32_t board_id[VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE];
};
vendor_ramdisk_size
es el tamaño total de todos los fragmentos del ramdisk del proveedor.ramdisk_type
denota el tipo del ramdisk. Los valores posibles son los siguientes:VENDOR_RAMDISK_TYPE_NONE
indica que el valor no se especifica.- Los ramdisks
VENDOR_RAMDISK_TYPE_PLATFORM
contienen bits específicos de la plataforma. El bootloader siempre debe cargarlos en la memoria. VENDOR_RAMDISK_TYPE_RECOVERY
de ramdisks contienen recursos de recuperación. El debe cargarlos en la memoria cuando se inician en recuperación.VENDOR_RAMDISK_TYPE_DLKM
ramdisks contienen kernel dinámico cargable módulos.
ramdisk_name
es un nombre único del ramdisk.board_id
es un vector de identificadores de hardware definidos por el proveedor.
Compatibilidad con el bootloader
Debido a que la partición de inicio del proveedor contiene información (como el tamaño de la página Flash, el kernel, las direcciones de carga de ramdisk y la DTB) que existía anteriormente en la para la partición de inicio, el bootloader debe acceder tanto al inicio como al del proveedor para tener suficientes datos para completar el inicio.
El bootloader debe cargar el ramdisk genérico en la memoria inmediatamente después de eso.
el ramdisk del proveedor (los formatos CPIO, Gzip y lz4 admiten este tipo de
concatenación). No alinees la imagen genérica del ramdisk ni introduzcas alguna.
entre él y el final del ramdisk del proveedor en la memoria. Después del
el kernel descomprime el archivo concatenado y lo extrae en un initramfs
,
lo que da como resultado una estructura de archivos que es un disco RAM genérico superpuesto
estructura del archivo ramdisk del proveedor.
Debido a que el ramdisk genérico y el ramdisk del proveedor se concatenan, deben estar en el mismo formato. La imagen de arranque de GKI usa un ramdisk genérico comprimido en lz4, por lo que dispositivo que cumpla con GKI debe usar un ramdisk del proveedor comprimido en lz4. El configuración para esto se muestra a continuación.
Los requisitos del bootloader para admitir bootconfig se explican en Implementación Bootconfig
Varios ramdisks del proveedor (versión 4)
Con la versión 4 del encabezado de imagen de arranque, el bootloader puede seleccionar un subconjunto o
todos los ramdisks del proveedor se cargarán como initramfs
durante el tiempo de inicio. El
del ramdisk del proveedor contiene los metadatos de cada uno y puede ayudar
para decidir qué ramdisks cargar. El bootloader puede decidir
para cargar los ramdisks del proveedor seleccionados, siempre y cuando
se cargó en último lugar.
Por ejemplo, el bootloader puede omitir la carga de ramdisks del proveedor del tipo
VENDOR_RAMDISK_TYPE_RECOVERY
durante el inicio normal para ahorrar recursos, por lo que solo
ramdisks del proveedor del tipo VENDOR_RAMDISK_TYPE_PLATFORM
y
VENDOR_RAMDISK_TYPE_DLKM
se cargan en la memoria. Por otro lado, el proveedor
ramdisks de tipo VENDOR_RAMDISK_TYPE_PLATFORM
y VENDOR_RAMDISK_TYPE_RECOVERY
y VENDOR_RAMDISK_TYPE_DLKM
se cargan en la memoria cuando se inician en el modo de recuperación.
.
Como alternativa, el bootloader puede ignorar la tabla del ramdisk del proveedor y cargar el
toda la sección del ramdisk del proveedor. Esto tiene el mismo efecto que cargar
los fragmentos del ramdisk del proveedor en la partición vendor_boot
Genera asistencia
Para implementar la compatibilidad con el inicio del proveedor en un dispositivo, haz lo siguiente:
Establece
BOARD_BOOT_HEADER_VERSION
en3
o superior.Establece
BOARD_RAMDISK_USE_LZ4
comotrue
si tu dispositivo cumple con GKI o si de lo contrario, usa un disco RAM genérico comprimido en lz4.Establece
BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE
en un tamaño adecuado para tu teniendo en cuenta los módulos kernel que deben ir en el disco RAM del proveedor.Actualiza
AB_OTA_PARTITIONS
para incluirvendor_boot
y cualquier configuración específica del proveedor. listas de particiones inalámbricas del dispositivo.Copia el elemento
fstab
de tu dispositivo en/first_stage_ramdisk
envendor_boot
. no la particiónboot
. (por ejemplo,$(LOCAL_PATH)/fstab.hardware:$(TARGET_COPY_OUT_VENDOR_RAMDISK)/first_stage_ramdisk/fstab.$(PRODUCT_PLATFORM)
).
Para incluir varios ramdisks del proveedor en vendor_boot
, haz lo siguiente:
- Establece
BOARD_BOOT_HEADER_VERSION
en4
. Configura
BOARD_VENDOR_RAMDISK_FRAGMENTS
en una lista de ramdisk lógico del proveedor los nombres de fragmentos que se incluirán envendor_boot
.Para agregar un ramdisk del proveedor compilado previamente, configura
BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).PREBUILT
a la compilación previa ruta de acceso.Para agregar un ramdisk del proveedor de DLKM, configura
BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).KERNEL_MODULE_DIRS
al Lista de directorios de módulos de kernel que se incluirán.Establecer
BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).MKBOOTIMG_ARGS
en Argumentos demkbootimg
. Estos son los valores de--board_id[0-15]
y--ramdisk_type
para el fragmento de ramdisk del proveedor. Para el ramdisk del proveedor de DLKM, El valor predeterminado--ramdisk_type
seríaDLKM
si no se especifica de otra manera.
Para compilar recursos de recuperación como un ramdisk recovery
independiente en vendor_boot
, haz lo siguiente:
- Establece
BOARD_BOOT_HEADER_VERSION
en4
. - Establece
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT
entrue
. - Establece
BOARD_INCLUDE_RECOVERY_RAMDISK_IN_VENDOR_BOOT
entrue
. - Esto agrega un fragmento de ramdisk del proveedor cuyo
ramdisk_name
esrecovery
yramdisk_type
esVENDOR_RAMDISK_TYPE_RECOVERY
. El disco RAM contiene todos los archivos de recuperación, que son archivos instalados$(TARGET_RECOVERY_ROOT_OUT)
Argumentos de mkbootimg
Argumento | Descripción |
---|---|
--ramdisk_type |
El tipo de ramdisk puede ser NONE ,
PLATFORM , RECOVERY o DLKM .
|
--board_id[0-15] |
Especifica el vector board_id , el valor predeterminado es 0 . |
A continuación, se muestra un ejemplo de configuración:
BOARD_KERNEL_MODULE_DIRS := foo bar baz
BOARD_BOOT_HEADER_VERSION := 4
BOARD_VENDOR_RAMDISK_FRAGMENTS := dlkm_foobar
BOARD_VENDOR_RAMDISK_FRAGMENT.dlkm_foobar.KERNEL_MODULE_DIRS := foo bar
BOARD_VENDOR_RAMDISK_FRAGMENT.dlkm_foobar.MKBOOTIMG_ARGS := --board_id0 0xF00BA5 --board_id1 0xC0FFEE
La vendor_boot
resultante contendrá dos fragmentos de ramdisk del proveedor. El
el primero es el “predeterminado” ramdisk, que contiene el directorio de DLKM baz
y
el resto de los archivos en $(TARGET_VENDOR_RAMDISK_OUT)
. El segundo es el
El ramdisk dlkm_foobar
, que contiene los directorios de DLKM foo
y bar
--ramdisk_type
es DLKM
de forma predeterminada.