カーネルのビルド

このページでは、Android デバイス用にカスタム カーネルをビルドする手順について詳しく説明します。適切なソースを選択する手順、カーネルをビルドする手順、そのビルド結果を Android オープンソース プロジェクト(AOSP)ベースでビルドされたシステム イメージに埋め込む手順について以下で説明します。

最近のカーネルソースは、Repo を使用して取得することが可能で、ソース チェックアウトのルートから build/build.sh を実行することにより、追加構成を行うことなくビルドできます。

ソースとビルドツールをダウンロードする

最近のカーネルの場合、repo を使用してソース、ツールチェーン、ビルド スクリプトをダウンロードします。Pixel 3 カーネルなど、カーネルによっては、複数の Git リポジトリのソースが必要になることがあります。それ以外のカーネルの場合(共通カーネルなど)、必要なのは単一のソースだけです。repo アプローチを使用すると、ソース ディレクトリを確実に正しくセットアップできます。

以下のコマンドで、適切なブランチのソースをダウンロードします。

mkdir android-kernel && cd android-kernel
repo init -u https://android.googlesource.com/kernel/manifest -b BRANCH
repo sync

この方法で取得できるカーネルの BRANCH 名を以下の表に示します。

デバイス AOSP ツリーのバイナリパス Repo ブランチ
Google Pixel 7(Panther)
Google Pixel 6 Pro(Cheetah)
device/google/pantah-kernel android-gs-pantah-5.10-android13-d1
Google Pixel 6a(bluejay) device/google/bluejay-kernel android-gs-bluejay-5.10-android13
Google Pixel 6(Oriole)
Google Pixel 6 Pro(Raven)
device/google/raviole-kernel android-gs-raviole-5.10-android13
Google Pixel 5a(Barbet) device/google/barbet-kernel android-msm-barbet-4.19-android13
Google Pixel 5(Redfin)
Google Pixel 4a (5G)(Bramble)
device/google/redbull-kernel android-msm-redbull-4.19-android13
Google Pixel 4a(Sunfish) device/google/sunfish-kernel android-msm-sunfish-4.14-android13
Google Pixel 4(Flame)
Google Pixel 4 XL(Coral)
device/google/coral-kernel android-msm-coral-4.14-android13
Google Pixel 3a(Sargo)
Google Pixel 3a XL(Bonito)
device/google/bonito-kernel android-msm-bonito-4.9-android12L
Google Pixel 3(Blueline)
Google Pixel 3 XL(Crosshatch)
device/google/crosshatch-kernel android-msm-crosshatch-4.9-android12
Google Pixel 2(Walleye)
Google Pixel 2 XL(Taimen)
device/google/wahoo-kernel android-msm-wahoo-4.4-android10-qpr3
Pixel(Sailfish)
Pixel XL(Marlin)
device/google/marlin-kernel android-msm-marlin-3.18-pie-qpr2
Hikey960 device/linaro/hikey-kernel hikey-linaro-android-4.14
hikey-linaro-android-4.19
common-android12-5.4
Beagle x15 device/ti/beagle_x15-kernel omap-beagle-x15-android-4.14
omap-beagle-x15-android-4.19
Android 共通カーネル なし common-android-4.4
common-android-4.9
common-android-4.14
common-android-4.19
common-android-4.19-stable
common-android11-5.4
common-android12-5.4
common-android12-5.10
common-android13-5.10
common-android13-5.15
common-android-mainline

カーネルをビルドする

次に、以下のスクリプトを実行してカーネルをビルドします。

build/build.sh

カーネル バイナリや、モジュール、対応するイメージは、out/BRANCH/dist ディレクトリにあります。

Bazel(Kleaf)を使用してビルドする

Android 13 では、build/build.sh に代わって、Bazel を使用したカーネルのビルドが導入されました。

aarch64 アーキテクチャ用の GKI カーネルをビルドするには、次のコマンドを実行します。

tools/bazel build //common:kernel_aarch64_dist

