Ubuntu Weekly Recipe

第333回 カーネルパッケージをビルドしよう

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

実際にビルドしてみる

カーネルパッケージをビルドするには,まず開発環境を準備して,ソースコードを用意し,変更を加えたうえでビルドスクリプトを実行します。詳しいことはUbuntuのドキュメントにまとまっていますが,今回のポイントは次の3つです。

  • ARMカーネルなのでクロスコンパイル環境も準備する
  • Ubuntuカーネルのgitリポジトリからソースコードを取得する
  • 変更するのはdebian.master/の下にある設定ファイルだけ

開発環境の構築

Ubuntu上でカーネルビルドに必要なパッケージをインストールします。ターゲットのアーキテクチャはARMですが,クロスコンパイルするため,amd64アーキテクチャ上でも問題ありません。ただし,Ubuntuのバージョン自体は合わせておいたほうが良いでしょう。

Linuxカーネルをビルドするために必要なパッケージはかなりたくさんあります。このためビルド用に隔離された環境を1つ用意して,その上に開発環境を用意するのも1つの手です。もしLXCを使うなら,以下のように実行すると良いでしょう。

$ sudo apt install lxc
$ sudo lxc-create -t ubuntu-cloud -n linuxbuilder -- --auth-key=/home/`id -un`/.ssh/id_rsa.pub
$ sudo lxc-start -n linuxbuilder -d
$ ssh ubuntu@`sudo lxc-info -in linuxbuilder | awk '{print $2}'`
$ sudo update-alternatives --set editor /usr/bin/vim.basic

もちろん,普段の環境や他の仮想マシン上で行う場合は,上記は必要ありません。最後のコマンドは標準のエディターをnanoからvimに変更しているだけです

次に必要なパッケージをインストールしましょう。

$ sudo apt install git fakeroot build-essential gcc-arm-linux-gnueabihf \
    libncurses5 libncurses5-dev libelf-dev binutils-dev devscripts \
    u-boot-tools
$ sudo apt-get build-dep linux

build-depでそのパッケージを構築するために必要なパッケージをインストールできます。ちなみに13.10以前の環境であれば,linuxはlinux-metaから提供されているため,代わりに「linux-image-`uname -r`」を指定してください。

gitはUbuntuカーネルのソースコードをgitリポジトリから取得するために指定しています。必要に応じてgitの設定もしておきましょう。たとえばコミットログに記載する名前やメールアドレスは次のように設定します。

$ git config --global user.name "Mitsuya Shibata"
$ git config --global user.email shibata@example.com

gcc-arm-linux-gnueabihfは,armhfアーキテクチャ用のクロスコンパイラです。他のアーキテクチャを使う場合は,適宜変更してください。ホストとターゲットが同じCPUアーキテクチャなら,インストールする必要はありません。u-boot-toolsはU-Boot用のイメージファイルを作成する場合に必要になります。

ソースコードのダウンロード

次にカーネルのソースコードをダウンロードします。おもに次の3つのいずれかを実行します。

  • Ubuntuカーネルのgitリポジトリを使う
  • 公式リポジトリにあるソースパッケージをダウンロードする
  • リポジトリにないバージョンをダウンロードする

