カーネル/アップグレード
この記事は新しいバージョンのLinuxカーネルにアップグレードすることについて説明しています。
新しいソースから新しいカーネルを作成する作業は、システムをインストールするときにカーネルを作成したときと基本的には同じ流れです。唯一異なる点は、make menuconfig などを使ってすべてのカーネルオプションを再度設定し直す代わりに、新しいカーネルでの変更点に応じて古いカーネルのコンフィグを微修正することで、時間を節約できるという点です。
新しいカーネルは、古いカーネルにはないオプションや機能を備えていることや、古いカーネルにあったオプションや機能がなくなっていることがあります。したがって、新しいカーネルのコンフィグファイルには、古いカーネルのコンフィグファイルには無い新しいエントリがあったり、古いカーネルのコンフィグファイルにあったエントリがなくなっていたりすることがあります。
この記事は、古いカーネルのコンフィグファイルを新しいカーネルで使えるコンフィグに変換することにより、こうしたコンフィグファイルの変更に対応する方法に関するガイドです。
Gentoo でのカーネルアップグレードは以下のステップが必要です:
- ステップ 1: 新しいカーネルソースを emerge する。
- ステップ 2: 新しいカーネルソースへのシンボリックリンクを正しく設定する。
- ステップ 3: 新しいカーネルのフォルダへ移動する。
- ステップ 4: 新しいカーネルのコンフィグで導入または削除されたオプションに対応するために、.config ファイルを修正する。
- ステップ 5: カーネルと initramfs をビルドする。
- ステップ 6: ブートローダを更新する。
- ステップ 7: 古いカーネルを削除するか、残す。
以前のコンフィギュレーションが失われないように、カーネルコンフィギュレーションのバックアップを取っておくのが賢明です。多くのユーザはシステムにとって最適なコンフィギュレーションを探すのにそれなりの時間を費やすもので、その情報を失いたいはずがありません。この記事の以前のカーネル設定をコピーするの部分は、コンフィギュレーションファイルのバックアップを作成するために活用することができます。
新しいカーネルソースを 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 を利用したテキストベースの設定に似ています。新しい設定オプションについては、ユーザに決定を求めます。例えば:
user $
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 からのオプションをすべて引き継ぎ、新しいオプションは推奨の (デフォルトの) 値に設定します:
user $
cd /usr/src/linux
root #
make olddefconfig
make help
他の利用可能な変換方法を見るには、make helpを実行してください:
user $
make help
差分を確認する
どのオプションが追加されたのか確認するために、新旧の .config ファイルを比較するのには、diff ツールを使うことができます:
user $
diff <(sort .config) <(sort .config.old) | awk '/^<.*(=|Linux)/ { $1=""; print }'
CONFIG_64BIT_TIME=y CONFIG_AMD_NB=y CONFIG_ARCH_CLOCKSOURCE_INIT=y CONFIG_ARCH_HAS_GIGANTIC_PAGE=y CONFIG_ARCH_HAS_PTE_DEVMAP=y CONFIG_ARCH_HAS_SET_DIRECT_MAP=y CONFIG_ARCH_STACKWALK=y CONFIG_ARCH_USE_MEMREMAP_PROT=y CONFIG_BLK_PM=y CONFIG_CC_CAN_LINK=y CONFIG_CC_DISABLE_WARN_MAYBE_UNINITIALIZED=y CONFIG_CC_HAS_ASM_INLINE=y CONFIG_CC_HAS_KASAN_GENERIC=y CONFIG_CC_HAS_WARN_MAYBE_UNINITIALIZED=y CONFIG_CPU_SUP_AMD=y CONFIG_CPU_SUP_HYGON=y CONFIG_CPU_SUP_ZHAOXIN=y CONFIG_CRYPTO_LIB_AES=y CONFIG_CRYPTO_LIB_ARC4=y CONFIG_CRYPTO_LIB_DES=y CONFIG_CRYPTO_LIB_SHA256=y CONFIG_DEBUG_MISC=y CONFIG_DRM_I915_FORCE_PROBE="" CONFIG_DRM_I915_SPIN_REQUEST=5 CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND=250 CONFIG_DYNAMIC_EVENTS=y CONFIG_EFI_EARLYCON=y CONFIG_GCC_PLUGINS=y CONFIG_GENERIC_GETTIMEOFDAY=y CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y CONFIG_HAVE_ARCH_STACKLEAK=y CONFIG_HAVE_ASM_MODVERSIONS=y CONFIG_HAVE_EISA=y CONFIG_HAVE_FAST_GUP=y CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y CONFIG_HAVE_GENERIC_VDSO=y CONFIG_HAVE_MOVE_PMD=y CONFIG_HAVE_PCI=y CONFIG_INIT_STACK_NONE=y CONFIG_IO_URING=y CONFIG_KASAN_STACK=1 CONFIG_LEDS_TRIGGER_AUDIO=y CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" CONFIG_MMC_SDHCI_IO_ACCESSORS=y CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m CONFIG_NET_VENDOR_GOOGLE=y CONFIG_NET_VENDOR_MICROCHIP=y CONFIG_NET_VENDOR_PENSANDO=y CONFIG_NET_VENDOR_XILINX=y CONFIG_NF_NAT=m CONFIG_NF_NAT_MASQUERADE=y CONFIG_NVMEM_SYSFS=y CONFIG_OPTIMIZE_INLINING=y CONFIG_POWER_SUPPLY_HWMON=y CONFIG_PROC_PID_ARCH_STATUS=y CONFIG_SKB_EXTENSIONS=y CONFIG_SND_INTEL_NHLT=y CONFIG_UBSAN_ALIGNMENT=y CONFIG_UNIX_SCM=y CONFIG_USB_AUTOSUSPEND_DELAY=2 CONFIG_X86_ACPI_CPUFREQ_CPB=y CONFIG_X86_MCE_AMD=y # end of Gentoo Linux # Linux/x86 5.4.0-gentoo Kernel Configuration
そして、どれが削除されたのかも:
user $
diff <(sort .config) <(sort .config.old) | awk '/^>.*(=|Linux)/ { $1=""; print }'
CONFIG_ANON_INODES=y CONFIG_ARCH_DISCARD_MEMBLOCK=y CONFIG_ARCH_HAS_SG_CHAIN=y CONFIG_ARCH_HAS_ZONE_DEVICE=y CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y CONFIG_ARM_GIC_MAX_NR=1 CONFIG_AUDIT_TREE=y CONFIG_AUDIT_WATCH=y CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_CRYPTO_WORKQUEUE=y CONFIG_DEFAULT_CFQ=y CONFIG_DEFAULT_IO_DELAY_TYPE=0 CONFIG_DEFAULT_IOSCHED="cfq" CONFIG_DEFAULT_SECURITY="" CONFIG_DMA_DIRECT_OPS=y CONFIG_FB_BACKLIGHT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_HAVE_DEBUG_STACKOVERFLOW=y CONFIG_HAVE_GENERIC_GUP=y CONFIG_HAVE_MEMBLOCK=y CONFIG_IA32_AOUT=y CONFIG_INET6_XFRM_MODE_BEET=y CONFIG_INET6_XFRM_MODE_TRANSPORT=y CONFIG_INET6_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_IO_DELAY_TYPE_0X80=0 CONFIG_IO_DELAY_TYPE_0XED=1 CONFIG_IO_DELAY_TYPE_NONE=3 CONFIG_IO_DELAY_TYPE_UDELAY=2 CONFIG_IOSCHED_CFQ=y CONFIG_IOSCHED_NOOP=y CONFIG_MAY_USE_DEVLINK=y CONFIG_NO_BOOTMEM=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_X86_DEV_DMA_OPS=y # Linux/x86 4.19.86-gentoo Kernel Configuration
また、2 つのコンフィグファイルを、例えオプションがファイル内で移動されていた場合でも、いい感じに比較するスクリプトがカーネルによって提供されています:
user $
/usr/src/linux/scripts/diffconfig .config.old .config
その後、必要であれば、以下を実行することでオプションを精査して変更することができます:
root #
make menuconfig
menuconfig ターゲットはカーネルシンボル依存関係の解決を安全に処理してくれるため、便利です。
ビルド
もし外部カーネルモジュール(例えばnvidiaやzfs)がインストールされているならば、それらの外部モジュールをビルドする前に 下で説明されているようにmake modules_prepareを実行することが必要かもしれません。一部のモジュールはカーネルがビルドされる前にインストールや準備をすることができません。
新しいカーネルのファイル名を参照させるためにブートローダーを再設定することを忘れないでください。そして、もしinitramfsを使用していた場合、こちらも同様に再設定することを忘れないでください。
このステップに関しては、ビルドのページに従ってください。
自動ビルドとインストール
Portageフックで新しくemergeされたカーネルを自動でビルド、インストールすることが可能です。他の方法も可能ですが、以下ではgenkernelとgentoo-sourcesパッケージをベースとしています。以下の条件を満たす必要があります:
- genkernel all によって、/usr/src/linux シンボリックが指す先にあるカーネルをビルドでき、
$BOOTDIR
にインストールでき、ブートローダを設定できること。 - カーネル ebuild に対して
symlink
use フラグが設定されていること。
これらが満たされていれば、以下に示す post_pkg_postinst
Portage フックをインストールするだけです。
/etc/portage/env/sys-kernel/gentoo-sources
自動でカーネルビルドとインストールをする portage フックpost_pkg_postinst() { # Eselect the new kernel or genkernel will build the current one eselect kernel set linux-"${PV}"-gentoo 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 --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 --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 --kernel-config="${EROOT}/tmp/genkernel.config" all rm "${EROOT}/tmp/genkernel.config" # No valid configs known, compile a clean one else genkernel all fi }
外部のカーネルモジュールの再インストール
もしカーネル全体をビルドするのなら、modules_prepareは必要ありません。この機能は通常のプロセスの一部だからです。
例えばバイナリカーネルモジュールのようなすべての外部カーネルモジュールは、それぞれの新しいカーネルに対して再ビルドされる必要があります。もしまだカーネルをビルドしていないのならば、外部カーネルモジュールのビルドのためにカーネルを準備しなければなりません。
root #
make modules_prepare
カーネルモジュールを含むパッケージは@module-rebuild
をセットすることで再ビルドできます:
root #
emerge --ask @module-rebuild
ビルドの問題の解決
もし、現在のカーネルの再ビルド中に問題が発生したのであれば、カーネルソースをきれいにすることが役に立つかもしれません。初めに.configファイルのバックアップを取ることを忘れないでください。以下のコマンドはこのファイルを削除するからです。.bakや~をファイル名の後ろにつけないでください。make distcleanはこれらの拡張子や接尾辞を持つファイルも削除するからです。
root #
cp .config /usr/src/kernel_config_bk
root #
make distclean
root #
mv /usr/src/kernel_config_bk .config
ブートローダを更新する
アップグレードされた、ビルドされたカーネルは、最終的にブートローダまたはブートアイテムを更新してセットアップする必要があります。Kernel/Configuration/ja#セットアップを参照してください。Grub を利用している場合は下記の方法を使用してください。他のブートローダを利用している場合はハンドブックを確認してください。
/boot パーティションがマウントされていることを確認したら、
grub-mkconfig を使う
grub の設定ファイルを更新するために、次のコマンドを実行することができます:
root #
grub-mkconfig -o /boot/grub/grub.cfg
systemd-boot UEFI 設定を更新するために systemd-boot-gen を使う
Rust のパッケージマネージャである cargo からのインストールは、自己責任で行うべきです。Gentoo プロジェクトは、それから何がビルドされるのか、そして特にブートローダのレベルでどんなセキュリティリスクがあり得るのか、検証することができません。万一攻撃を受けていれば、ルートキットをインストールすることにもなりかねないということです。充分注意したうえでこの節の内容を進めてください。
systemd-boot-gen の手動インストール:
user $
cargo install systemd-boot-gen
カーネルパラメータを /etc/default/cmdline にコピーしてください。ファイルが次の内容を含むように:
/etc/default/cmdline
CMDLINE="<kernel command line parameters>"
そして、root 特権を使用して実行してください:
user $
sudo ~/.cargo/bin/systemd-boot-gen
これにより、対応する /boot/initramfs-* を持ち、利用可能なすべての /boot/vmlinuz-* について、/boot/loader/entries/ 内にブート設定が生成されるでしょう。
古いカーネルを残すか削除する
古いカーネルソースを残す
カーネルソースはいずれサポートされなくなるでしょう。パッケージによっては、ビルドするのに最新のソースを必要とすることがあります。depclean で削除されないように新しいソースを保護するには、次のようにして world ファイル (/var/lib/portage/world) に追加することができます:
root #
emerge --noreplace sys-kernel/gentoo-sources:ここに.新しいソースの.バージョン
もうサポートされなくなった古いソースは、次のようにして world ファイルから削除することができます:
root #
emerge --deselect sys-kernel/gentoo-sources:ここに.要らない.バージョン
古いカーネルを削除する
kernel removalを参照してください。
関連項目
- Genkernel — kernelとinitramfsを自動的にビルドすることができるGentoo製のツールです。
- Dracut — an initramfs infrastructure and aims to have as little as possible hard-coded into the initramfs.
- Kernel/Configuration — Linux カーネル の設定とセットアップを手作業で行う方法
- GRUB を新しいカーネル用にアップデートする