ディストリビューションを作成するには、次のコマンドを実行します。

tools/bazel run //common:kernel_aarch64_dist -- --dist_dir=$DIST_DIR

その後、カーネルのバイナリ、モジュール、対応するイメージが $DIST_DIR ディレクトリに配置されます。--dist_dir を指定していない場合のアーティファクトの場所については、コマンドの出力を参照してください。詳しくは、AOSP のドキュメントをご覧ください。

仮想デバイスのベンダー モジュールをビルドする

Android 11 で導入された GKI により、カーネルは Google が管理するカーネル イメージとベンダーが管理するモジュールに分割され、別個にビルドされます。

この例では、カーネル イメージ構成を示しています。

BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh

この例では、モジュール構成(Cuttlefish とエミュレータ)を示しています。

BUILD_CONFIG=common-modules/virtual-device/build.config.cuttlefish.x86_64 build/build.sh

Android 12 では Cuttlefish と Goldfish が収束するため、同じカーネル「virtual_device」を共有します。そのカーネルのモジュールをビルドするには、次のビルド構成を使用します。

BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.x86_64 build/build.sh

Android 13 では、build.sh に代わって Bazel を使用したカーネルのビルド(Kleaf)が導入されました。

virtual_device のモジュールをビルドするには、次のコマンドを実行します。

tools/bazel build //common-modules/virtual-device:virtual_device_x86_64_dist

ディストリビューションを作成するには、次のコマンドを実行します。

tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist -- --dist_dir=$DIST_DIR

Kleaf(Bazel を使用したカーネルのビルド)の詳細については、AOSP のドキュメントをご覧ください。

カーネルを実行する

カスタムビルド カーネルを実行する方法は複数あります。各種の開発シナリオに適した既存の方法を以下に示します。

Android イメージビルドに埋め込む

Image.lz4-dtb を AOSP ツリー内の各カーネル バイナリの場所にコピーして、ブートイメージを再ビルドします。

あるいは TARGET_PREBUILT_KERNEL 変数を定義して、make bootimage など、ブートイメージをビルドする make コマンドラインを使用する方法もあります。この変数は、device/common/populate-new-device.sh を通じてセットアップされるため、すべてのデバイスでサポートされます。たとえば、次のようになります。

export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb

fastboot を使用してカーネルをフラッシュしてブートする

最近のデバイスはブートローダー拡張機能を備えており、ブートイメージの生成とブートのプロセスが効率化されています。

フラッシュせずにカーネルをブートするには、以下のコマンドを使用します。

adb reboot bootloader
fastboot boot Image.lz4-dtb

この方法を使用した場合、カーネルはフラッシュされず、リブート後に保持されることもありません。

カーネルビルドをカスタマイズする

ビルドプロセスとビルド結果は、環境変数の影響を受ける場合があります。環境変数のほとんどは省略可能であり、各カーネル ブランチには適切なデフォルト構成が用意されています。主な環境変数のリストを以下に示します。最新の全リストについては、build/build.sh をご覧ください。

環境変数 説明
BUILD_CONFIG ビルド環境の初期化を行うビルド構成ファイル。ビルドの場所は、Repo ルート ディレクトリを基準とする相対パスで定義する必要があります。デフォルトは build.config です。
共通カーネルでは必須です。
BUILD_CONFIG=common/build.config.gki.aarch64
CC 使用するコンパイラをオーバーライドします。build.config で定義されているデフォルト コンパイラにフォールバックします。 CC=clang
DIST_DIR カーネル配布用のベース出力ディレクトリ。 DIST_DIR=/path/to/my/dist
OUT_DIR カーネルビルドのベース出力ディレクトリ。 OUT_DIR=/path/to/my/out
SKIP_DEFCONFIG make defconfig をスキップします。 SKIP_DEFCONFIG=1
SKIP_MRPROPER make mrproper をスキップします。 SKIP_MRPROPER=1

ローカルビルド用のカスタム カーネル構成

