Google は、黒人コミュニティに対する人種平等の促進に取り組んでいます。取り組みを見る

ブートイメージ ヘッダーのバージョニング

Android 9 以降では、ブートイメージ ヘッダーにヘッダー バージョンを示すフィールドが含まれています。ブートローダーは、このヘッダー バージョン フィールドを確認し、それに応じてヘッダーを解析する必要があります。ブートイメージ ヘッダーをバージョニングすると、ヘッダーをその後変更できるようになり、一方で下位互換性も確保できます。

Android 9 を搭載したデバイスはすべて、ブートヘッダー バージョン 1 を使用する必要があります。

ブートイメージ ヘッダーの変更

以前のブートイメージ ヘッダー(下記)の unused フィールドは、Android 9 を搭載したデバイスではヘッダー バージョン フィールドに変換されました。

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];
    };

以前のブートイメージ ヘッダーを使用して起動される Android 9 より前のデバイスは、ブートヘッダー バージョン 0 を使用しているものとみなされます。Android 9 を搭載したすべてのデバイスで、ブートイメージ ヘッダーに次の構造を使用し、ヘッダー バージョンを 1 に設定する必要があります。

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_size;   /* size of recovery dtbo image */
        uint64_t recovery_dtbo_offset; /* offset in boot image */
        uint32_t header_size;   /* size of boot image header in bytes */
    };

header_size フィールドには、ブートイメージ ヘッダーのサイズが格納されています。ブートイメージ ヘッダー バージョンが 1 に設定されている場合、id フィールドには、ブートイメージの kernelramdisksecond sections に加えて recovery_dtbo セクションの SHA-1 ダイジェストが格納されています。recovery_dtbo_size フィールドと recovery_dtbo_offset フィールドの詳細については、非 A/B デバイスの復元を DTBO に含めるをご覧ください。

実装

ブートイメージを作成する mkbootimg ツールは、新しいブートイメージ ヘッダーをサポートできるように、次の引数を追加します。

引数 説明
header_version ブートイメージ ヘッダーのバージョンを設定します。
recovery_dtbo リカバリ イメージに含めるリカバリ DTBO イメージのパス。

デバイス BoardConfig.mk は構成 BOARD_MKBOOTIMG_ARGS を使用して、header versionmkbootimg のボード固有の他の引数に追加します。例:

      BOARD_MKBOOTIMG_ARGS := --ramdisk_offset $(BOARD_RAMDISK_OFFSET) --tags_offset $(BOARD_KERNEL_TAGS_OFFSET) --header_version $(BOARD_BOOTIMG_HEADER_VERSION)

Android ビルドシステムは、リカバリ イメージの作成中に BoardConfig 変数 BOARD_PREBUILT_DTBOIMAGE を使用して mkbootimg ツールの recovery_dtbo 引数を設定します。

Android Open Source Project(AOSP)の変更点については、ブートイメージ ヘッダーのバージョニングに関連するチェンジリストをご覧ください。

検証

Android 9 を搭載したすべてのデバイスで、ベンダー テストスイート(VTS)はブートイメージとリカバリ イメージの形式をチェックし、ブートイメージ ヘッダーにバージョン 1 が使用されていることを確認します。

ブートイメージに DTB を含める

Android 10 は、ブートイメージ ヘッダーをバージョン 2 に更新します。この中には、デバイスツリー blob(DTB)イメージを格納するセクションが含まれます。 Android 10 VTS テストでは、Android 10 を搭載するすべてのデバイスがブートイメージ ヘッダー バージョン 2 を使用し、有効な DTB イメージがブートイメージまたは復元イメージの一部として含まれていることを検証します。

DTB について

Android 9 以前のリリースでは、DTB イメージは独自のパーティションに配置されるか、カーネル image.gz に追加され、カーネル+DTB イメージが作成されます(その後 mkbootimg に渡され、boot.img が作成されます)。Android 10 では、ブートイメージ形式が DTB イメージ用のセクションを使用するよう、さらに更新されます。 この変更により、Android ではカーネルで DTB イメージを image.gz に追加するスクリプトをサポートする必要がなくなり、VTS テストを使用して DTB プレースメントを検証(および標準化)できるようになりました。

