このページでは、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 ベースのアーキテクチャを使用している場合は、Image
を bzImage
に、aarch64
を x86_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
に生成されます。