機能の開発時など、カーネル構成オプションを定期的に切り替える必要がある場合や、開発上の目的でオプションを設定する必要がある場合は、ビルド構成をローカルレベルで編集したりコピーしたりすることで、そのような柔軟性を実現することができます。

POST_DEFCONFIG_CMDS 変数を、通常の make defconfig ステップの実行直後に評価されるステートメントに設定します。build.config ファイルはビルド環境に供給されるため、build.config 内で定義されている関数は post-defconfig コマンドの一部として呼び出すことができます。

たとえば、開発段階では、クロスハッチ カーネルのリンク時最適化(LTO)を無効にすることができます。LTO はリリース カーネルにとってはメリットがありますが、ビルド時のオーバーヘッドは相当なものになります。以下のスニペットをローカル build.config に追加することで、build/build.sh の使用時に LTO を永続的に無効にできます。

POST_DEFCONFIG_CMDS="check_defconfig && update_debug_config"
function update_debug_config() {
    ${KERNEL_DIR}/scripts/config --file ${OUT_DIR}/.config \
         -d LTO \
         -d LTO_CLANG \
         -d CFI \
         -d CFI_PERMISSIVE \
         -d CFI_CLANG
    (cd ${OUT_DIR} && \
     make O=${OUT_DIR} $archsubarch CC=${CC} CROSS_COMPILE=${CROSS_COMPILE} olddefconfig)
}

カーネル バージョンを識別する

ビルドのための正しいバージョンは、AOSP ツリーとシステム イメージという 2 つのソースから識別できます。

AOSP ツリーのカーネル バージョン

AOSP ツリーには、ビルド済みのカーネル バージョンが含まれています。Git ログにより、commit メッセージの一部として正しいバージョンを確認できます。

cd $AOSP/device/VENDOR/NAME
git log --max-count=1

カーネル バージョンが Git ログに記載されていない場合は、下記で説明されているように、システム イメージから取得してください。

システム イメージのカーネル バージョン

システム イメージ内で使用されているカーネル バージョンを確認するには、カーネル ファイルに対して次のコマンドを実行します。

file kernel

Image.lz4-dtb ファイルに対しては、次のコマンドを実行します。

grep -a 'Linux version' Image.lz4-dtb

ブートイメージをビルドする

カーネルのビルド環境を使用してブートイメージをビルドできます。そのためには、RAM ディスク バイナリが必要です。これは、GKI ブートイメージをダウンロードして展開することで取得できます。関連付けられている Android リリースの任意の GKI ブートイメージを使用できます。

tools/mkbootimg/unpack_bootimg.py --boot_img=boot-5.4-gz.img
mv $KERNEL_ROOT/out/ramdisk gki-ramdisk.lz4

ターゲット フォルダはカーネルツリーの最上位ディレクトリ(現在の作業ディレクトリ)です。

AOSP マスターを使用して開発している場合は、代わりに ci.android.com にある aosp_arm64 ビルドから ramdisk-recovery.img ビルド アーティファクトをダウンロードして、RAM ディスク バイナリとして使用できます。

取得した RAM ディスク バイナリをカーネルビルドのルート ディレクトリにある gki-ramdisk.lz4 にコピーしたら、次のコマンドを実行してブートイメージを生成できます。

BUILD_BOOT_IMG=1 SKIP_VENDOR_BOOT=1 KERNEL_BINARY=Image GKI_RAMDISK_PREBUILT_BINARY=gki-ramdisk.lz4 BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh

x86 ベースのアーキテクチャを使用している場合は、ImagebzImage に、aarch64x86_64 にそれぞれ置き換えます。

BUILD_BOOT_IMG=1 SKIP_VENDOR_BOOT=1 KERNEL_BINARY=bzImage GKI_RAMDISK_PREBUILT_BINARY=gki-ramdisk.lz4 BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh

このファイルはアーティファクト ディレクトリ $KERNEL_ROOT/out/$KERNEL_VERSION/dist にあります。

ブートイメージは out/<kernel branch>/dist/boot.img に生成されます。