カーネル/アップグレード
この記事では、より新しいバージョンの Linux カーネルにアップグレードする手順について説明します。
新しいソースから新しいカーネルを作成する作業は、システムをインストールするときにカーネルを作成したときと基本的には同じ流れです。唯一異なる点は、make menuconfig などを使ってすべてのカーネルオプションを再度設定し直す代わりに、新しいカーネルでの変更点に応じて古いカーネルのコンフィグを微修正することで、時間を節約できるという点です。
新しいカーネルは、古いカーネルにはないオプションや機能を備えていることや、古いカーネルにあったオプションや機能がなくなっていることがあります。したがって、新しいカーネルのコンフィグファイルには、古いカーネルのコンフィグファイルには無い新しいエントリがあったり、古いカーネルのコンフィグファイルにあったエントリがなくなっていたりすることがあります。
この記事は、古いカーネルのコンフィグファイルを新しいカーネルで使えるコンフィグに変換することにより、こうしたコンフィグファイルの変更に対応する方法に関するガイドです。
Gentoo でのカーネルアップグレードは以下のステップが必要です:
- 新しいカーネルソースをインストールする。
- カーネルソースへのシンボリックリンクを (新しくインストールされたものを指すように) 設定する。
- 新しいカーネルのフォルダへ移動する。
- 新しいカーネルのコンフィグで導入または削除されたオプションに対応するために、.config ファイルを修正する。
- カーネルと initramfs をコンパイルする。
- ブートローダを更新する。
- 古いカーネルを削除するか、残す。
以前のコンフィギュレーションが失われないように、カーネルコンフィギュレーションのバックアップを取っておくのが賢明です。多くのユーザはシステムにとって最適なコンフィギュレーションを探すのにそれなりの時間を費やすもので、その情報を失いたいはずがありません。この記事の以前のカーネル設定をコピーするの部分は、コンフィギュレーションファイルのバックアップを作成するために活用することができます。
新しいカーネルソースを emerge する
新しいカーネルのソースがインストールされたときは、カーネルを更新するといいかもしれません。新しいカーネルのソースは、次のコマンドでシステムを更新するときにインストールされることがあります。
root #
emerge --ask --update --deep --with-bdeps=y --newuse @world
勿論、次のコマンドを使って直接インストールすることが可能です("gentoo-sources"を現在使用しているカーネルのパッケージに変えてください):
root #
emerge --ask --update --deep --with-bdeps=y --newuse sys-kernel/gentoo-sources
新しいカーネルのソースをインストールしても、新しいカーネルが提供されるわけではありません。新しいソースから新しいカーネルをビルドして、インストールして、実際に新しいカーネルを稼働させるためにシステムを再起動する必要があります。
新しいカーネルソースへのシンボリックリンクを設定する
カーネルコンフィグは、カーネルソースを格納しているディレクトリの中の .config という名前のファイルに保存されています。このディレクトリを指すシンボリックリンクがあります。
/usr/src/linux のシンボリックリンクは常に、現在使用中のカーネルソースが入っているディレクトリへ張られるべきです。このシンボリックリンクを張るのは、以下の3つの方法のいずれかで可能です。
- デフォルト: eselect でリンクを設定する。
- 代替案 1: 手動でシンボリックリンクを更新する。
- 代替案 2:
USE="symlink"
を設定してカーネルソースをインストールする。
デフォルト: eselect でリンクを設定する
eselectによるシンボリックリンクの設定
user $
eselect kernel list
Available kernel symlink targets: [1] linux-3.14.14-gentoo * [2] linux-3.16.3-gentoo
利用可能なカーネルソースが出力されており、*が現在使われているソースを表しています。
カーネルソースを2番に変えるには次のようにします :
root #
eselect kernel set 2
代替案 1: 手動でシンボリックリンクを更新する
シンボリックリンクを手動で設定するならば、次のコマンドを実行してください:
root #
ln -sf /usr/src/linux-3.16.3-gentoo /usr/src/linux
user $
ls -l /usr/src/linux
lrwxrwxrwx 1 root root 19 Oct 4 10:21 /usr/src/linux -> linux-3.16.3-gentoo
代替案 2: symlink USE フラグを設定してカーネルソースをインストールする
これによって/usr/src/linuxのリンク先が、新しくインストールされるカーネルソースになります。
必要であれば、他の 2 個の方法のいずれかを使って、後から変更できます。
新しいカーネルフォルダへ移動する
シンボリックリンクが更新されたので、作業ディレクトリを新しいカーネルのフォルダに移動しましょう。
user $
cd /usr/src/linux
このコマンドはもしシンボリックリンクが変更された時、作業ディレクトリが既に/usr/src/linuxであっても必要です。新しいシンボリックリンクに実際に従うまでは、コンソールは"古い"カーネルのディレクトリに居続けます。
新しいカーネル用に .config ファイルを修正する
以前のカーネル設定をコピーする
古いカーネルの設定ファイルを新しいカーネルのフォルダに移動させなければなりません。古い設定ファイルはいくつかの場所にあります:
- procfs ファイルシステムの場合、カーネルのオプション Enable access to .config through /proc/config.gz (CONFIG_IKCONFIG_PROC) が前のカーネルで有効になっている場合:
root #
zcat /proc/config.gz > /usr/src/linux/.config
- 古いカーネルから。これは古いカーネルが CONFIG_IKCONFIG を有効にしてコンパイルされている場合のみ有効です:
root #
/usr/src/linux/scripts/extract-ikconfig /path/to/old/kernel >/usr/src/linux/.config
- 設定が /boot にインストールされている場合:
root #
cp /boot/config-3.14.14-gentoo /usr/src/linux/.config
- 現在使用されているカーネルのディレクトリの中:
root #
cp /usr/src/linux-3.14.14-gentoo/.config /usr/src/linux/
- もし /etc/genkernel.conf 内で
SAVE_CONFIG="yes"
と設定され、過去に genkernel を使用していた場合、/etc/kernels/ ディレクトリの中:
root #
cp /etc/kernels/kernel-config-x86_64-3.14.14-gentoo /usr/src/linux/.config
.config ファイルを更新する
genkernel を利用する場合、/etc/genkernel.conf 内でOLDCONFIG および MENUCONFIG パラメータを有効化することで、ビルドプロセス中に自動的に make oldconfig および make menuconfig を行うことができます。genkernel の設定で OLDCONFIG が有効化されているか、genkernel コマンドに --oldconfig オプションを渡すことで有効化しようとしている場合は、この記事のビルドの節へ進んでください。
通常、新しいカーネルは新しいカーネルの機能をサポートするために、新しい .config ファイルを必要とします。古いカーネルの .config は、新しいカーネルで使用するために変換することができます。変換を行う方法は複数あり、そのうちひとつは make oldconfig または make olddefconfig を実行することです。
make oldconfig
make syncconfig は内部の実装詳細となりました; 可能な限りmake oldconfig を使用すべきです。make silentoldconfig ターゲットは Linux カーネル 4.19 以降では削除されています。
次の設定は、make config を利用したテキストベースの設定に似ています。新しい設定オプションについては、ユーザに決定を求めます。例えば:
root #
cd /usr/src/linux
root #
make oldconfig
Anticipatory I/O scheduler (IOSCHED_AS) [Y/n/m/?] (NEW)
最後の(NEW)は、このオプションが新しいオプションであることを示しています。左の角括弧内の文字は選択可能な設定です:Yes、no、module,あるいは?を入力してヘルプを表示します。推奨される(すなわちデフォルトの)設定は大文字で表示されます(ここではY)。ヘルプではオプションやドライバの説明がされます。
残念ながら、make oldconfig はそれぞれのオプションに対して例えば背景など、よりたくさんの情報を示してくれません。従って正しい選択をすることが難しい場合がたまにあります。この場合、オプションの名前を覚えておいて、グラフィカルなカーネル設定ツールを使用してあとで直す方法が最も良いです。新しいオプションを一覧表示して、それらについて調べるためには、make oldconfig を実行する前に make listnewconfig を使うことができます。
make olddefconfig
make olddefconfig を実行すると、古い .config からのオプションをすべて引き継ぎ、新しいオプションは推奨の (デフォルトの) 値に設定します:
root #
cd /usr/src/linux
root #
make olddefconfig
make help
他の利用可能な変換方法を見るには、make helpを実行してください:
user $
make help
差分を確認する
どのオプションが追加されたのか確認するために、新旧の .config ファイルを比較するのには、diff ツールを使うことができます:
user $
comm -2 -3 <(sort .config) <(sort .config.old)
# CONFIG_BATTERY_RT5033 is not set # Compiler: gcc (Gentoo 12.2.1_p20230428-r1 p2) 12.2.1 20230428 # Linux/x86 4.19.284-gentoo Kernel Configuration CONFIG_ARCH_USE_MEMREMAP_PROT=y CONFIG_GCC_VERSION=120201 CONFIG_GENTOO_PRINT_FIRMWARE_INFO=y CONFIG_INET_TABLE_PERTURB_ORDER=16 CONFIG_PLUGIN_HOSTCC="" CONFIG_RANDOM_TRUST_BOOTLOADER=y CONFIG_UNIX_SCM=y CONFIG_USER_NS=y
そして、どれが削除されたのかも:
user $
comm -1 -3 <(sort .config) <(sort .config.old)
# CONFIG_GCC_PLUGINS is not set # CONFIG_NVM is not set # CONFIG_RANDOM_TRUST_CPU is not set # CONFIG_USER_NS is not set # Compiler: gcc (Gentoo 10.2.0-r5 p6) 10.2.0 # Linux/x86 4.19.184-gentoo Kernel Configuration CONFIG_GCC_VERSION=100200 CONFIG_PLUGIN_HOSTCC="g++"
また、2 つのコンフィグファイルを、例えオプションがファイル内で移動されていた場合でも、いい感じに比較するスクリプトがカーネルによって提供されています:
user $
/usr/src/linux/scripts/diffconfig .config.old .config
その後、必要であれば、以下を実行することでオプションを精査して変更することができます:
root #
make menuconfig
menuconfig ターゲットはカーネルシンボル依存関係の解決を安全に処理してくれるため、便利です。
ビルド
手動ビルドとインストール
上の節の記述に従って新しいカーネルを設定した後、もし外部カーネルモジュール (例えば nvidia や zfs) がインストールされているならば、新しいカーネルをビルドする前にモジュールを準備して、新しくビルドされたカーネルとともに再ビルドする必要があるかもしれません:
root #
make modules_prepare
root #
make
root #
emerge --ask @module-rebuild
マルチスレッドシステムでは、
make
とともに -jN
オプションを使用する (ここで N
は並列ジョブ数です) ことでコンパイルプロセスを高速化することができます。例えば、4 個の論理コアを持つシステムでは make -j5
としてください。カーネルとモジュールの両方がビルドできたら、次はそれらをインストールすべきです:
root #
make modules_install
root #
make install
最後に、下で説明するように、新しいカーネルファイル名を使ってブートローダを再構成しなくてはなりません。initramfs を使用している場合はこれも再ビルドしなくてはなりません。
自動ビルドとインストール
Portageフックで新しくemergeされたカーネルを自動でビルド、インストールすることが可能です。他の方法も可能ですが、以下ではgenkernelとgentoo-sourcesパッケージをベースとしています。以下の条件を満たす必要があります:
- genkernel all によって、/usr/src/linux シンボリックが指す先にあるカーネルをビルドでき、
$BOOTDIR
にインストールでき、ブートローダを設定できること。 - カーネル ebuild に対して
symlink
use フラグが設定されていること。
これらが満たされていれば、以下に示す post_pkg_postinst
Portage フックをインストールするだけです。これは genkernel を --no-module-rebuild
付きで呼び出すことに注意してください。これは、module-rebuild を使用すると emerge の中で emerge が実行されるので、ロックファイルの待ちでデッドロックを発生させてしまうからです。カーネルアップグレードを含む更新の後には、emerge @module-rebuild
を忘れずに実行してください。
post_pkg_postinst() {
# Eselect the new kernel or genkernel will build the current one
eselect kernel set linux-"${KV}"
CURRENT_KV=$(uname -r)
# Check if genkernel has been run previously for the running kernel and use that config
if [[ -f "${EROOT}/etc/kernels/kernel-config-${CURRENT_KV}" ]] ; then
genkernel --no-module-rebuild --kernel-config="${EROOT}/etc/kernels/kernel-config-${CURRENT_KV}" all
# Use latest kernel config from current kernel
elif [[ -f "${EROOT}/usr/src/linux-${CURRENT_KV}/.config" ]] ; then
genkernel --no-module-rebuild --kernel-config="${EROOT}/usr/src/linux-${CURRENT_KV}/.config" all
# Use known running good kernel
elif [[ -f /proc/config.gz ]] ; then
zcat /proc/config.gz >> "${EROOT}/tmp/genkernel.config"
genkernel --no-module-rebuild --kernel-config="${EROOT}/tmp/genkernel.config" all
rm "${EROOT}/tmp/genkernel.config"
# No valid configs known, compile a clean one
else
genkernel --no-module-rebuild all
fi
}
ビルドの問題の解決
もし、現在のカーネルの再ビルド中に問題が発生したのであれば、カーネルソースをきれいにすることが役に立つかもしれません。初めに.configファイルのバックアップを取ることを忘れないでください。以下のコマンドはこのファイルを削除するからです。.bakや~をファイル名の後ろにつけないでください。make distcleanはこれらの拡張子や接尾辞を持つファイルも削除するからです。
root #
cp .config /usr/src/kernel_config_bk
root #
make distclean
root #
mv /usr/src/kernel_config_bk .config
ブートローダを更新する
アップグレードされた、インストールされたカーネルは、ブートローダに登録するか、UEFI ファームウェアに直接登録する必要があります。Kernel/Configuration を参照してください。GRUB を利用している場合は下記の方法を使用してください。他のブートローダを利用している場合はハンドブックを確認してください。
/boot パーティションがマウントされていることを確認してください。
grub-mkconfig を使う
GRUB の設定ファイルを更新するために、次のコマンドを実行することができます:
root #
grub-mkconfig -o /boot/grub/grub.cfg
(カーネルとは別で) GRUB 自体がアップグレードされた場合、例えば world 集合のアップグレードの一部としてアップグレードされた場合は、GRUB を再インストールする必要があり、そうしないとブートできなくなるかもしれません。詳細については GRUB#GRUB ブートローダのインストールを参照してください。
sys-kernel/installkernel の grub USE フラグを有効化することで、新しいカーネルがインストールされるたびに grub-mkconfig が自動で再生成されるでしょう。
systemd-boot
新しいカーネルがインストールされたときに、そのカーネルのための systemd-boot 設定ファイルは自動的に生成されます。手動での操作は必要ありません。
古いカーネルを削除する
カーネルの削除の記事を参照してください。
関連項目
- Genkernel — カーネルと initramfs を自動的にビルドすることができる Gentoo 謹製のツールです。
- Dracut — an initramfs infrastructure and aims to have as little as possible hard-coded into the initramfs.
- Kernel/Configuration — Linux カーネル の設定とセットアップを手作業で行う方法
- GRUB を新しいカーネル用にアップデートする