インストール - カーネルのアッブグレード(SUSE)
概要
Tumbleweedを除いたSUSEは安定したカーネルのみを提供している。
これは、最新のカーネルよりもはるかに古いことが多い。
ここでは、SUSEにおいて、カーネルをアップグレードする方法を記載する。
Zypper構成ファイルの変更
まず、/etc/zypp/zypp.confファイル(Zypper構成ファイル)を開く。
sudo vi /etc/zypp/zypp.conf
zypp.confファイルには、多くの設定項目が存在する。
このファイルにあるmultiversion.kernels
項目を探して、この項目がコメントアウトされている場合は、コメントを解除する。
この設定を有効にすると、SUSEに同梱されている従来のカーネルを維持しながら、新しいカーネルも取得できるようになる。
初期設定では、multiversion.kernels
の値は、latest,latest-1,running
となっている。
この値を、latest,latest-1,running,oldest
に変更する。
# /etc/zypp/zypp.confファイル multiversion.kernels = latest,latest-1,running,oldest
リポジトリを追加してインストール
Linuxカーネル用のリポジトリの追加
最も簡単に比較的新しいLinuxカーネルをインストールするには、カーネルリポジトリを追加してパッケージ管理システムからインストールすることである。
SUSEの標準リポジトリ(メインライン)には、比較的新しいLinuxカーネルは存在しないため、カーネルリポジトリを追加する必要がある。
カーネルリポジトリを追加するため、以下のコマンドを実行する。
sudo zypper ar -f http://download.opensuse.org/repositories/Kernel:/stable/standard Kernel:Stable # 推奨 または sudo zypper ar -f http://download.opensuse.org/repositories/Kernel:/HEAD/standard/ Kernel:Master
ただし、通常のzypper update
コマンドでアップグレードせずに、以下のセクションにしたがってdist-upgrade
コマンドを実行することに注意する。
Linuxカーネルのアップグレード
SUSEにおいて、別途Linuxカーネルをインストールする場合、カーネルリポジトリからのみアップグレードすることにより、Linuxカーネルのみが変更される。
Linuxカーネルのアップグレードを行うため、以下のコマンドを実行する。
sudo zypper dist-upgrade -r <Kernel:Stable または Kernel:Master>
※注意
Linuxカーネルをアップグレードする場合、上記の"Zypper構成ファイル"セクションで編集したmultiversion.kernels
の設定により、古いバージョンが保持されることに注意する。
アップグレードが完了した後、Linuxを再起動する。
再起動後、Linuxカーネルが正常にアップグレードされたかどうかを確認する。
uname -a
ソースコードからインストール
依存関係のライブラリのインストール
Linuxカーネルのビルドに必要な依存関係のライブラリをインストールする。
sudo zypper install bc bison flex patterns-base-basesystem patterns-devel-base-devel_basis patterns-devel-C-C++-devel_C_C++ \ gcc ncurses-devel ncurses5-devel libopenssl-1_1-devel libelf-devel dwarves
Linuxカーネルのソースコードのダウンロード
The Linux Kernel Archivesまたは以下に示すURLからLinuxカーネルのTarballをダウンロードする。
https://kernel.org/pub/linux/kernel/
ダウンロードしたファイルを解凍する。
tar xf linux-<バージョン>.tar.xz cd linux-<バージョン>
または、Gitからダウンロードする。
SUSEが提供しているLinuxカーネルのソースコードを使用する場合、SUSEのGithubからソースコードをダウンロードする。
SUSEのLinuxカーネルは、2種類存在している。
- 開発版 (比較的新しいLinuxカーネル)
- 開発版はkernel-sourceというGitリポジトリで行われており、アップストリームカーネルに対するパッチ、仕様ファイル、様々なスクリプト等が含まれている。
git clone https://github.com/SUSE/kernel-source -b stable
- 安定版 (現在と同一バージョンのLinuxカーネル)
- ソースコードのハック等が目的で、かつ、カーネルをパッケージ化する必要が無い場合は、安定版を使用する。
- 安定版は、アップストリームのカーネルと同様のレイアウトになっている。
git clone https://github.com/SUSE/kernel -b stable
Linuxカーネルのビルド環境の構築
Linuxカーネルのビルドディレクトリを作成する。
out-of-treeビルド(ソースコードと生成物を分離したビルド)の為のディレクトリを作成する。
mkdir build
異なるバージョンのカーネルをビルドする場合、または、特定の機能を有効化 / 無効化する場合、現在利用しているカーネルコンフィグのコピーをそのまま使用することができない。
そのため、既存のカーネルコンフィグ(/bootディレクトリ内にあるカーネルコンフィグ)を元に、新しいカーネルコンフィグを生成する。
make olderconfig
コマンドは、可能な限り既存のカーネルコンフィグの設定を使用して、ビルドディレクトリ内に必要なファイルを生成する。
make -j $(nproc) olddefconfig O=./build
以下に示すような警告が出力される場合がある。
不要ならば、.configファイルから該当する設定をコメントアウトする。
.config:9850:warning: symbol value 'm' invalid for CRYPTO_BLAKE2S_X86 .config:9941:warning: symbol value 'm' invalid for CRYPTO_ARCH_HAVE_LIB_BLAKE2S .config:9942:warning: symbol value 'm' invalid for CRYPTO_LIB_BLAKE2S_GENERIC
ビルドディレクトリに移動する。
cd build
Linuxカーネルのビルドを行う場合、同時にカーネルモジュールをビルドすることが一般的であるが、使用しないカーネルモジュールのビルドに多くの時間が掛かることがある。
make localmodconfig
コマンドは、現在のカーネルモジュールの設定を使用して、不要なカーネルモジュールのビルドを無効化することができる。
make -j $(nproc) localmodconfig
Linuxカーネルの機能を個別に選択する。
make -j $(nproc) menuconfig
Linuxカーネルおよびカーネルモジュールをビルドおよびインストールする。
LOCALVERSION=<サフィックス 例. -userbuild> make -j $(nproc) sudo make -j $(nproc) modules_install # カーネルモジュールのインストール sudo make -j $(nproc) install # Linuxカーネルのインストール(GRUB2のエントリも生成する)
初期化スクリプトを生成する。
sudo mkinitrd
GRUB2ブートメニューの設定
GRUB2を使用している場合、かつ、GRUB2スクリプトが新しいカーネルを自動検出できない場合、手動で/etc/grub.d/40_customファイルに関連情報を追加することができる。
なお、UUID名またはPARTUUID名は、sudo blkid
コマンドを使用することにより、確認することができる。
sudo vi /etc/grub.d/40_custom
# /etc/grub.d/40_customファイル menuentry '<任意のLinuxカーネル名 例. kernel x.y.z>' { echo '<Linuxカーネルの読み込み時のメッセージ>' linux <vmlinuzファイルのパス> root=UUID=<ルートパーティションがあるUUIDまたはPARTUUID> <Linuxカーネルのパラメータ> echo '<初期化スクリプト(initrd)の読み込み時のメッセージ>' initrd <initrdファイルのパス> } # 例 menuentry 'kernel x.y.z' { echo 'Loading Linux x.y.z ...' linux /boot/vmlinuz root=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ${extra_cmdline} splash=vervose resume=/dev/disk/by-uuid/<SWAPパーティションのUUID> preempt=full security=apparmor mitigations=auto echo 'Loading initial ramdisk ...' initrd /boot/initrd }
GRUB2の変更を有効にするため、GRUB2を更新する必要がある。
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
Linuxを再起動する。
sudo shutdown -r now
再起動後、Grubブートローダにおいて、インストールしたLinuxカーネルを選択する。
セキュアブートが有効の場合
署名の登録
pesignとnss-toolsをインストールする。
pesignのインストールと同時に、/etc/pki/pesignディレクトリ、および、/etc/pki/pesign-rh-testディレクトリにデータベースがインストールされる。
sudo zypper install pesign mozilla-nss-tools
certificateファイルを抽出する。
mkdir ~/MOK && cd ~/MOK sudo certutil -d /etc/pki/pesign-rh-test -L -n "Red Hat Test CA" -r > rhca.cer
抽出したcertファイルを署名する。
sudo mokutil --import ./rhca.cer --roow-pw
正常に署名されているかどうかを確認する。
sudo mokutil --list-new
PCを再起動する。
sudo systemctl reboot
カーネルへの署名を行う。
この時、-i
オプションを付加して、vmlinuz(bzImageイメージ)のパスを指定する。
sudo pesign -c 'Red Hat Test Certificate' --certdir /etc/pki/pesign-rh-test \ -i <vmlinuz(bzImageファイル)のパス 例. /boot/vmlinuz-x.xx.xx> \ -o vmlinuz.signed -s
署名および生成されたLinuxカーネルであるvmlinuz.signedファイル名を変更する。
この時、ファイル名は任意の名前でよい。
mv vmlinuz.signed vmlinuz-<カーネルのバージョン>-user-build
vmlinuzファイルを/bootディレクトリに配置する。
sudo mv vmlinuz-<カーネルのバージョン>-user-build /boot
PCを再起動する。
ブート画面において、生成したLinuxカーネルを選択する。
sudo systemctl reboot
起動しているLinuxカーネルを確認する。
uname -a
署名の削除
署名を削除する時、そのカーネルでは起動できなくなることに注意する。
cd <署名ファイルがあるディレクトリ> sudo mokutil --delete ./rhca.cer --root-pw
GRUBの設定
Linuxのブート画面において、デフォルトで読み込まれるLinuxカーネルを変更する。
SUSEがLinxuカーネルのマルチバージョンに対応しているかどうかを確認する。
sudo vi /etc/zypp/zypp.conf
# /etc/zypp/zypp.confファイル multiversion = provides:multiversion(kernel)
GRUB2のサブメニューの変数$menuentry_id_option
を検索する。
sudo grep submenu /boot/grub2/grub.cfg # 出力例 submenu 'Advanced options for SUSE Linux Enterprise 15 SP4' --hotkey=1 $menuentry_id_option 'gnulinux-advanced-xxx' {
使用するLinuxカーネルのメニューエントリの変数$menuentry_id_option
を検索する。
sudo awk '/menuentry/ && /class/ {count++; print count-1"****"$0 }' /boot/grub2/grub.cfg # 出力例 0****menuentry 'SUSE Linux Enterprise 15 SP4' --class opensuse --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-b9406985-a289-4710-be6b-c74f2c200075' { 1**** menuentry 'SUSE Linux Enterprise 15 SP4, with Linux 5.14.21-150400.24.28-default' --hotkey=2 --class opensuse --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.14.21-50400.24.28-default-advanced-xxx' { 2**** menuentry 'SUSE Linux Enterprise 15 SP4, with Linux 5.14.21-150400.24.28-default (recovery mode)' --hotkey=3 --class opensuse --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.14.21-150400.24.28-default-recovery-yyy' { 3**** menuentry 'SUSE Linux Enterprise 15 SP4, with Linux 5.14.21-150400.24.21-default' --class opensuse --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.14.21-150400.24.21-default-advanced-zzz' { 4**** menuentry 'SUSE Linux Enterprise 15 SP4, with Linux 5.14.21-150400.24.21-default (recovery mode)' --hotkey=1 --class opensuse --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.14.21-150400.24.21-default-recovery-aaa' {
/etc/default/grubファイルにあるGRUB_DEFAULT
をコメントアウトして、
上記で表示したサブメニューの変数$menuentry_id_option
とLinuxカーネルのメニューエントリ変数$menuentry_id_option
に、>
で区切って置き換える。
sudo vi /etc/default/grub
# /etc/default/grubファイル #GRUB_DEFAULT=saved GRUB_DEFAULT="<サブメニュー変数$menuentry_id_optionの値 例. gnulinux-xxx>><メニューエントリ変数$menuentry_id_optionの値 例. gnulinux-<バージョン>.xxx-yyy>"
GRUB2を更新する。
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
元のLinuxカーネルに戻す場合、/etc/default/grubファイルにあるGRUB_DEFAULT
の設定を戻す。
sudo vi /etc/default/grub # /etc/default/grubファイル GRUB_DEFAULT=saved #GRUB_DEFAULT="<サブメニュー変数$menuentry_id_optionの値 例. gnulinux-xxx>><メニューエントリ変数$menuentry_id_optionの値 例. gnulinux-<バージョン>.xxx-yyy>"
GRUB2を更新する。
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
vmlinuzファイルの展開と逆アセンブル
vmlinuzとは
vmlinuzは、システムを起動して、カーネルをメモリにロードすることができる圧縮されたLinuxカーネルのイメージである。
また、vmlinuxは静的にリンクされた実行ファイルであり、カーネルはELF、COFF、a.out等のオブジェクトファイル形式をサポートしている。
vmlinuzとvmlinuxは似た名前であるが、vmlinuxはvmlinuzの圧縮されていないブート不可能なバージョンのことである。
(vmlinuz : Virtual Memory Linuz linuzはLinuxの圧縮版の意味)
アセンブリコードの問題の特定、または、特定の関数がどのように実行されているかをデバッグする場合、vmlinuzを抽出する。
vmlinuzファイルの展開
現在使用しているvmlinuzファイルの種類を確認する。
file /boot/vmlinuz-$(uname -r) # 出力例 vmlinuz-5.14.21-150400.24.28-default: Linux/x86 Kernel, Setup Version 0x20f, bzImage, Version 5.14.21-150400.24.28-default (geeko@buildhost) #1 SMP PREEMPT_DYNAMIC Mon Oct 10 15:21:12 UTC 2, RO-rootFS, swap_dev 0xA, Normal VGA
Linuxカーネルのイメージから圧縮されていないカーネルを抽出するため、extract-vmlinuxスクリプトをダウンロードする。
wget -O extract-vmlinux https://raw.githubusercontent.com/torvalds/linux/master/scripts/extract-vmlinux chmod u+x extract-vmlinux
Linuxカーネルのイメージから圧縮されていないカーネルを抽出する。
./extract-vmlinux /boot/vmlinuz-$(uname -r) > vmlinuz
展開したvmlinuzファイルの種類が、ELFオブジェクトかどうかを確認する。
file vmlinuz # 出力例 vmlinuz: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=915f2e0498b5123d9c51edb9ffca1b68d958fb7f, stripped
objdump
コマンドを使用して、vmlinuzを逆アセンブルすることができる。
objdump -D vmlinuz | less