Ubuntu Weekly Recipe

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

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

パッケージのカスタマイズ

ちゃんとビルドできることを確認したところで,次は実際にパッケージをカスタマイズしてみましょう。

Configファイルの構成

カーネルのカスタマイズの基本は,カーネルコンフィグの変更です。⁠make defconfig」「make menuconfig」で.configファイルを生成・編集するという手順を知っている方も多いでしょう。

Ubuntuのカーネルパッケージの場合,.configの作成はパッケージのスクリプト側で対応します。binary-genericやbinary-debsターゲットを実行したときに,自動的にアーキテクチャやフレーバーごとに.configを生成して,カーネルビルドを行うのです。そのため,Configファイルはアーキテクチャ・フレーバーごとに別途管理されています。

そこでまずはパッケージビルドの大まかな流れを把握したうえで,どんな風にConfigファイルが生成されているのか確認してみましょう。以下のファイルリストは,カーネルのソースパッケージ含まれるファイルの一部を抽出したものです。

debian/
    debian.env
    rules
    rules.d/
    scripts/
debian.master/
    abi/
    changelog
    config/
        amd64/
        armhf/
            config.common.armhf
            config.flavour.generic
            config.flavour.generic-lpae
        config.common.ubuntu
        enforce
    rules.d/
        amd64.mk
        armhf.mk

debian/rulesがビルドスクリプトの本体となります。armhfアーキテクチャに対してdebian/rulesのbinary-genericターゲットを実行すると,おもに次のような処理が行われます。

  1. debian.envが読み出されサブのdebianディレクトリ(debian.master)を決定する。
  2. debian/rules.dとdebian.master/rules.d/armhf.mkを読み込む。debian.master/rules.d/には,アーキテクチャ固有の設定が記述されている。
  3. ビルドするアーキテクチャとフレーバーに合わせて,debian/rules.d/2-binary-arch.mkの"stamp-prepare-tree"ターゲットで,debian.master/config以下にあるConfigファイルを連結し,ビルドディレクトリ(debian/build/build-generic/)に.configとして保存する。
  4. 生成されたConfigのうち,必須オプション(debian.master/config/enforce)が有効になっているかどうかを,debian/scripts/config-checkで確認する。
  5. debian.master/rules.d/armhf.mkのbuild_imageをビルドする。
  6. debian/scripts/module-checkとdebian/scripts/abi-checkを使って,debian.master/abi/以下に保存されている前回リリースしたバージョンのシンボルやモジュールリストと比較を行う。
  7. ビルドしたファイル群をDebianパッケージとしてまとめる。

.configを生成しているのは3.の部分なのですが,ここで使っているのはcatコマンドとmake silentoldconfgです。とどのつまり,次のようなコマンドを実行しているだけです。

$ cat config.common.ubuntu armhf/config.common.armhf armhf/config.flavour.generic > build/build-generic/.config
$ cd build/build-generic; make silentoldconfig

よって,カーネルコンフィグを変更するときは,debian.master/config/以下のファイルを編集します。config.common.ubuntuがフレーバー,アーキテクチャ共通の設定,config.common.armhfがarmhfアーキテクチャ固有の設定,config.flavour.genericがarmhfアーキテクチャのgenericフレーバー固有の設定になります。

フレーバーの追加

Configを大きく変更する場合は,既存のフレーバーを上書きするのではなく,新規にフレーバーを追加することも考えたほうが良いでしょう。おもな編集ポイントは次のとおりです。

  • 「debian.master/rules.d/$(ARCH).mk」のflavours行に,新しいフレーバー名を追加する
  • 「debian.master/config/$(ARCH)/config.flavour.フレーバー名」を作成する
  • ビルド時は「debian/rules binary-フレーバー名」を実行する

今回はMultiPlatform対応のgenericカーネルに,OpenBlocks AX3のConfigを追加するだけなので,新規フレーバーは作成しません。

OpenBlocks AX3の場合

編集すべきところがわかったところで,OpenBlocks AX3に必要な設定を有効にしていきましょう。

OpenBlocks AX3のdefconfigはarch/arm/configs/mvebu_defconfigのようです。このファイルをそのままdebian.master/config/config.common.ubuntuに追加しても良いのですが,既存の設定と重複しているところが多々あります。そこで一度内容を確認してみます。まず,次のようなスクリプトをcheck_config.shという名前で作成してください。

check_config.sh

