内核/升级

From Gentoo Wiki
< Kernel
Jump to: navigation, search
This page is a translated version of the page Kernel/Upgrade and the translation is 100% complete.

Other languages:
Deutsch • ‎English • ‎Nederlands • ‎español • ‎français • ‎italiano • ‎português do Brasil • ‎русский • ‎中文(中国大陆)‎ • ‎日本語 • ‎한국어

这篇文章描述了升级到新版本内核的步骤。

安装

当安装新的内核源代码后,升级您的内核或许是一个很棒的主意。当您运行以下命令时,新的内核源代码有时会随着系统的更新而安装。

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

安装新的内核源代码并不会给使用者提供一个新的内核。从新内核源代码编译和安装一个新的内核,然后重启系统从而真正的运行新的内核是有必要的。

从新的源代码制作一个新的内核基本上和安装系统时的制作内核是一样的。不同之处在于可以基于旧内核的配置文件来为新内核制作一个配置文件。使用旧的配置文件可以让使用者不从头到尾再做一次内核选项(像 make menuconfig 一样)。

内核的配置文件 .config 保存在内核源代码的目录下面。一个新的内核或许会有旧内核没有的特性或选项,新内核也有可能没有现存于旧内核的特性或选项。内核配置文件指定了是否开启内核的功能和选项,要么嵌入内核,要么以模块形式构建从而允许在内核运行时被按需加载。因此,新内核的配置文件可能有新的但是旧内核的配置文件没有的选项,同时新内核的配置文件可能没有旧内核的配置文件现有的选项。

要处理配置文件的更改,旧内核的配置文件需要转换为可用于新内核的配置。本文展示了如何通过转换旧内核的配置文件来制作一个新内核。

为当前运行内核的配置文件制作一个备份

备份内核配置是明智的,这样以前的配置就不会丢失了。毕竟许多用户花了大量的时间来配置出系统的最佳配置,同时失去内核配置是绝对不会想要的。

制作一个当前内核配置的备份很容易:

root #cp /usr/src/linux/.config ~/kernel-config-`uname -r`

在内核源代码的链接被配置正确的情况下,这复制了正在使用的内核的配置文件到了根用户的家目录下,重命名了配置文件变成 kernel-config- 加上现在正在运行的内核的版本号。

配置

设置一个链接到新的内核源代码

符号链接 /usr/src/linux 应该始终指向正在运行的内核的源代码的目录。下面三种方法中任意一个可以实现这一点:

  1. 安装内核源代码时使用 USE="symlink"
  2. 用 eselect 设置链接
  3. 手动更新符号链接

安装使用 USE Flag 的内核源代码

这将会让 /usr/src/linux 指向新安装的内核源代码。

如果有必要的话,也可以选择下面两种方法之一来进行稍后修改。

使用 eselect 设置链接

eselect 设置链接:

root #eselect kernel list
Available kernel symlink targets:
[1] linux-3.14.14-gentoo * 
[2] linux-3.16.3-gentoo

这将输出可用的内核源代码。星号表示已经选择的来源。

要更改内核源,例如选第二个选项:

root #eselect kernel set 2

手动更新符号链接

手动设置符号链接:

root #ln -sf /usr/src/linux-3.16.3-gentoo /usr/src/linux
root #ls -l /usr/src/linux
lrwxrwxrwx 1 root root 19 Oct  4 10:21 /usr/src/linux -> linux-3.16.3-gentoo

移步到新目录

现在已修改符号链接,将工作目录更改为新的内核文件夹。

root #cd /usr/src/linux
附注
即使在修改符号链接时工作目录已经是/usr/src/linux,此命令仍然是必需的。在实际遵循新的符号链接之前,控制台仍将位于内核的目录中。

复制以前的内核配置文件

旧内核的配置需要被复制到新的内核中。除了在先前步骤中保存到/root的备份副本之外,还可以在多个位置找到旧配置:

  • 如果在当前内核中选项Enable access to .config through /proc/config.gz(CONFIG_IKCONFIG_PROC)是激活的,配置文件在procfs 文件系统:
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/
  • In the /etc/kernels/ directory, if SAVE_CONFIG="yes" is set in /etc/genkernel.conf and genkernel was previously used:
root #cp /etc/kernels/kernel-config-x86_64-3.14.14-gentoo /usr/src/linux/.config

.config文件

要使用适用于新内核的旧内核的配置,需要转换旧内核的配置。转换可以通过运行 make silentoldconfig 或者 make olddefconfig。只用其中一个,不要都使用。

make silentoldconfig

重要
make silentoldconfig从linux 4.19版本开始被删除,它将被make syncconfig取代。

下面的配置是基于类似文本的配置 make config 。 对于新的配置,它提供选择。例如:

root #cd /usr/src/linux
root #make silentoldconfig
Anticipatory I/O scheduler (IOSCHED_AS) [Y/n/m/?] (NEW)

字符串“(NEW)”在该行结束时标记该选项是新的。左边的方括号中的字符串是可能的答案:“Y”是,“N”不是,“m”模块,或者“?”显示帮助。推荐(或者说是默认)答案是大写(“Y”)。帮助说明解释了选项或驱动程序。

可惜 make silentoldconfig 不会在每一个选项显示太多的信息,例如上下文,因此有时候做出正确的选择比较困难。这种情况下最好的办法就是记住选项的名字,之后通过 graphical kernel configuration tools 重新修正。

制作旧的配置 (make olddefconfig)

如果所有的新配置选项都应该被设置成推荐 (也就是default)值就用这条命令 make olddefconfig:

root #cd /usr/src/linux
root #make olddefconfig

make help

使用 make help 查看其他可用的转换方法:

root #make help

编译

重要
当外部内核模块安装 (如 NVIDIA 或 ZFS),在制作内核前可能需要运行 make modules_prepare ,它被描述在 这里 。一些模块在内核构建之前不能被安装或准备好。
重要
别忘了重新配置 bootloader 去登记新内核的名称。如果使用了initramfs,请重新制作initramfs

这一步请参考 manual configuration

自动构建和安装

可以使用Portage钩子自动构建和安装新出现的内核。虽然其他方法也是可行的,但以下内容基于genkernel和gentoo-sources包。它需要以下先决条件:

  1. genkernel all能够构建和安装内核到/usr/src/linux符号链接指向的$BOOTDIR和引导程序。
  2. 为内核ebuild设置了symlink use标志。

如果满足这些要求,只需安装post_pkg_postinst Portage钩子,如下所示。

FILE /etc/portage/env/sys-kernel/gentoo-sourcesAutomated kernel build and installation portage hook
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步骤,因为此功能是作为标准过程的一部分完成的。

任何外部的内核模块,像 binary kernel modules, 需要为新的内核重新编译。如果新内核还没有编译,需要首先为编译外部内核模块做准备:

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

移除

参考 移除旧的内核

另请参阅

外部资源