これまでリリースされたUbuntuカーネルのソースコードは,カーネルチームのgitリポジトリでメンテナンスされています。よって,gitでcloneすれば,特定のリリースのカーネルやその変更履歴が取り出せます。たとえば14.04(コードネームがtrusty)の,実際使っているカーネル(3.13.0-30-generic #55)を取り出すには次のように実行します。

●バージョンの確認
$ uname -a
Linux linuxbuilder 3.13.0-30-generic #55-Ubuntu SMP ...

●ソースコードの取得(時間がかかる)
$ git clone git://kernel.ubuntu.com/ubuntu/ubuntu-trusty.git
$ cd ubuntu-trusty

●上記で確認したバージョンをベースに,新規ブランチを作成
$ git tag -l Ubuntu-3.13.0-30*
Ubuntu-3.13.0-30.54
Ubuntu-3.13.0-30.55
$ git checkout -b openblocks Ubuntu-3.13.0-30.55

gitで取得しておけば,次のカーネルアップデート時も,openblocksブランチをrebaseするだけで,アップデートに追随できるのでお勧めです。ただしgitのcloneには時間がかかるので注意してください。

バージョン管理をしなくても良いのであれば,直接ソースパッケージをダウンロードしても良いでしょう。13.10以前の場合は,⁠linux」「linux-image-`uname -r`」に変更してください。

●最新版をダウンロードする
$ apt-get source linux

●バージョンを指定したい場合
$ apt-get source linux:3.13.0-30.55

この方法でダウンロードできるのは,リポジトリに存在するパッケージだけです。他のリリースのソースコードをダウンロードしたい場合は,ubuntu packagesからパッケージを検索したうえで,ソースパッケージをdgetします。たとえば12.04のカーネルパッケージであれば,ページ下部にあるlinux_3.2.0-65.99.dscファイルを使って,次のように実行します。

$ dget -x http://archive.ubuntu.com/ubuntu/pool/main/l/linux/linux_3.2.0-65.99.dsc

パッケージのビルド

カーネルのソースコードをダウンロードできましたので,まずは何も変更を加えずにパッケージのビルドを試してみましょう。

●クロスコンパイル用の設定
$ export $(dpkg-architecture -aarmhf); export CROSS_COMPILE=arm-linux-gnueabihf-

●debian/controlやビルドディレクトリのセットアップ
$ fakeroot debian/rules clean

●アーキテクチャに依存するパッケージのビルド
$ fakeroot debian/rules binary-generic

●アーキテクチャに依存しないパッケージのビルド
$ fakeroot debian/rules binary-indep

最初の「クロスコンパイル用の設定」は,ホストとターゲットのアーキテクチャが同じなら(amd64上でamd64パッケージをビルドするなら)必要ありません。

3つ目のbinary-genericターゲットは,指定したアーキテクチャに対するgenericフレーバー用のパッケージを作成します注2⁠。別フレーバーをビルドする場合は「generic」の部分をそのフレーバー名に変更し,そのアーキテクチャーでサポートしているすべてのフレーバーをビルドするなど,⁠binary-generic」の代わりに「binary-debs」ターゲットを指定します。

ちなみにbinary-genericは,Intel Core i5-3317U/4GBメモリー/SSDという環境で,だいたい2時間20分ぐらいかかりました注3⁠。

パッケージは親ディレクトリに作成されます。

$ ls ../*.deb
linux-cloud-tools-common_3.13.0-32.56_all.deb
linux-doc_3.13.0-32.56_all.deb
linux-headers-3.13.0-32-generic_3.13.0-32.56_armhf.deb
linux-headers-3.13.0-32_3.13.0-32.56_all.deb
linux-image-3.13.0-32-generic_3.13.0-32.56_armhf.deb
linux-source-3.13.0_3.13.0-32.56_all.deb
linux-tools-common_3.13.0-32.56_all.deb
ubuntu-trusty

linux-cloud-tools-commonは,Hyper-V上でUbuntuを動かす場合に使うデーモンです。linux-docはドキュメント類のパッケージで。linux-headerdsはともにヘッダーファイルなどが入っているパッケージで,カーネルモジュールのビルドやDKMSを利用する場合にどちらも必要になります。linux-imageがカーネルイメージやモジュール類を提供するカーネルパッケージの本体になります。linux-sourceはカーネルソースコードをシステムにインストールするためのパッケージになります。最後のlinux-tools-commonは,カーネルソースのtoolsディレクトリをビルドしたソフトウェアが入っています。

カーネルイメージとモジュール類だけで良いのであれば,linux-imageパッケージをビルドするbinary-genericターゲットのみを実行すれば十分です。

注2)
カーネルフレーバーについては,第278回の記事を参照してください。
注3)
具体的に時間を計測したわけではありません。ビルドを開始した直後に艦隊を「北方鼠輸送作戦」に送り出し,戻ってきたころにビルドも完了したという感じです。

著者プロフィール

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

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