#!/bin/bash
cat $1 | while read line
do
    [ -z "$line" ] && continue

    if echo $line | grep -q "^#" ; then
        # "# CONFIG_ABC is not set" to "CONFIG_ABC"
        conf=`echo $line | sed "s/^# \(.*\) is not set/\1/"`
    else
        # "CONFIG_ABC=y" to "CONFIG_ABC"
        conf=${line%=*}
    fi
    orig=`grep "$conf[= ]" $2`

    if [ -z "$orig" ]; then
        echo "Added    : $line"
    elif [ "$line" = "$orig" ]; then
        echo "Duplicate: $line"
    elif [ "# $conf is not set" = "$orig" ]; then
        echo "Uncomment: $line"
    elif echo $line | grep -q "^# " ; then
        echo "Commented: $conf (Ubuntu is $orig)"
    else
        echo "Changed  : $orig => ${line#*}"
    fi
done

そして既存のConfigをubuntu_configsという名前のファイルに保存し,比較を行ってみます。

$ cd ubuntu-trusty

$ cat debian.master/config/config.common.ubuntu > ../ubuntu_configs
$ cat debian.master/config/config.common.ports >> ../ubuntu_configs
$ cat debian.master/config/armhf/config.common.armhf >> ../ubuntu_configs
$ cat debian.master/config/armhf/config.flavour.generic >> ../ubuntu_configs

$ chmod u+x ../check_config.sh
$ ../check_config.sh arch/arm/configs/mvebu_defconfig ../ubuntu_configs | sort
Added    : # CONFIG_EXT3_FS_XATTR is not set
Added    : CONFIG_ARMADA_THERMAL=y
Added    : CONFIG_EXPERIMENTAL=y
Added    : CONFIG_I2C_MV64XXX=y
Added    : CONFIG_MACH_ARMADA_370=y
Added    : CONFIG_MACH_ARMADA_XP=y
Added    : CONFIG_MMC_MVSDIO=y
(中略)

Changed  : CONFIG_BT=m -> y
Changed  : CONFIG_BT_MRVL=m -> y
(中略)

Commented: CONFIG_CACHE_L2X0 (Ubuntu is CONFIG_CACHE_L2X0=y)
Commented: CONFIG_DEBUG_BUGVERBOSE (Ubuntu is CONFIG_DEBUG_BUGVERBOSE=y)
Commented: CONFIG_IOMMU_SUPPORT (Ubuntu is CONFIG_IOMMU_SUPPORT=y)
Commented: CONFIG_SCHED_DEBUG (Ubuntu is CONFIG_SCHED_DEBUG=y)
Commented: CONFIG_SWP_EMULATE (Ubuntu is CONFIG_SWP_EMULATE=y)

Duplicate: # CONFIG_COMPACTION is not set
Duplicate: CONFIG_AEABI=y
Duplicate: CONFIG_ARCH_MVEBU=y
(中略)

Uncomment: CONFIG_DEBUG_USER=y
Uncomment: CONFIG_EXT2_FS=y
Uncomment: CONFIG_EXT3_FS=y
Uncomment: CONFIG_GPIO_SYSFS=y
(後略)

Addedがubuntu_configsでは設定されていない項目,ChangedがUbuntuからMVEBUで値が変更された項目,CommentedがMVEBUで「is not set」にされた項目,Duplicateが値が同じ項目,Uncommentが「is not set」から変更された項目です。

Addedは原則としてそのまま追加し,Duplicateは他のところで設定されているために追加する必要はありません。ChangedとConfig,Uncommentは内容によって判断することになります。変更する箇所は,debian.master/config以下のどこにもないものはconfig.flavour.genericに,それ以外については記載のある場所を変更するか,config.flavour.genericを変更するかは随時判断することになるでしょう。今後,カーネルパッケージをアップデートするときに,Ubuntuの変更点を取り込みやすいほうを選びましょう。

編集したら,一度Configを再生成してみます。

$ debian/rules updateconfigs

これによりsilentoldconfigを行うため,未設定の項目についてはプロンプトが表示されます。ビルドの自動化まで考えているのであれば,ここの項目を参考に,さらにdebian.master/configを設定してください。さらにupdateconfigsでは,すべてのアーキテクチャとフレーバーで矛盾がなくなるように,debian.master/config以下を再構築します。このため,config.common.ubuntuに設定されていたものが,armhf/config.flavour.genericと矛盾するために,各アーキテクチャのconfig.flavour.に分散設定されるようになる,ということも起こります。具体的にどこが変更されたかは,⁠git diff⁠などで確認してください。

著者プロフィール

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

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