Linux内核升级指南

升级Linux内核是一个有一定风险的操作,不过如果操作系统的内核太老了,也可能导致部分新的应用程序无法运行,此外升级内核也可能能够提升一些性能等。

下面将以Debian发行版为例,讲解两种 升级内核的方法,即使用包管理器和手动编译,大家根据情况选择其一即可。

1,基于包管理器升级

使用包管理器升级内核是推荐的方法,我们可以通过下列命令搜索查看可安装的内核版本:

bash 复制代码
apt list | grep linux-image

结果如下:

可见内核软件包的命名规则为:

arduino 复制代码
linux-image-版本号-类型-架构

有的内核软件包没有"类型"这一部分例如linux-image-6.1.0-11-amd64,说明是通用的内核,我们一般安装这种即可,对于有类型部分的包名,类型通常如下:

  • rt 对实时性应用程序优化的内核,提供更快的响应时间
  • lowlatency 针对低延迟应用程序优化的内核
  • cloud 适用于云计算的内核
  • server 适用于服务器的内核
  • generic 等同于没有类型的内核,即通用内核

事实上,不同类型内核一般是配置不同,实质是一样的。

此外,往下翻我们还能发现版本号带有+bpo字样的内核包:

通常遵循下列命名方式:

arduino 复制代码
linux-image-版本号+bpo-类型-架构

这种内核通常更新,但是稳定性可能不佳,来自于backports软件源。

知道了软件包及其版本,我们直接使用apt安装就可以完成内核升级工作,例如:

bash 复制代码
sudo apt install linux-image-6.1.0-31-rt-amd64
sudo apt autopurge
sudo apt clean

重启系统,在grub引导界面选择新安装的内核版本的选项即可:

启动后执行uname -r命令可查看内核版本,确定是否更新成功。

带有dbg等其它后缀的软件包通常是包含调试符号、用于内核驱动开发的内核,这里我们先不关注。

2,源码编译安装

大多数情况下,不建议使用源码编译安装的方式升级内核,因为官方的内核通常比较新,我们现有的发行版不一定适配得很好,且绝大多数闭源驱动(例如NVIDIA、AMD显卡驱动)很可能会与最新内核不兼容,导致内核安装失败。

不过,如果你有一些定制化的需求,比如需要自定义内核编译配置等,或者单纯需要更加新的内核,则可以进行源码编译安装的方式。

(1) 下载源码包

进入Linux内核源码官方网站:传送门

选择stable或者longterm版本,点击对应版本右侧的tarball链接下载:

例如下载后得到linux-6.13.3.tar.xz文件,进行解压,解压后将得到linux-6.13.3文件夹,进入源码文件夹:

bash 复制代码
tar -xvf linux-6.13.3.tar.xz
cd linux-6.13.3

内核目录中文件如下:

(2) 安装依赖

编译内核需要安装一些基本依赖工具,执行下列命令:

bash 复制代码
sudo apt install flex bison bc build-essential libssl-dev libelf-dev libncurses-dev

(3) 配置内核

如果你只是单纯的升级内核,我们可以将现有的内核配置复制过来,保持当前配置即可:

bash 复制代码
cp /boot/config-$(uname -r) .config
yes '' | make oldconfig

反之,如果你对内核配置比较熟悉,且需要自定义一些配置,则可以执行下列命令进入配置界面:

bash 复制代码
make menuconfig

或者,也可以使用下列命令生成一个通用默认配置:

bash 复制代码
make defconfig

最终,出现configuration written to .config说明已完成配置:

(4) 编译安装

有两种编译安装的方式:

  • 直接编译源码并安装至系统
  • 编译源码并打包为deb安装包,然后使用包管理器安装

这里将分别介绍这两种方式,大家根据喜好选其一即可。

① 直接编译安装

在源码目录中,执行下列命令完成编译安装:

bash 复制代码
# 编译源码
make -j$(nproc)
# 安装内核模块
sudo make modules_install
# 安装内核
sudo make install

make-j参数表示指定多线程编译,nproc命令是用于输出当前处理器核心数的,这里指定给了-j,也可以指定为固定线程数例如-j8表示使用8线程编译。

编译内核通常耗费的时间很长,以R5 7600X处理器为例,使用12线程编译完成大概需要35分钟左右。

如果编译失败或者中断,想要重新编译,则执行下列命令清理已编译结果:

bash 复制代码
make mrproper

清理完成后,需要重新配置内核,再进行编译步骤。

② 编译打包为deb再安装

内核源码也支持一键打包为deb包,然后使用包管理器安装,这种方式比较推荐,因为后续我们可以统一使用包管理器管理多个版本内核。

要打包为deb,我们还需要安装一些额外工具,执行下列命令:

bash 复制代码
sudo apt install git rsync debhelper

然后在内核源码目录下,我们需要先创建一个git仓库,否则无法进行后续打包工作:

bash 复制代码
git init
git add .
git commit -m "message"

提交信息可以随意编写,若commit失败则可能是没有配置提交人信息导致,执行下列命令:

bash 复制代码
# 配置提交人信息
git config --global user.name "username"
git config --global user.email "example@example.com"

然后就可以开始编译构建工作了:

bash 复制代码
make deb-pkg -j$(nproc) LOCALVERSION=''

这里使用deb-pkg表示编译构建为安装包,此外还设定了变量LOCALVERSION,该变量用于设定编译后内核版本号后缀,例如你设定LOCALVERSION=-custom,那么编译后得到的内核版本号就是6.13.3-custom,由于默认情况下构建deb安装包时,版本号会有一个后缀+,因此这里出于"强迫症"就设定版本号后缀为空字符串''了,确保版本号是干净的。

