CentOS 7のカーネルをソースコードからビルドする
この記事について
この前、素人ながらLinuxカーネルモジュールを修正する事になりました。なんとなく難しい気がして、もう一層Linuxカーネルそのものをビルドしようっと間違った道に走ってしまい…
結局、今は欲しいモジュールだけをビルドして使ってますが、後で役に立つかもしれないので立って欲しくないですがソースコードを探す所からの過程をまとめてみました。
※多くの場合、カーネルをソースコードからビルドしてまで使う必要はないと思います。凄く手間のかかる作業なので本当に必要なのかもう一度考えてみましょう。
ビルドに必要なパッケージをダウンロードする
yum
でDevelopment Tools
をインストールします。apt-get
のbuild-essential
みたいに関連ツールを一括ダウンロードしてくれます。
$ sudo yum groupinstall "Development Tools"
カーネルをビルドする時必要なツールです。
$ sudo yum install rpm-build redhat-rpm-config asciidoc hmaccalc perl-ExtUtils-Embed pesign xmlto
$ sudo yum install audit-libs-devel binutils-devel elfutils-devel elfutils-libelf-devel java-devel
$ sudo yum install ncurses-devel newt-devel numactl-devel pciutils-devel python-devel zlib-devel
私の場合、net-tools
とbc
も要求されました。
$ sudo yum install net-tools bc
ソースコードを手に入れる
CentosのWikiを参考しました1。ソースコードはSRPM(Source RPM)を利用してダウンロードします。SRPMファイルは以下のURLからダウンロードできます。{バージョン}
の所は欲しい数字に変えてください。
http://vault.centos.org/{バージョン}/os/Source/SPackages/
http://vault.centos.org/{バージョン}/updates/Source/SPackages
カーネルをビルドする時は一般ユーザーモードからすることが勧められているそうです2。ユーザーに変更しましょう。
$ su user
ソースコードをダウンロードするディレクトリを作ります。
$ mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
$ echo '%_topdir %(echo $HOME)/rpmbuild' > ~/.rpmmacros
srpmファイルをインストールします。
$ rpm -i http://vault.centos.org/7.3.1611/os/Source/SPackages/kernel-3.10.0-514.el7.src.rpm 2>&1 | grep -v exist
rpmbuild
を使ってソースコードを得ることができます。パッチを当てたい場合kernel.specを修正する必要があるみたいです。
$ cd ~/rpmbuild/SPECS
$ rpmbuild -bp --target=$(uname -m) kernel.spec
ソースコードが~/rpmbuild/BUILD/kernel*/linux*/
ディレクトリに展開されます。
ビルド
~/rpmbuild/BUILD/kernel*/linux*/
で作業します。
installではroot
権限が必要なのでroot
になるかsudo
を使う必要があります。
一旦、初期化します。
$ make mrproper
設定ファイルを生成します。
$ make menuconfig
ビルドします。これからの作業はかなり時間が掛かります。必ず-j
オプションを与えましょう。
$ make
モジュールをコンパイルします。
$ make modules
コンパイルされたモジュールを/lib/modules
にインストールします。
$ make modules_install
コンパイルされたカーネルをインストールします。
$ make install
確認
起動するカーネルを確認します。インストールしたカーネルになっていると思います。
$ grub2-editenv list
現在利用できるカーネルのリストは以下のコマンドでみれます。grub2.cfg
ファイルの名前は違う場合がありますので失敗する場合は/etc
の下でそれっぽいファイルを探しましょう。
$ awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
新しいカーネルで起動して欲しくない場合デフォルトを変えます。上で出力された数字かフルネームを使って指定できます。
$ grub2-set-default {上で出力された番号もしくは名前}
注意
- 本文の中では通り過ぎましたが
make menuconfig
には注意すべきだと思います。例えば、カーネルの名前を認識して動作するプログラムはしばしばありますのでmake menuconfig
で設定するローカルネームは大事かもしれません。