AlmaLinux 第22回「Raspberry Pi用のAlmaLinuxでカーネルをビルドする」

今回は、Raspberry Pi 4にインストールしたAlmaLinuxのカーネルをビルドしたいと思います。カーネルのビルドというと敷居が高そうにも思えますが、手順通りに実行すればさほど難しいものでもないかと思います。

また、カーネルを自前でビルドできるようになれば公開されているイメージには含まれていないドライバーや機能を追加することが出来ますから、Raspberry Pi 4で動かすAlmaLinuxをより便利に使用できるようになります。

カーネルも自分の好みに合わせて作り上げることができるというのも、RHEL互換のLinuxとして公開されているAlmaLinuxの醍醐味の一つではないでしょうか。

ここでは、例として配布されている状態のままでカーネルをビルドしていくことにします。必要に応じて構成する場合には、途中で実行するmenuconfigを使用してドライバーや機能を追加、削除することが可能です。

前提ソフトウェアのインストール

カーネルをビルドするために必要となる、前提ソフトウェアをインストールします。まず、開発環境としてDevelopment Toolsのパッケージグループをインストールします。ここでは、さらにcmakersyncvimなどをインストールしています。

$ sudo dnf group install -y "Development Tools"
$ sudo dnf install -y cmake rsync vim

AlmaLinuxのソースは、rpm形式で提供されていますから、それを展開するためにrpmdevtoolsもインストールします。

$ sudo dnf install -y rpmdevtools

また、途中で実行するmenuconfigで必要となるncurses-develとビルド時に使用されているbcopenssl-develパッケージもインストールしておきます。

$ sudo dnf install -y ncurses-devel bc openssl-devel

AlmaLinuxカーネルソースの入手

Raspberry Pi用のAlmaLinuxのカーネルはraspberrypi2-kernel4パッケージで提供されています。そこで、このソースのURLを参照します。

$ dnf download raspberrypi2-kernel4 --source --url

しばらくするとソースのURLが表示されました。

http://repo.almalinux.org/vault/9.2/raspberrypi/Source/Packages/raspberrypi2-6.1.31-v8.1.el9.src.rpm

ちなみに、現在実行しているカーネルとしては次の状態になっています。

$ uname -a
Linux almalinux.local 6.1.31-v8.1.el9 #1 SMP PREEMPT Wed Jun 14 12:18:16 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux

ソースのURLがわかりましたから、wgetまたはcurlでダウンロードします。

$ wget http://repo.almalinux.org/vault/9.2/raspberrypi/Source/Packages/raspberrypi2-6.1.31-v8.1.el9.src.rpm

入手したソースの展開とパッチの適用

入手したソースのrpmファイルをrpmdev-extractコマンドで展開します。

$ rpmdev-extract ./raspberrypi2-6.1.31-v8.1.el9.src.rpm 

raspberrypi2-6.1.31-v8.1.el9.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の画面

このmenuconfigの画面で矢印キーで画面と項目を移動して、YNMなどのキーを押下してドライバー、機能を選択することが出来ます。

ここでは、既定値のままとしてタブキーで「Save」を選択して「Enter」キーを押下します。

.configの作成画面

.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
6.1.31-v8.1.el9

先に確認したバージョンが6.1.31で同じですから、上記のCONFIG_LOCALVERSIONの内容が-v8.1.el9になると重複してしまいます。そのため、この例ではRaspberry Pi用ということで-rpiを追加しています。

カーネルビルドの実行

用意ができましたから、実際にカーネルをビルドします。

$ 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圧縮されていますが、AlmaLinuxの場合には非圧縮のイメージが使用されています。

AlmaLinux用の設定

Raspberry Pi OSの場合であれば、これまでの設定で大丈夫なのですが、AlmaLinuxの場合には次の作業を追加で実行します。

$ 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

AlmaLinuxでは、カーネルイメージは非圧縮ですがinitramfsgzip圧縮されていますからdracutコマンドの実行時に--gzipを引数として追加しています。

新しいカーネルで起動

すべての設定が完了したら、新しいカーネルで起動するために再起動します。

$ sudo reboot

無事に起動したら、カーネルのバージョンを確認してみます。

$ uname -a
Linux almalinux.local 6.1.31-v8.1.el9-rpi #1 SMP PREEMPT Sun Sep 17 00:07:44 JST 2023 aarch64 aarch64 aarch64 GNU/Linux

unameコマンドで表示されるカーネルリリース番号からも、新しくビルドしたカーネルで起動していることがわかります。

今回は、何も新しいドライバーや機能を追加したりしていませんが、これでRaspberry Pi用のAlmaLinuxのカーネルを好みに合わせてカスタマイズできるようになりました。

この記事をシェアする
  • URLをコピーしました!
  • URLをコピーしました!
目次