编译完成后,deb安装包会生成在上一级目录下,通过下列命令查看:

bash 复制代码
ls ../ | grep '.deb$'

结果如下:

可见有4个安装包,它们分别是:

  • linux-image-6.13.3_xxx_amd64.deb 内核镜像包,包含了编译好的内核和内核模块,这个包就是我们要安装的实际内核
  • linux-headers-6.13.3_xxx_amd64.deb 内核头文件包,包含了编译内核模块所需的头文件,开发者在编写或编译内核模块时需要这个包
  • linux-image-6.13.3-dbg_xxx_amd64.deb 内核调试信息包,包含了调试内核所需的符号和调试信息
  • linux-libc-dev_xxx_amd64.deb 内核C库开发包,提供了用户空间程序在与内核交互时所需的头文件和库函数

一般来说,我们只需要安装linux-image-6.13.3_xxx_amd64.deb内核镜像即可,使用dpkg -i进行安装:

bash 复制代码
sudo dpkg -i linux-image-6.13.3_6.13.3-g6e078ce39376-1_amd64.deb

如果需要安装或者编译驱动,则通常还需要安装linux-headers-6.13.3_xxx_amd64.deb这个内核头文件包。

到此,内核升级完成,重启系统并执行命令uname -r即可查看当前内核版本:

3,移除不要的内核

如果安装了很多内核,通常可以移除一部分,不过建议除了最新的内核之外,还是保留一个稳定版本的内核,防止启动失败。

(1) 包管理器安装的内核移除

对于包管理器安装的内核,我们直接卸载即可,执行下列命令查看我们安装了哪些版本的内核:

bash 复制代码
# 列出已安装内核镜像
apt list --installed | grep linux-image

# 此外,还可以列出已安装的内核头文件包
apt list --installed | grep linux-headers

结果:

使用sudo apt purge卸载你需要移除的内核即可。

(2) 手动安装的内核移除

如果说是使用make install手动安装的内核,那么就稍微麻烦一点了,因为手动安装的内核是不会显示在apt list里面的,就要手动删除。

我们可以先来了解一下内核相关文件存放位置,在手动安装时,内核文件安装在下列位置:

  • /boot目录下:存放的是内核镜像等和启动相关内核文件,执行make install时会将相关文件安装到该目录下
  • /lib/modules目录下:内核模块,通常是驱动以及其它系统相关模块,执行make modules_install时会将相关文件安装到该目录下

首先查看/boot目录如下:

可见一个版本的内核对应了多个相关文件,以6.13.3版本为例:

  • config-6.13.3 内核编译时的配置文件,它包含了在编译过程中使用的各种选项和参数设置
  • initrd.img-6.13.3 initrd(initial RAM disk)是一个临时磁盘镜像,它包含了必要的驱动程序和工具,用于在系统启动过程中挂载真正的根文件系统
  • System.map-6.13.3 存放了编译内核时定义的内核函数和它们的内存地址之间的关系表
  • vmlinuz-6.13.3 经过编译的内核的可执行映像文件,在Linux系统启动过程中,这个文件会被加载到内存中并由内核第一阶段程序解压和运行

删除对应版本的内核文件即可,例如:

bash 复制代码
# 删除6.12.9+bpo-rt-amd64版本内核文件
sudo rm /boot/config-6.12.9+bpo-rt-amd64 /boot/initrd.img-6.12.9+bpo-rt-amd64 /boot/System.map-6.12.9+bpo-rt-amd64 /boot/vmlinuz-6.12.9+bpo-rt-amd64

然后查看/lib/modules目录:

可见一个内核版本对应的模块文件,都以一个文件夹形式存放在该目录下,删除对应版本即可,例如:

bash 复制代码
# 删除6.12.9+bpo-rt-amd64版本内核模块文件
sudo rm -rf /lib/modules/6.12.9+bpo-rt-amd64

此外,我们发现根目录下还有符号链接:

这些符号链接指向了当前实际使用的内核文件,但如果删除了其指向就不存在了,我们删除链接,然后重新创建:

bash 复制代码
# 删除链接
sudo rm /initrd.img /initrd.img.old /vmlinuz /vmlinuz.old

# 重新链接至新内核
sudo ln -s /boot/initrd.img-6.13.3 /initrd.img
sudo ln -s /boot/vmlinuz-6.13.3 /vmlinuz

最后重新生成镜像并更新GRUB引导即可:

bash 复制代码
sudo update-initramfs -u
sudo update-grub

到此,内核的升级以及旧版本清理工作完成,在实际情况下需要谨慎升级内核。

相关推荐
心月狐的流火号32 分钟前
计算机I/O模式演进与 Java NIO 直接内存
java·操作系统
绵绵细雨中的乡音1 小时前
网络基础知识
linux·网络
Peter·Pan爱编程1 小时前
Docker在Linux中安装与使用教程
linux·docker·eureka
kunge20132 小时前
Ubuntu22.04 安装virtualbox7.1
linux·virtualbox
清溪5492 小时前
DVWA中级
linux
Sadsvit3 小时前
源码编译安装LAMP架构并部署WordPress(CentOS 7)
linux·运维·服务器·架构·centos
xiaok3 小时前
为什么 lsof 显示多个 nginx 都在 “使用 443”?
linux
苦学编程的谢4 小时前
Linux
linux·运维·服务器
G_H_S_3_4 小时前
【网络运维】Linux 文本处理利器:sed 命令
linux·运维·网络·操作文本
Linux运维技术栈4 小时前
多系统 Node.js 环境自动化部署脚本:从 Ubuntu 到 CentOS,再到版本自由定制
linux·ubuntu·centos·node.js·自动化