Android 11 では、汎用カーネル イメージ(GKI)という概念が導入されています。GKI を使用して任意のデバイスを起動できるように、Android 11 ではブートイメージ ヘッダー バージョン 3 を使用できます。バージョン 3 では、ベンダー固有の情報はすべて boot
パーティションから移動され、新しい vendor_boot
パーティションに再配置されています。5.4 Linux カーネルに Android 11 を搭載した ARM64 デバイスは、vendor_boot
パーティションと更新された boot
パーティション形式をサポートして、GKI を使用したテストに合格する必要があります。
Android 12 では、ブートイメージ ヘッダー バージョン 4 を使用できます。このバージョンでは vendor_boot
パーティションに複数のベンダー RAM ディスクを格納できます。複数のベンダー RAM ディスク フラグメントは、ベンダー RAM ディスク セクションで連続して連結されます。ベンダー RAM ディスク テーブルは、ベンダー RAM ディスク セクションのレイアウトと、各ベンダー RAM ディスク フラグメントのメタデータを記述するために使用されます。
パーティションの構造
ベンダー ブート パーティションは、仮想 A/B で A/B 化され、Android の確認付きブートによって保護されます。
バージョン 3
このパーティションは、ヘッダー、ベンダー RAM ディスク、デバイスツリー blob(DTB)で構成されます。
セクション | ページ数 |
---|---|
ベンダーの起動ヘッダー(n ページ) | n = (2112 + page_size - 1) / page_size |
ベンダー用 RAM ディスク(o ページ) | o = (vendor_ramdisk_size + page_size - 1) / page_size |
DTB(p ページ) | p = (dtb_size + page_size - 1) / page_size |
バージョン 4
このパーティションは、ヘッダー、ベンダー RAM ディスク セクション(連結されたすべてのベンダー RAM ディスク フラグメントで構成)、デバイスツリー blob(DTB)、ベンダー RAM ディスク テーブルで構成されます。
セクション | ページ数 |
---|---|
ベンダーの起動ヘッダー(n ページ) | n = (2128 + page_size - 1) / page_size |
ベンダー用 RAM ディスク フラグメント(o ページ) | o = (vendor_ramdisk_size + page_size - 1) / page_size |
DTB(p ページ) | p = (dtb_size + page_size - 1) / page_size |
ベンダー用 RAM ディスク テーブル(q ページ) | q = (vendor_ramdisk_table_size + page_size - 1) / page_size |
bootconfig(r ページ) | r = (bootconfig_size + page_size - 1) / page_size |
ベンダー ブートヘッダー
ベンダー ブート パーティション ヘッダーの内容は、主にブートイメージ ヘッダーから再配置されたデータで構成されます。また、ベンダーの RAM ディスクに関する情報も含まれています。
バージョン 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 */
};
バージョン 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
は、すべてのベンダー RAM ディスク フラグメントの合計サイズです。ramdisk_type
は RAM ディスクのタイプを示します。有効な値は次のとおりです。VENDOR_RAMDISK_TYPE_NONE
は、値が指定されていないことを示します。VENDOR_RAMDISK_TYPE_PLATFORM
RAM ディスクには、プラットフォーム固有のビットが含まれています。 ブートローダーは、これらを常にメモリに読み込む必要があります。VENDOR_RAMDISK_TYPE_RECOVERY
RAM ディスクにはリカバリ リソースが含まれています。ブートローダーは、リカバリでの起動時にこれらをメモリに読み込む必要があります。VENDOR_RAMDISK_TYPE_DLKM
RAM ディスクには、動的に読み込み可能なカーネル モジュールが含まれています。
ramdisk_name
は RAM ディスクの固有名です。board_id
は、ベンダーが定義したハードウェア識別子のベクトルです。
ブートローダーのサポート
ベンダー ブート パーティションには、ブート パーティションに以前存在していた情報(Flash ページサイズ、カーネル、RAM ディスク アドレス、DTB 自体など)が含まれているため、ブートローダーはブート パーティションとベンダーブート パーティションの両方にアクセスして起動を完了するうえで十分なデータを取得する必要があります。
ブートローダーは、ベンダー RAM ディスクの直後に汎用の RAM ディスクをメモリに読み込む必要があります(CPIO、Gzip、lz4 形式はこのタイプの連結をサポートしています)。汎用の RAM ディスク イメージをページに合わせて配置する、またはベンダー用 RAM ディスクとの間にその他のスペースをメモリ内に配置することはしないでください。カーネルが解凍されると、連結されたファイルが initramfs
に抽出されます。これにより、ベンダー用 RAM ディスクのファイル構造にオーバーレイされる汎用 RAM ディスクのファイル構造が生成されます。
汎用の RAM ディスクとベンダー RAM ディスクは連結されるため、同じ形式にする必要があります。GKI ブートイメージは lz4 圧縮の汎用 RAM ディスクを使用するため、GKI に準拠するデバイスは lz4 圧縮のベンダー RAM ディスクを使用する必要があります。その構成を以下に示します。
bootconfig をサポートするためのブートローダーの要件については、Bootconfig の実装ページをご覧ください。
複数のベンダー RAM ディスク(バージョン 4)
ブートイメージ ヘッダー バージョン 4 では、ブートローダーはベンダー RAM ディスクのサブセットまたはすべてを選択して、ブート時に initramfs
として読み込むことができます。ベンダー RAM ディスク テーブルには各 RAM ディスクのメタデータが含まれており、ブートローダーが読み込む RAM ディスクを決定する際に役立ちます。ブートローダーは、選択したベンダー RAM ディスクを読み込む順序を決定できます。ただし、汎用の RAM ディスクは最後に読み込む必要があります。
たとえば、通常のブート時に、リソースを節約するために VENDOR_RAMDISK_TYPE_RECOVERY
タイプのベンダー RAM ディスクの読み込みを省略できます。この場合、メモリに読み込まれるのは VENDOR_RAMDISK_TYPE_PLATFORM
タイプと VENDOR_RAMDISK_TYPE_DLKM
タイプのベンダー RAM ディスクのみです。一方、VENDOR_RAMDISK_TYPE_PLATFORM
、VENDOR_RAMDISK_TYPE_RECOVERY
、VENDOR_RAMDISK_TYPE_DLKM
タイプのベンダー RAM ディスクは、リカバリモードで起動したときにメモリに読み込まれます。
また、ブートローダーは、ベンダー RAM ディスク テーブルを無視して、ベンダー RAM ディスク セクション全体を読み込むこともできます。このときの動作は、vendor_boot
パーティション内のすべてのベンダー RAM ディスク フラグメントを読み込む場合と同じ効果を持ちます。
ビルドサポート
デバイスにベンダーブートのサポートを実装するには、次の操作を行います。
BOARD_BOOT_HEADER_VERSION
を3
以上に設定します。デバイスが GKI に準拠している場合、またはそれ以外の場合で lz4 で圧縮された汎用 RAM ディスクを使用している場合は
BOARD_RAMDISK_USE_LZ4
をtrue
に設定します。ベンダーの RAM ディスクに必要なカーネル モジュールを考慮して、
BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE
をデバイスの適切なサイズに設定します。vendor_boot
と、デバイス固有の OTA パーティションのベンダー固有のリストが含まれるように、AB_OTA_PARTITIONS
を更新します。boot
パーティションではなくvendor_boot
パーティションの/first_stage_ramdisk
にデバイスfstab
をコピーします。例:$(LOCAL_PATH)/fstab.hardware:$(TARGET_COPY_OUT_VENDOR_RAMDISK)/first_stage_ramdisk/fstab.$(PRODUCT_PLATFORM)
。
vendor_boot
に複数のベンダー RAM ディスクを含めるには:
BOARD_BOOT_HEADER_VERSION
を4
に設定します。BOARD_VENDOR_RAMDISK_FRAGMENTS
を、vendor_boot
に含める論理ベンダー RAM ディスク フラグメント名のリストに設定します。ビルド済みのベンダー RAM ディスクを追加するには、
BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).PREBUILT
をビルド済みのパスに設定します。DLKM ベンダー RAM ディスクを追加するには、
BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).KERNEL_MODULE_DIRS
を、含めるカーネル モジュール ディレクトリのリストに設定します。BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).MKBOOTIMG_ARGS
をmkbootimg
引数に設定します。これらは、ベンダーの RAM ディスク フラグメントの--board_id[0-15]
引数と--ramdisk_type
引数です。DLKM ベンダー RAM ディスクの場合、特に指定されていない限り、デフォルトの--ramdisk_type
はDLKM
になります。
vendor_boot
でリカバリ リソースをスタンドアロンの recovery
RAM ディスクとしてビルドするには:
BOARD_BOOT_HEADER_VERSION
を4
に設定します。BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT
をtrue
に設定します。BOARD_INCLUDE_RECOVERY_RAMDISK_IN_VENDOR_BOOT
をtrue
に設定します。- これにより、
ramdisk_name
がrecovery
で、ramdisk_type
がVENDOR_RAMDISK_TYPE_RECOVERY
のベンダー RAM ディスク フラグメントが追加されます。その場合、RAM ディスクにはすべてのリカバリ ファイルが含まれます。これらのファイルは$(TARGET_RECOVERY_ROOT_OUT)
にインストールされています。
mkbootimg の引数
引数 | 説明 |
---|---|
--ramdisk_type |
RAM ディスクの種類。NONE 、PLATFORM 、RECOVERY 、DLKM のいずれかを指定できます。
|
--board_id[0-15] |
board_id ベクトルを指定します。デフォルトは 0 です。 |
設定の例を以下に示します。
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
この場合、vendor_boot
には、2 つのベンダー RAM ディスク フラグメントが含まれます。1 つ目は「デフォルト」の RAM ディスクで、DLKM ディレクトリ baz
と、$(TARGET_VENDOR_RAMDISK_OUT)
の残りの部分が含まれています。2 つ目は dlkm_foobar
RAM ディスクで、DLKM ディレクトリ foo
および bar
が含まれます。--ramdisk_type
のデフォルトは DLKM
になります。