Ubuntu Weekly Recipe

第526回 Ubuntuで最新のカーネルをお手軽にビルドする方法

この記事を読むのに必要な時間:およそ 6 分

カーネルビルド環境の準備

まずはLinuxカーネルのビルドに必要なパッケージをインストールしましょう。

$ sudo apt install git ccache fakeroot libncurses5-dev
$ sudo apt build-dep linux

個別にインストールしているパッケージの用途は次のとおりです。

  • git:ソースコードの取得・管理に使用する
  • ccache:ビルドの高速化(今回は使用しません)
  • fakeroot:カーネルパッケージ作成時に使用
  • libncurses5-dev:カーネルコンフィグ時のUIをビルドする際に必要

次のbuild-depは指定したソースパッケージをビルドする際に必要なパッケージをインストールするサブコマンドです。このコマンドを実行するためには,/etc/apt/sources.listdeb-srcフィールドを有効化しておく必要があります。該当するファイルを手で編集するか,デスクトップ環境であれば「ソフトウェアとアップデート」を起動した上で「Ubuntuのソフトウェア」タブの「ソースコード」にチェックを入れてください。

build-depではソースパッケージのBuild-Dependsフィールドに書かれているパッケージ一式をインストールします。

$ apt showsrc linux
(中略)
Build-Depends: debhelper (>= 9), dh-systemd, cpio, kernel-wedge, ...
(後略)

linuxパッケージの場合はおよそ数百MBのパッケージをダウンロード・インストールすることになりますので,ネットワークとストレージがそれなりに潤沢な環境で実行しましょう。また,ビルド時のみ必要なbuild-depパッケージ群をホストシステムにインストールしたくない場合は,第521回で紹介したLXDなどのように仮想環境上で実行するのも選択肢のひとつになるでしょう。

ちなみに「ビルドする際に必要なパッケージ」に前述のlibncurses5-devなどが入っていないのは,パッケージビルドシステムにおいてはこれらのパッケージが必要ではないためです。あくまでユーザーの環境で,手作業でビルドする際に必要になると思っておけば良いでしょう。

最後にVanillaカーネルの最新のソースコードをダウンロードします。

$ git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
$ cd linux
$ mkdir ../build

最後にビルドデータを置くディレクトリを作っています。

カーネルパッケージをビルドする

カーネルパッケージを作成する際は主に,⁠カーネルコンフィグを設定する」⁠カーネル本体をビルドする」⁠カーネルモジュールをビルドする」⁠パッケージングする」の順番で行われます。

このうちカーネルコンフィグではカーネルの各種機能のオンオフやデフォルトパラメーターの設定,機能をカーネルに組み込むか外部モジュールにするかの選択などを設定します。ゼロからすべてを設定するにはそれなりの知識が必要ですので,既存の設定をベースに個別に改変していくのが一般的です。Ubuntuの場合は既存のコンフィグファイルを流用しましょう。

Ubuntuが動いている実機がある場合は,/bootディレクトリにコンフィグファイルがあります。それをそのままコピーしましょう。

$ cp /boot/config-`uname -r` ../build/.config

実機がない場合や別リリース・別バージョンのカーネルのコンフィグを使いたい場合は,カーネルチームのサイトから持ってくる方法が便利です。特にLXD環境だと/bootが空なので,ホストからコピーするか以下の方法を使う必要があります。

$ wget -O ../build/.config http://kernel.ubuntu.com/~kernel-ppa/config/bionic/linux/4.15.0-21.22/amd64-config.flavour.generic

フレーバーやアーキテクチャーごとにコンフィグファイルが置いてありますので,用途にあわせて選んでください。

UbuntuカーネルのコンフィグからCONFIG_DEBUG_INFOを外しておくと,カーネルのビルド時間が短くなります。crashツールなどでデバッグする予定がないのであれば,次のように外しておいてもいいでしょう。

$ scripts/config --file ../build/.config --disable DEBUG_INFO

ダウンロードしたコンフィグを元に最新のカーネルにあわせて作り直します。

$ make O=../build/ olddefconfig
make[1]: ディレクトリ '/home/ubuntu/kernel/build' に入ります
  HOSTCC  scripts/basic/fixdep
  GEN     ./Makefile
  HOSTCC  scripts/kconfig/conf.o
  YACC    scripts/kconfig/zconf.tab.c
  LEX     scripts/kconfig/zconf.lex.c
  HOSTCC  scripts/kconfig/zconf.tab.o
  HOSTLD  scripts/kconfig/conf
scripts/kconfig/conf  --olddefconfig Kconfig
.config:890:warning: symbol value 'm' invalid for HOTPLUG_PCI_SHPC
.config:1144:warning: symbol value 'm' invalid for NF_NAT_REDIRECT
.config:1147:warning: symbol value 'm' invalid for NF_TABLES_INET
.config:1148:warning: symbol value 'm' invalid for NF_TABLES_NETDEV
.config:1331:warning: symbol value 'm' invalid for NF_TABLES_IPV4
.config:1336:warning: symbol value 'm' invalid for NF_TABLES_ARP
.config:1343:warning: symbol value 'm' invalid for NF_NAT_MASQUERADE_IPV4
.config:1378:warning: symbol value 'm' invalid for NF_TABLES_IPV6
.config:1388:warning: symbol value 'm' invalid for NF_NAT_MASQUERADE_IPV6
.config:1416:warning: symbol value 'm' invalid for NF_TABLES_BRIDGE
.config:3992:warning: symbol value 'm' invalid for HW_RANDOM_TPM
.config:4941:warning: symbol value 'm' invalid for LIRC
.config:6167:warning: symbol value 'm' invalid for SND_SOC_INTEL_SST_TOPLEVEL
.config:6172:warning: symbol value 'm' invalid for SND_SOC_INTEL_MACH
.config:7725:warning: symbol value 'm' invalid for DELL_SMBIOS_WMI
.config:7726:warning: symbol value 'm' invalid for DELL_SMBIOS_SMM
#
# configuration written to .config
#
make[1]: ディレクトリ '/home/ubuntu/kernel/build' から出ます

