前回のAlmaLinuxに引き続いて、Raspberry Pi 4にインストールしたRocky Linuxのカーネルをビルドしたいと思います。カーネルのビルドというと敷居が高そうにも思えますが、手順通りに実行すればさほど難しいものでもないかと思います。
また、カーネルを自前でビルドできるようになれば公開されているイメージには含まれていないドライバーや機能を追加することが出来ますから、Raspberry Pi 4で動かすRocky Linuxをより便利に使用できるようになります。
カーネルも自分の好みに合わせて作り上げることができるというのも、RHEL互換のLinuxとして公開されているRocky Linuxの醍醐味の一つではないでしょうか。
ここでは、例として配布されている状態のままでカーネルをビルドしていくことにします。必要に応じて構成する場合には、途中で実行するmenuconfig
を使用してドライバーや機能を追加、削除することが可能です。
AlmaLinuxもRocky LinuxもRHEL互換ということで、ほとんど同じ手順で違いはカーネルソースの入手方法くらいにはなりますが、ここではRocky Linux用としてまとめています。
前提ソフトウェアのインストール
カーネルをビルドするために必要となる、前提ソフトウェアをインストールします。まず、開発環境としてDevelopment Tools
のパッケージグループをインストールします。ここでは、さらにcmake
もインストールしています。
$ sudo dnf group install -y "Development Tools"
$ sudo dnf install -y cmake
Rocky Linuxのソースは、rpm
形式で提供されていますから、それを展開するためにrpmdevtools
もインストールします。
$ sudo dnf install -y rpmdevtools
また、途中で実行するmenuconfig
で必要となるncurses-devel
とビルド時に使用されているbc
とopenssl-devel
パッケージもインストールしておきます。
$ sudo dnf install -y ncurses-devel bc openssl-devel
Rocky Linuxカーネルソースの入手
まず、AlmaLinuxと同様にraspberrypi2-kernel4
のソースパッケージを検索してみます。
$ dnf download raspberrypi2-kernel4 --source --url
Rocky Linuxの場合には、エラーとなってURLを調べることが出来ませんでした。
No package raspberrypi2-6.1.31-v8.1.el9.altarch.src available.
そこで、Rocky Linuxのダウンロードサイトhttps://dl.rockylinux.org/
を見ると次のURLでソースパッケージが公開されています。バージョン番号がv7.1
となっているのが気にはなりますが、これをダウンロードします。
$ wget https://dl.rockylinux.org/pub/sig/9/altarch/source/altarch-rockyrpi/Packages/r/raspberrypi2-6.1.31-v7.1.el9.altarch.src.rpm
ちなみに、現在実行しているカーネルとしては次の状態になっています。
$ uname -a
Linux rockylinux 6.1.31-v8.1.el9.altarch #1 SMP PREEMPT Sat Jun 10 22:16:20 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux
入手したソースの展開とパッチの適用
入手したソースのrpm
ファイルをrpmdev-extract
コマンドで展開します。
$ rpmdev-extract ./raspberrypi2-6.1.31-v7.1.el9.altarch.src.rpm
raspberrypi2-6.1.31-v7.1.el9.altarch.src
ディレクトリーが作成されて、次のようなファイルが展開されます。
$ ls
bcm2709_selinux_config.patch patch-6.1.31.xz
bcm2711_selinux_config.patch raspberrypi2.spec
cb9500d6021e083a182ba168fe4424e3db2494cf.tar.gz rpi-6.1.x.patch
linux-6.1.tar.xz
まず、linux-6.1.tar.xz
ファイルを解凍します。
$ tar Jxvf linux-6.1.tar.xz
作成されたlinux-6.1
ディレクトリーで、用意されているパッチを適用していきます。
$ cd linux-6.1
$ xz -dc ../patch-6.1.31.xz | patch -p1
$ cat ../rpi-6.1.x.patch | patch -p1
$ cat ../bcm2709_selinux_config.patch | patch -p1
$ cat ../bcm2711_selinux_config.patch | patch -p1
すべてのパッチを適用したら、カーネルのバージョンを確認してみます。
$ sed 4q Makefile
# SPDX-License-Identifier: GPL-2.0
VERSION = 6
PATCHLEVEL = 1
SUBLEVEL = 31
現在実行しているカーネルと同じ6.1.31
になっていました。
カーネルビルドの準備
カーネルをビルドする準備として、次のコマンドを実行しておきます。
$ KERNEL=kernel8
$ make bcm2711_defconfig
menuconfig
の実行
次に、menuconfig
を実行します。実際には、このメニュー画面から必要なドライバーや機能を追加・削除することが出来ます。
$ make menuconfig
このmenuconfig
の画面で矢印キーで画面と項目を移動して、Y
、N
、M
などのキーを押下してドライバー、機能を選択することが出来ます。
ここでは、既定値のままとしてタブキーで「Save」を選択して「Enter」キーを押下します。
.config
を作成するという画面が表示されますから「Ok」のまま「Enter」キーを押下します。
以降、「Exit」を選択してmenuconfig
を終了します。
これで、menuconfig
でドライバー、機能を選択した結果の.config
ファイルが作成されました。
次に、.config
ファイルのCONFIG_LOCALVERSION
の内容を編集しておきます。
$ vi .config
CONFIG_LOCALVERSION="-v8.1.el9-rpi"
ここでは、例として-v8
となっていた内容を-v8.1.el9-rpi
に修正してみました。実際には、構成するカーネルの内容がわかるようにしておくと良いでしょう。
注意点としてビルドしたモジュールが/lib/modules
ディレクトリーに登録されます。その際に、名前が重複してしまわないようにしておくのが良いでしょう。
現在の内容は次のようになっています。
$ ls /lib/modules
5.14.0-284.11.1.el9_2.aarch64 6.1.23-v8.1.el9.altarch
5.14.0-284.25.1.el9_2.aarch64 6.1.31-v8.1.el9.altarch
カーネルビルドの実行
用意ができましたから、実際にカーネルをビルドします。
$ make Image modules dtbs -j4
ここでは、Raspberry Pi 4のCPUコア数が4ですから並列度の引数を-j4
として実行しています。今回は、Raspberry Pi 4の8GBモデルを使用してビルドしていますが、約4時間30分ほどでビルドを完了しています。
ビルドしたカーネルの登録
ビルドが完了したら、新しいカーネルモジュールなどを登録していきます。その前に、念のために/boot
にある内容をバックアップしておきます。
$ sudo mkdir /boot.backup
$ sudo rsync -avhP /boot/ /boot.backup/
万が一、新しいカーネルモジュールなどを登録した後で起動できなくなったような場合には、他で稼働しているコンピューターを使用してバックアップしていた/boot
のファイルをリストアします。これで、元々のカーネルで起動できるようになります。
それでは、実際に新しいカーネルモジュールを登録していきます。
$ sudo make modules_install
$ sudo cp arch/arm64/boot/dts/broadcom/*.dtb /boot/
$ sudo cp arch/arm64/boot/dts/overlays/*.dtb /boot/overlays/
$ sudo cp arch/arm64/boot/dts/overlays/README /boot/overlays/
$ sudo cp arch/arm64/boot/Image /boot/
$ sudo mv /boot/Image /boot/${KERNEL}.img
ここでは、最初に設定していたKERNEL
環境変数を使用している点に注意して下さい。ここまでの作業で、KERNEL環境変数の値が設定されていない場合には、再度設定する必要があります。
注:Raspberry Pi OSの場合には、カーネルイメージがgzip圧縮されていますが、Rocky Lnuxの場合には非圧縮のイメージが使用されています。
Rocky Linux用の設定
Raspberry Pi OSの場合であれば、これまでの設定で大丈夫なのですが、Rocky Linuxの場合には次の作業を追加で実行します。
$ KERNEL_VERSION=6.1.31-v8.1.el9-rpi
$ sudo cp .config /boot/config-$KERNEL_VERSION
$ cd /boot
$ sudo cp kernel8.img kernel-$KERNEL_VERSION.img
$ sudo dracut . --kver $KERNEL_VERSION --gzip
$ sudo chmod 755 initramfs.img
$ sudo cp initramfs.img initramfs-$KERNEL_VERSION.img
$ sudo vi config-kernel.inc
arm_64bit=1
kernel kernel-6.1.31-v8.1.el9-rpi.img
initramfs initramfs-6.1.31-v8.1.el9-rpi.img followkernel
$ sudo cp config-kernel.inc config-kernel-$KERNEL_VERSION
Rocky Linuxでは、カーネルイメージは非圧縮ですがinitramfs
はgzip
圧縮されていますからdracut
コマンドの実行時に--gzip
を引数として追加しています。
新しいカーネルで起動
すべての設定が完了したら、新しいカーネルで起動するために再起動します。
$ sudo reboot
無事に起動したら、カーネルのバージョンを確認してみます。
$ uname -a
Linux rockylinux 6.1.31-v8.1.el9-rpi #1 SMP PREEMPT Sun Sep 17 15:04:18 JST 2023 aarch64 aarch64 aarch64 GNU/Linux
uname
コマンドで表示されるカーネルリリース番号からも、新しくビルドしたカーネルで起動していることがわかります。
今回は、何も新しいドライバーや機能を追加したりしていませんが、これでRaspberry Pi用のRocky Linuxのカーネルを好みに合わせてカスタマイズできるようになりました。