Linuxカーネルビルド環境をCentOS-7からAlmaLinux8に移行したのでビルド手順の差異を調べてみる

## 概要

Linuxカーネルのstableで追加された機能を試す環境として、CentOS-7を長らく利用していたのですが、サポート期限が今年の6月末(204/06/30)で終了してしまいます。そこで新天地(？)としてAlmaLinux-8を次の実験用環境として利用してみることにしました。さっそく年初めにLinux 6.7がリリースされたので、カーネルビルド手順確認も兼ねて調べてみました。

 * [2024年最初のカーネル「Linux 6.7」がリリース⁠⁠、新ファイルシステムBcachefsをサポート](https://gihyo.jp/article/2024/01/daily-linux-240109)(2024/01/09)

カーネルビルドとインストール手順はCentOS-7の頃とほとんど変わらないのですが、 `/boot/loader/entries/*-6.7.x86_64.conf` の内容を手動で変更する必要がありました。この手順を抜かしてしまうと、カーネル起動時に"Faled to start Switch Root."エラーが発生し起動に失敗してしまいます。

このあたりの注意点も踏まえた状態で、AlmaLinux-8でのLinuxカーネルビルド手順をまとめてみました。

## カーネルビルドに必要なパッケージのインストール

事前準備として、カーネルに必要なパッケージのインストールを実施しておきます。 `ncurses-devel` は `make menuconfig` によるカーネルコンフィグで利用され、 [dracut](https://wiki.archlinux.jp/index.php/Dracut) と `grub2` はそれぞれinitramfs(カーネルが起動時に使用する初期イメージ)の作成とブートローダーの更新に使用します。

その他、コンパイラなどのツールはグループインストール機能で一括インストールします。その際の注意点として、グループ名は環境変数 `LANG` によって変わる( `LANG=ja_JP.UTF-8` だと「開発ツール」というグループ名になる)ため、グループインストール時のみ `LANG=C` とするのが個々の環境設定で挙動が変わらずに済むので便利かと思います。

```sh
# sudo dnf install -y ncurses-devel dracut grub2
# LANG=C dnf group install "Development Tools"
```

## カーネルアーカイブの取得と展開、カーネルのコンフィグ設定

```sh
# # カーネルソースアーカイブの取得。
# curl -sLO https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.7.tar.xz
#
# # カーネルソースの展開。
# mkdir -p /usr/src
# tar Jxf local/src/ARCHIVE/linux-6.7.tar.xz -C /usr/src
#
# # カーネルコンフィグの設定
# cd /usr/src/linux-6.7
# make defconfig  # デフォルトコンフィグの作成。
# cp .config .config.defconfig  # 構成変更したカーネルコンフィグとの比較用に、オリジナルをコピーしておく。
# # (カーネルコンフィグを編集する)
# diff -u .config.defconfig .config
```

`.config.defconfig` と設定を変更・追加した `.config` との差分は以下になります。別の実験用に設定していた[bcache](https://wiki.archlinux.jp/index.php/Bcachefs)のコンフィグが混じっていますが、実際は[xfs](https://ja.wikipedia.org/wiki/XFS)をカーネルに組み込む設定のみが追加されていればOKです。

https://gist.github.com/furandon-pig/2394aca4e0702c947a34f3afafa3b195

## カーネルのビルドとインストール

カーネルのビルドとインストールはCentOS-7の頃とほぼ変わりません。一点だけ違う箇所は `initramfs` の作成コマンドが `mkinitrd` ではなく `dracut` になっている所です。

```sh
# # カーネルをビルドします。
# time make -j `cat /proc/cpuinfo | grep processor | wc -l`
#
# # カーネルをインストールします。
# # dracutコマンド実行時のみ、「6.7.0」と指定する点に注意。
# cd /usr/src/linux-6.7
# make modules_install
# cp -f arch/x86_64/boot/bzImage /boot/vmlinuz-6.7.x86_64
# dracut --force /boot/initramfs-6.7.x86_64.img 6.7.0
```

grub(ブートローダー)の更新もCentOS-7の時と同じです。

```sh
# # grub.cfgの更新。
# grub2-mkconfig -o /boot/grub2/grub.cfg
#
# # EFI環境の場合は以下の手順でgrub.cfgを更新してください。
# # grub2-mkconfig -o /boot/efi/EFI/almalinux/grub.cfg
#
# # grubへのエントリ追加。
# grubby --add-kernel=/boot/vmlinuz-6.7.x86_64 --title 'AlmaLinux 8(6.7.x86_64)'
#
# # 追加したエントリが起動時に選択されるように設定します。
# grub2-set-default 0
```

## AlmaLinux-8で追加設定が必要な項目

ここまでの手順はCentOS-7環境でもほぼ同じですが、AlmaLinux-8環境では `/boot/loader/entries/*-6.7.x86_64.conf` への設定を追加する必要があります( `grubby` コマンドで行ってくれても良さそうな気はするのですが…🥺)。

具体的には以下の手順が追加で必要となります。

```sh
# # 既存のloaderコンフィグを確認する。
# ls /boot/loader/entries/c59bd1f73d9744b9914c27c39e91ae61-*.conf
/boot/loader/entries/c59bd1f73d9744b9914c27c39e91ae61-0-rescue.conf
/boot/loader/entries/c59bd1f73d9744b9914c27c39e91ae61-4.18.0-513.5.1.el8_9.x86_64.conf
/boot/loader/entries/c59bd1f73d9744b9914c27c39e91ae61-4.18.0-513.9.1.el8_9.x86_64.conf
/boot/loader/entries/c59bd1f73d9744b9914c27c39e91ae61-6.7.x86_64.conf
# 
# # 既存のloaderコンフィグには「options」の設定がある。
# grep options /boot/loader/entries/c59bd1f73d9744b9914c27c39e91ae61-4.18.0-513.9.1.el8_9.x86_64.conf
options $kernelopts $tuned_params
#
# # 今回ビルドしたlinux-6.7はloaderコンフィグこそ作成されているが、
# # optionsの設定が含まれていない。
# grep options /boot/loader/entries/c59bd1f73d9744b9914c27c39e91ae61-6.7.x86_64.conf | wc -l
0
```

ビルドしたLinuxカーネルのloaderコンフィグは作成されているのですが、既存のものと比べて `options $kernelopts $tuned_params` の設定が入っていません。このため `/boot/loader/entries/*-6.7.x86_64.conf` には手動で `options $kernelopts $tuned_params` の設定を追加します。

```diff
# diff -u /boot/loader/entries/c59bd1f73d9744b9914c27c39e91ae61-6.7.x86_64.conf.ORIG /boot/loader/entries/c59bd1f73d9744b9914c27c39e91ae61-6.7.x86_64.conf
--- /boot/loader/entries/c59bd1f73d9744b9914c27c39e91ae61-6.7.x86_64.conf.ORIG  2024-01-25 03:05:31.702399614 +0900
+++ /boot/loader/entries/c59bd1f73d9744b9914c27c39e91ae61-6.7.x86_64.conf       2024-01-25 03:11:53.073380770 +0900
@@ -2,7 +2,7 @@
 version 6.7.x86_64
 linux /boot/vmlinuz-6.7.x86_64
 initrd /boot/initramfs-6.7.x86_64.img
-options
+options $kernelopts $tuned_params
 id almalinux-0-6.7.x86_64
 grub_users $grub_users
 grub_arg --unrestricted
```

ちなみに、 `options $kernelopts $tuned_params` が入っていない場合、起動時に以下のようなエラーが発生してしまいます…😭

![_img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61137/6bc92894-74ca-d72b-e08d-08b608ba0177.png)

エラー内容は以下のようになっており、一見しただけでは `options $kernelopts $tuned_params` の設定が入っていないことが原因とは分かりづらくなっています…😖

```
[FAILED] Faled to start Switch Root.
See 'systemctl status initrd-switch-root.service' for details.

Generating "/run/initramfs/rdsosreport.txt"
```

ここまでの設定を行ったのち、マシンを再起動するとビルドしたLinuxカーネルで起動してきます。

```sh
# uname -a
Linux alma8test 6.7.0 #1 SMP PREEMPT_DYNAMIC Thu Jan 18 15:55:07 JST 2024 x86_64 x86_64 x86_64 GNU/Linux
```

## まとめ

AlmaLinux-8の環境でLinux-6.7(stable)のカーネルビルドとインストールを行う手順を調べてみました。
Linuxカーネル、というかLinuxディストリビューションはメジャーバージョンが上がるとカーネルビルドとインストールの手順が微妙に変わるので、折に触れて手順をアップデートしておきたいところです。