2025年7月9日水曜日

Linux カーネルを docker を使ってビルドしテストする

Linux カーネルを docker を使ってビルドしテストする

概要

docker 上で Linux カーネルのソースコードをビルドしビルドしてできたカーネルイメージファイルを使って docker 上で動作確認します
ビルド用のイメージとテスト用のイメージを作成しています
またテスト時には docker 上で QEMU + busybox でカスタムカーネルイメージを動かします

今回は M2pro mac mini 上でビルドしたのでカーなるは aarch64 向けのカーネルになります

環境

  • M2pro mac mini
    • macOS 15.5
  • docker 28.3.0
    • Ubuntu 24.04
  • Linux kernel 6.15

Linux カーネルビルド用のイメージ作成

  • mkdir kernel_build
  • cd kernel_build
  • vim Dockerfile
FROM ubuntu:24.04

# 必要なツールをインストール
RUN apt update && DEBIAN_FRONTEND=noninteractive apt install -y \
    git build-essential libncurses-dev bison flex libssl-dev libelf-dev bc \
    && apt clean

# ビルド作業ディレクトリ
WORKDIR /kernel

# 実行シェル
CMD ["bash"]
  • docker build -t kernel-builder .

Linux カーネルのソースコードを取得する

テストする際にちゃんと自分でビルドした Linux カーネルイメージかどうか確認しやすいように Linux カーネル名を変更しておきます

  • git clone --depth=1 --branch v6.15 https://github.com/torvalds/linux.git
  • cd linux
  • vim Makefile
EXTRAVERSION = -custom123

ビルドする

  • docker run --rm -it -v $(pwd):/kernel -v ./kernel-build-out:/kernel_build kernel-builder

以下は起動したコンテナ上で実行します

  • cd /kernel/linux
  • make defconfig
  • make -j$(nproc)
  • make modules -j$(nproc)

ビルドが完了したら成果物である Linux カーネルイメージをコピーしておきます

  • cp ./arch/arm64/boot/Image /kernel_build/

エラーが出る場合は make -j$(nproc) 2>&1 | tee build.log で再度実行しエラーログを確認しましょう

Linux カーネルテスト用のイメージ作成

生成された Linux カーネルイメージは QEMU を使ってテストします
なので qemu と busybox が使えるイメージを準備します

  • vim test.dockerfile
FROM ubuntu:24.04

RUN apt update && apt install -y cpio qemu-system-aarch64 busybox-static && apt clean

WORKDIR /test

CMD ["bash"]
  • docker build -t kernel-tester -f test.dockerfile .

テストする

  • docker run --rm -it -v ./kernel-build-out:/kernel_build kernel-tester

以下は起動したコンテナ上で実行します

起動のための簡易的なファイルシステムを準備します
busybox の使い方などはこの記事内では説明しないので興味があれば調べてみてください

  • mkdir -p /kernel_build/initramfs_root
  • cd /kernel_build/initramfs_root
cat > init << 'EOF'
#!/bin/sh
mount -t proc proc /proc
exec /bin/sh
EOF
  • chmod +x init
  • mkdir -p bin proc
  • cp /usr/bin/busybox bin/sh
  • cp /usr/bin/busybox bin/mount
  • find . | cpio -o --format=newc > ../initramfs.cpio

あとは QEMU を使って Linux カーネルイメージを指定し起動します

  • cd /kernel_build
qemu-system-aarch64 \
  -M virt \
  -cpu cortex-a53 \
  -nographic \
  -kernel ./Image \
  -append "console=ttyAMA0" \
  -initrd ./initramfs.cpio

動作確認

QEMU が起動したら以下のようなプロンプトが表示されれば OK です

[    0.529104] clk: Disabling unused clocks
[    0.529510] PM: genpd: Disabling unused power domains
[    0.530130] ALSA device list:
[    0.530334]   No soundcards found.
[    0.568895] Freeing unused kernel memory: 11200K
[    0.569684] Run /init as init process


BusyBox v1.36.1 (Ubuntu 1:1.36.1-6ubuntu3.1) built-in shell (ash)
Enter 'help' for a list of built-in commands.

/bin/sh: can't access tty; job control turned off
~ #

試しに uname -an を実行してみると自分で設定した Linux カーネル名になっていることが確認できると思います

~ # uname -an
Linux (none) 6.15.0-custom123-g0ff41df1cb26-dirty #1 SMP PREEMPT Tue Jul  8 03:03:15 UTC 2025 aarch64 GNU/Linux

最後に

Linux カーネルのソースコードを M2pro mac mini 上でビルドしてみました
初回のビルドは30分から1時間ほどかかります
2回目以降はエラーや修正部分のみ再度ビルドされるので早くビルドできます

一応これで Linux カーネルをトライ&エラーできる環境はできたのであとは C のコードを修正すれば Linux カーネルにコミットできるかもしれません

0 件のコメント:

コメントを投稿