Ubuntuのカーネルパッケージは、
カーネルパッケージをビルドする理由をひねりだす
第278回の
そんなカーネルパッケージですから、
それを踏まえたうえでカーネルパッケージを自前でビルドする必要があるとすれば、
- カーネルそのものやドライバーの開発
Linuxカーネルやカーネルドライバーの開発者であれば、
当然のことながらカーネルをビルドする必要は出てくるでしょう。ただしこのケースの場合は、 Ubuntuのカーネルをベースにすることはほとんどなく、 アップストリームの特定のバージョンのカーネルだったり、 LSP/ BSPなどで提供されるベンダーのコードを利用することになりますし、 あえてパッケージングまで行うこともあまりないはずです。もしパッケージングするとなるとMainlineBuildsという形で、 Debianパッケージに必要なファイル群のカーネルソースコードへの取り込みから行うことになります。 - Ubuntuカーネルの不具合を修正したい
カーネルに起因すると思われる何か不具合に遭遇したときに、
デバッグメッセージを仕込んだカーネルを作成して、 テストします。すでに他の場所で修正されていることがわかっている場合は、 それの修正を取り込んで試してみることもあるでしょう。 - 特定のデバイスやソフトウェアを動かすためにConfigを変更する必要がある
カーネルの特定の機能と連携するタイプのデバイスやソフトウェア
(たとえばsystemdやLXC) を使うとき、 Ubuntuの標準設定とは異なるConfigで、 カーネルを再構築しなければならないときがあります。 - パフォーマンスチューニング
特定の用途向けにLinuxカーネルを使うとき、
パフォーマンスをチューニングするために、 Linuxカーネルのコードその物に手を加えたり、 Configを変更することもあります。パラメーターの変更程度であればカーネルオプションやsysctlでも行えたりしますが、 より深く、 より細かくとなると、 カーネルの再構築も必要になってくるかもしれません。とくにUbuntuのカーネルは、 一般的なデスクトップPCやPCサーバー上で動かすことを想定して設定が行われていますので、 用途を限定したときに不要となるものも多数存在するでしょう。 - 知的好奇心・
勉強・ 興味本位 これは言わずもがな、
ですね。
今回は例としてOpenBlocks AX3のカーネルパッケージを作成してみます。OpenBlocks AX3はMarvellのARMADA XP
幸い、
そこで、
パッケージにするメリット
カーネルをただビルドして使用するだけでなく、
まず複数マシンへのカーネルやモジュール、
さらにパッケージにしておけば、
実際にビルドしてみる
カーネルパッケージをビルドするには、
- ARMカーネルなのでクロスコンパイル環境も準備する
- Ubuntuカーネルのgitリポジトリからソースコードを取得する
- 変更するのはdebian.
master/の下にある設定ファイルだけ
開発環境の構築
Ubuntu上でカーネルビルドに必要なパッケージをインストールします。ターゲットのアーキテクチャはARMですが、
Linuxカーネルをビルドするために必要なパッケージはかなりたくさんあります。このためビルド用に隔離された環境を1つ用意して、
$ 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
もちろん、
次に必要なパッケージをインストールしましょう。
$ 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.
gitはUbuntuカーネルのソースコードをgitリポジトリから取得するために指定しています。必要に応じてgitの設定もしておきましょう。たとえばコミットログに記載する名前やメールアドレスは次のように設定します。
$ git config --global user.name "Mitsuya Shibata" $ git config --global user.email [email protected]
gcc-arm-linux-gnueabihfは、
ソースコードのダウンロード
次にカーネルのソースコードをダウンロードします。おもに次の3つのいずれかを実行します。
- Ubuntuカーネルのgitリポジトリを使う
- 公式リポジトリにあるソースパッケージをダウンロードする
- リポジトリにないバージョンをダウンロードする
これまでリリースされたUbuntuカーネルのソースコードは、
●バージョンの確認 $ 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で取得しておけば、
バージョン管理をしなくても良いのであれば、
●最新版をダウンロードする $ apt-get source linux ●バージョンを指定したい場合 $ apt-get source linux:3.13.0-30.55
この方法でダウンロードできるのは、
$ 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
最初の
3つ目のbinary-genericターゲットは、
ちなみにbinary-genericは、
パッケージは親ディレクトリに作成されます。
$ 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は、
カーネルイメージとモジュール類だけで良いのであれば、
パッケージのカスタマイズ
ちゃんとビルドできることを確認したところで、
Configファイルの構成
カーネルのカスタマイズの基本は、
Ubuntuのカーネルパッケージの場合、
そこでまずはパッケージビルドの大まかな流れを把握したうえで、
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/
- debian.
envが読み出されサブのdebianディレクトリ (debian. master) を決定する。 - debian/
rules. dとdebian. master/ rules. d/ armhf. mkを読み込む。debian. master/ rules. d/には、 アーキテクチャ固有の設定が記述されている。 - ビルドするアーキテクチャとフレーバーに合わせて、
debian/ rules. d/ 2-binary-arch. mkの"stamp-prepare-tree"ターゲットで、 debian. master/ config以下にあるConfigファイルを連結し、 ビルドディレクトリ (debian/ build/ build-generic/) に.configとして保存する。 - 生成されたConfigのうち、
必須オプション (debian. master/ config/ enforce) が有効になっているかどうかを、 debian/ scripts/ config-checkで確認する。 - debian.
master/ rules. d/ armhf. mkのbuild_ imageをビルドする。 - debian/
scripts/ module-checkとdebian/ scripts/ abi-checkを使って、 debian. master/ abi/以下に保存されている前回リリースしたバージョンのシンボルやモジュールリストと比較を行う。 - ビルドしたファイル群をDebianパッケージとしてまとめる。
.configを生成しているのは3.の部分なのですが、
$ cat config.common.ubuntu armhf/config.common.armhf armhf/config.flavour.generic > build/build-generic/.config $ cd build/build-generic; make silentoldconfig
よって、
フレーバーの追加
Configを大きく変更する場合は、
- 「debian.
master/ rules. d/$(ARCH).mk」 のflavours行に、 新しいフレーバー名を追加する - 「debian.
master/ config/$(ARCH)/config. flavour.フレーバー名」 を作成する - ビルド時は
「debian/ rules binary-フレーバー名」 を実行する
今回はMultiPlatform対応のgenericカーネルに、
OpenBlocks AX3の場合
編集すべきところがわかったところで、
OpenBlocks AX3のdefconfigはarch/
#!/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_
$ 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_
Addedは原則としてそのまま追加し、
編集したら、
$ debian/rules updateconfigs
これによりsilentoldconfigを行うため、
DTBファイルのインストール
ハードウェアのプロパティについて記述するDevice Treeに対応したアーキテクチャであれば、
$ echo -e 'dtb_files_generic\t+= armada-xp-openblocks-ax3-4.dtb' >> debian.master/rules.d/armhf.mk
armhf.
debian.master/changelogの編集
最後にdebian.
$ dch -v "$(dpkg-parsechangelog -SVersion -ldebian.master/changelog)+obs1" \ -c debian.master/changelog "Support OpenBlocks AX3" Linux (3.13.0-30.55+obs1) trusty; urgency=low (変更点をここに記述) Linux (3.13.0-30.55) trusty; urgency=low (3.13.0-30.55リリース時の変更点) Linux (3.13.0-30.54) trusty; urgency=low
ただし、
$ skipmodule=true skipabi=true fakeroot debian/rules binary-generic
上記のようにskipmodule/
あとは
そして次のステップへ
新規に作成したカーネルパッケージは、
今回の例ではパッケージ名が公式リポジトリのそれと同じになるので、
ARMデバイスのように、
Initramfs
カーネルそのものはMultiPlatformに対応しているARMデバイスすべてで共通になるのですが、
別にインストーラーは必要ないということであれば、
このようにデバイスによっては、