「warning」が出ている部分は適宜確認してください。netfilterの変更に伴う警告はインパクトが大きそうですが,今回はとりあえず無視します。

カーネルとカーネルモジュールをビルドしましょう。

$ time make -j9 O=../build/ LOCALVERSION=-stock
make[1]: ディレクトリ '/home/ubuntu/kernel/build' に入ります
  GEN     ./Makefile
scripts/kconfig/conf  --syncconfig Kconfig
  GEN     ./Makefile
  WRAP    arch/x86/include/generated/uapi/asm/bpf_perf_event.h
  HOSTCC  scripts/basic/bin2c
(中略)
  LD [M]  sound/usb/usx2y/snd-usb-usx2y.ko
  LD [M]  virt/lib/irqbypass.ko
  LD [M]  sound/x86/snd-hdmi-lpe-audio.ko
make[1]: ディレクトリ '/home/ubuntu/kernel/build' から出ます

real    17m23.013s
user    124m57.950s
sys     11m6.538s

モジュール側は次のようにビルドします。

$ time make modules -j9 O=../build/ LOCALVERSION=-stock

LOCALVERSIONはメインラインビルドとは異なるということを明示するためにつけています。指定してもしなくてもかまいません。またカーネルコンフィグのCONFIG_LOCALVERSION_AUTOを有効にすると,コミットのハッシュが自動的に入ります。これらのラベルはシグネチャとして使われます。あるカーネルに対してシグネチャの異なるカーネルモジュールをロードできませんので注意してください※4)⁠

※4
modprobeコマンドの--force-vermagicオプションでこの値を上書き可能です。

最後にカーネルパッケージを作成しましょう。4.3以降のLinuxにはオリジナルのMakefileにもDebianパッケージを作成するターゲットが存在するので,それを使用します。

$ make bindeb-pkg O=../build/ LOCALVERSION=-stock
make[1]: ディレクトリ '/home/ubuntu/kernel/build' に入ります
/bin/bash /home/ubuntu/kernel/linux/scripts/package/mkdebian
dpkg-buildpackage -r"fakeroot -u" -a$(cat debian/arch) -b -nc -uc
dpkg-buildpackage: info: source package linux-4.18.0-rc2-stock
dpkg-buildpackage: info: source version 4.18.0-rc2-stock-1
dpkg-buildpackage: info: source distribution bionic
(中略)
  INSTALL debian/headertmp/usr/include/xen/ (4 files)
  INSTALL debian/headertmp/usr/include/asm/ (62 files)
dpkg-deb: building package 'linux-headers-4.18.0-rc2-stock' in '../linux-headers-4.18.0-rc2-stock_4.18.0-rc2-stock-1_amd64.deb'.
dpkg-deb: building package 'linux-libc-dev' in '../linux-libc-dev_4.18.0-rc2-stock-1_amd64.deb'.
dpkg-deb: building package 'linux-image-4.18.0-rc2-stock' in '../linux-image-4.18.0-rc2-stock_4.18.0-rc2-stock-1_amd64.deb'.
 dpkg-genbuildinfo --build=binary
 dpkg-genchanges --build=binary >../linux-4.18.0-rc2-stock_4.18.0-rc2-stock-1_amd64.changes
dpkg-genchanges: warning: package linux-image-4.18.0-rc2-stock-dbg in control file but not in files list
dpkg-genchanges: info: binary-only upload (no source code included)
 dpkg-source --after-build build
dpkg-buildpackage: info: binary-only upload (no source included)
make[1]: ディレクトリ '/home/ubuntu/kernel/build' から出ます

bindeb-pkgターゲットはバイナリパッケージのみを,deb-pkgターゲットならソースパッケージも作ってくれます。

$ ls -1 ../*.deb
../linux-headers-4.18.0-rc2-stock_4.18.0-rc2-stock-1_amd64.deb
../linux-image-4.18.0-rc2-stock_4.18.0-rc2-stock-1_amd64.deb
../linux-libc-dev_4.18.0-rc2-stock-1_amd64.deb

Ubuntuのカーネルパッケージと異なり,カーネル本体とモジュール群が同じパッケージにまとめられている点が特徴です。

カーネルパッケージをインストールする

あとはlinux-image*.debパッケージを,テストしたいシステム上にインストールするだけです。またlinux-headersは主にDKMSを使う場合などサードパーティのカーネルモジュールをビルドしたい時に,linux-libc-devはカーネルが提供するUAPIのヘッダーファイルを使用するユーザーランドアプリケーションをビルドしたい時にインストールします。

$ sudo apt ../*.deb

システムを再起動し,GRUBでインストールしたカーネルを選択すれば,新しいカーネルで起動できます。あらかじめ/etc/default/grubGRUB_CMDLINE_LINUX_DEFAULTからquiet splashを削除し,sudo update-grubコマンドを実行することで起動ログが表示されるようにしておいてもよいでしょう。

これで問題なく起動することを確認したら,コンフィグやコードの修正・ビルド・インストールを繰り返すことで,望みのカーネルの完成です。

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member株式会社 創夢所属。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。

コメント

コメントの記入