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 "[email protected]"

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

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

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

相关推荐
大白的编程日记.1 小时前
【Linux学习笔记】基础IO之理解文件
linux·笔记·学习
东南门吹雪1 小时前
Debian系统上PostgreSQL15版本安装调试插件及DBeaver相应配置
linux·运维·postgresql·debian
Lzc7742 小时前
Linux的基础开发工具
linux·linux的基础开发工具
jarreyer4 小时前
Vim 编辑器常用快捷键速查表
linux·编辑器·vim
冰激凌zz4 小时前
ubuntu nobel + qt5.15.2 设置qss语法识别正确
linux·qt·ubuntu
编码雪人4 小时前
CentOS算法部署
linux·运维·centos
广药门徒4 小时前
关于多版本CUDA共存的研究,是否能一台机子装两个CUDA 版本并正常切换使用
linux·运维·人工智能
又逢乱世4 小时前
Ubuntu 安装 Docker
linux·ubuntu·docker
小猪佩奇TONY5 小时前
Linux 内核学习(6) --- Linux 内核基础知识
linux·学习
Ac157ol5 小时前
模拟内存管理
linux·服务器