カーネル/アップグレード
この記事は新しいバージョンの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 ファイルを更新する
Invoking make oldconfig and make menuconfig can be done automatically via genkernel in the build process by enabling the OLDCONFIG and MENUCONFIG parameters in /etc/genkernel.conf. If OLDCONFIG is enabled in genkernel's configuration or if it's going to be enabled by passing --oldconfig option to genkernel command, jump to the build section in this article.
通常、新しいカーネルは新しいカーネルの機能をサポートするために、新しい .config ファイルを必要とします。古いカーネルの .config は、新しいカーネルで使用するために変換することができます。変換を行う方法は複数あり、そのうちひとつは make oldconfig または make olddefconfig を実行することです。
make oldconfig
make syncconfig は内部の実装詳細となりました; 可能な限りmake oldconfig を使用すべきです。make silentoldconfig ターゲットは Linux カーネル 4.19 以降では削除されています。
The following configuration is like the text based configuration with make config. For new configuration options, the user is asked for a decision. For example:
user $
cd /usr/src/linux
root #
make oldconfig
Anticipatory I/O scheduler (IOSCHED_AS) [Y/n/m/?] (NEW)
最後の(NEW)は、このオプションが新しいオプションであることを示しています。左の角括弧内の文字は選択可能な設定です:Yes、no、module,あるいは?を入力してヘルプを表示します。推奨される(すなわちデフォルトの)設定は大文字で表示されます(ここではY)。ヘルプではオプションやドライバの説明がされます。
残念ながら、make silentoldconfigはそれぞれのオプションに対して例えば背景など、よりたくさんの情報を示してくれません。従って正しい選択をすることが難しい場合がたまにあります。この場合、オプションの名前を覚えておいて、グラフィカルなカーネル設定ツールを使用してあとで直す方法が最も良いです。
make olddefconfig
もし、すべての新しい設定オプションを推奨される(すなわちデフォルトの)値に設定する場合、make olddefconfigを使用してください。
user $
cd /usr/src/linux
root #
make olddefconfig
make help
他の利用可能な変換方法を見るには、make helpを実行してください:
user $
make help
差分を確認する
A diff tool can be used to compare the old and new .config files to see what options have been added:
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
And which have been removed:
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
Alternatively, the kernel provides a script to cleanly compare two config files even if the options have moved in the file itself:
user $
/usr/src/linux/scripts/diffconfig .config.old .config
The options can then be researched and changed if necessary by running:
root #
make menuconfig
The menuconfig target is helpful because it safely handles kernel symbol dependency resolution.
ビルド
もし外部カーネルモジュール(例えばnvidiaやzfs)がインストールされているならば、カーネルをビルドする前に 下で説明されているようにmake modules_prepareを実行することが必要かもしれません。一部のモジュールはカーネルがビルドされる前にインストールや準備をすることができません。
新しいカーネルのファイル名を参照させるためにブートローダーを再設定することを忘れないでください。そして、もしinitramfsを使用していた場合、こちらも同様に再設定することを忘れないでください。
このステップに関しては、ビルドのページに従ってください。
自動ビルドとインストール
Portageフックで新しくemergeされたカーネルを自動でビルド、インストールすることが可能です。他の方法も可能ですが、以下ではgenkernelとgentoo-sourcesパッケージをベースとしています。以下の条件を満たす必要があります:
- genkernel all is able to build and install the kernel to which the /usr/src/linux symlink points into
$BOOTDIR
and the bootloader. - The
symlink
use flag is set for the kernel ebuild.
If those are fulfilled, simply install a post_pkg_postinst
Portage hook as shown below.
/etc/portage/env/sys-kernel/gentoo-sources
自動でカーネルビルドとインストールをする portage フックpost_pkg_postinst() { CURRENT_KV=$(uname -r) # Check to see 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 elif [[ -f "${EROOT}/usr/src/linux-${CURRENT_KV}/.config" ]] ; then # Use latest kernel config from current kernel genkernel --kernel-config="${EROOT}/usr/src/linux-${CURRENT_KV}/.config" all elif [[ -f /proc/config.gz ]] ; then # Use known running good kernel zcat /proc/config.gz >> "${EROOT}/tmp/genkernel.config" genkernel --kernel-config="${EROOT}/tmp/genkernel.config" all rm "${EROOT}/tmp/genkernel.config" else # No valid configs known 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
ブートローダを更新する
The upgraded and built kernel needs to be set up and eventually a bootloader or boot item updated, see Kernel/Configuration#Setup. Users of Grub can use the method below, users of other bootloaders must consult the handbook.
After making sure /boot partition is mounted,
grub-mkconfig を使う
The following command can be executed for updating grub's configuration file:
root #
grub-mkconfig -o /boot/grub/grub.cfg
Using systemd-boot-gen to update systemd-boot UEFI configuration
Installing from the cargo, the Rust package manager, should be done at one's own risk. The Gentoo project cannot what is built from it and could contain security risks particularly at the bootloader level. This could mean installing a rootkit if compromised. Proceed with the following section with caution.
Manual installation of systemd-boot-gen:
user $
cargo install systemd-boot-gen
Copy the kernel parameters to /etc/default/cmdline, the file should contain:
/etc/default/cmdline
CMDLINE="<kernel command line parameters>"
And run it using root privileges:
user $
sudo ~/.cargo/bin/systemd-boot-gen
This will generate the boot configuration in /boot/loader/entries/ for all the available /boot/vmlinuz-* that have a matching /boot/initramfs-*.
古いカーネルを残すか削除する
古いカーネルソースを残す
Kernel sources will eventually become unsupported. Some packages require the current sources to build. To protect the new sources from being removed by a depclean, it can be added to the world file (/var/lib/portage/world) by:
root #
emerge --noreplace sys-kernel/gentoo-sources:ここに.新しいソースの.バージョン
Old sources that are no longer supported can be removed from the world file by:
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 を新しいカーネル用にアップデートする