さらに、非 A/B デバイスの場合、DTB を個別のパーティションに入れずにリカバリ イメージの一部にする方が、OTA の中断による問題を安全に防止できます。 OTA の実行中、DTB パーティションのアップデート後(かつアップデート全体の完了前)に問題が発生すると、デバイスは OTA を完了するためにリカバリモードで起動しようとします。ただし、DTB パーティションがすでにアップデートされているため、まだアップデートされていないリカバリ イメージとの不一致が生じる可能性があります。DTB イメージをブートイメージ形式の一部にすることで、リカバリ イメージを自立させる(他のパーティションに依存しないようにする)ことができ、前述のような問題の発生を防ぐことができます。

ブートイメージ ヘッダー バージョン 2

ブートイメージ ヘッダー バージョン 2 は、下記のように定義されます。DTB イメージのサイズと物理負荷アドレスを表すフィールドがあります。

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_size;   /* size of recovery dtbo image */
        uint64_t recovery_dtbo_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 */
    };

DTB イメージを含められるようにするには、ブートイメージ形式を次のようにアップデートします。

ブートイメージ形式 ページ数
ブートヘッダー(1 ページ) 1
カーネル(l ページ) l=(kernel_sizepage_size-1)÷ page_size
Ramdisk(m ページ) m=(ramdisk_sizepage_size-1)÷ page_size
第 2 段階のブートローダー(n ページ) n=(second_sizepage_size-1)÷ page_size
リカバリ DTBO(o ページ) o=(recovery_dtbo_sizepage_size-1)÷ page_size
DTB(p ページ) p=(dtb_sizepage_size-1)÷ page_size

DTB イメージは次のいずれかの形式を使用する必要があります。

  • 連続して結合されている DT blob。。ブートローダーは各 FDT ヘッダーで totalsize フィールドを使用して、対応する blob の読み取りと解析を行います。
  • DTB / DTBO パーティション構造。ブートローダーでは、エントリのハードウェア識別情報を格納できる dt_table_entry 構造体(idrevcustom の各フィールドが格納されている)を調べることにより、適切な DT blob を効率的に選択できます。

Android 10 は mkbootimg.py を変更して次の引数をサポートできるようにします。

引数 説明
dtb ブート / リカバリ イメージに含める DTB イメージのパス。
dtb_offset base 引数に追加した場合、最終的なデバイスツリーの物理ロードアドレスを表します。たとえば、base 引数が 0x10000000dtb_offset 引数が 0x01000000 の場合、ブートイメージ ヘッダーの dtb_addr_field には 0x11000000 が代入されます。

DTB イメージのパスの指定にはボード構成変数 BOARD_PREBUILT_DTBIMAGE_DIR を使用する必要があります。拡張子が *.dtb であるファイルがディレクトリ BOARD_PREBUILT_DTBIMAGE_DIR に複数存在する場合、Android システムはこれらのファイルを連結して、ブートイメージ作成に使用する最終的な DTB イメージを作成します。

ボード構成変数 BOARD_INCLUDE_DTB_IN_BOOTIMG は true に設定する必要があります。

BOARD_INCLUDE_DTB_IN_BOOTIMG := true

これにより、引数 dtb が、BOARD_PREBUILT_DTBIMAGE_DIR で指定されたディレクトリからの DTB イメージとあわせて mkbootimg.py に渡されます。

dtb_offset 引数は、他のオフセットやヘッダー バージョンとあわせて、ボード構成変数 BOARD_MKBOOTIMG_ARGS に追加できます。

BOARD_MKBOOTIMG_ARGS := --ramdisk_offset $(BOARD_RAMDISK_OFFSET) --dtb_offset $(BOARD_DTB_OFFSET) --tags_offset $(BOARD_KERNEL_TAGS_OFFSET) --header_version $(BOARD_BOOTIMG_HEADER_VERSION)

ブートローダーはアップデートされたブートイメージをサポートする必要があり、また VTS 検証を容易にするために新しいカーネル コマンドライン パラメータ androidboot.dtb_idx を追加して、選択した DT のインデックスを示す必要があります。インデックスは 1 つだけ指定できます。 たとえば、パラメータ androidboot.dtb_idx=N は、ブートイメージにある DT blob のセットのブートローダーにより選択されたデバイスツリーのゼロベースのインデックスとしてパラメータ N を報告します。