你是不是也遇到过这种场景:新买的NVMe固态插到老服务器上,系统死活认不出来;或者跑Docker的时候某个内核特性不支持,容器就是起不来;又或者明明做的是嵌入式Linux开发,板子上的外设驱动总是加载失败。我被这类问题折腾过不止一次,最后排查来排查去,答案往往只有一个:内核版本太老了。
Linux内核升级这件事,说大不大,说小不小。很多人一听“编译内核”就发怵,觉得那是Linus Torvalds那种级别的人干的事;也有人觉得升级内核就是把软件包升一下,结果升完重启直接进不了系统。这两种极端我都见过。其实内核升级是有固定套路和清晰逻辑的,关键是你得知道自己在做什么,以及每一步背后的原理是什么。
这篇文章我会把Linux内核升级的完整路径拆开讲清楚:从为什么要升级、升级前要准备什么,到包管理器升级、ELRepo仓库升级、源码编译升级三条主流路线,再到升级后的验证、回滚和那些最容易踩的坑。不管你是刚入门的运维、做嵌入式开发的工程师,还是自己折腾服务器的爱好者,照着操作基本都能搞定。
1. 先搞清楚为什么要动内核:升级的收益与代价
1.1 先看懂内核版本号再说
动手之前,先要学会看版本号。打开终端执行:
bash复制uname -r
比如输出是 5.15.0-91-generic,拆开看就是:
5是主版本号15是次版本号0是修订号-91-generic是Ubuntu等发行版自己打的补丁版本
版本号的演进逻辑很简单:主版本号不变的情况下,次版本号和修订号的提升意味着功能增加和bug修复。而不同的发行版还会在自己的内核里打上额外的补丁,所以即使内核版本号一样,Ubuntu的内核和CentOS的内核在细节上也有差异。
1.2 升级内核到底解决了什么问题
你把内核升级上去,最直接的收益是这几个方面:
新硬件支持。 内核里包含了大量设备驱动代码,新内核通常会加入对新CPU、新显卡、新网卡、新NVMe控制器的支持。我之前遇到的那块NVMe盘认不出来,就是内核版本太低,没有对应的NVMe HMB驱动。
安全漏洞修复。 这是最容易被忽视但也是最重要的一点。像Dirty Pipe这类提权漏洞,影响的是一大堆Linux机器,唯一的修复途径就是升级内核或者打补丁。长期不升级内核的系统,本质上就是把漏洞敞开着。
性能和调度优化。 新内核在进程调度、内存管理、文件系统层面的改进是持续的。比如针对高并发场景的调度器优化、针对SSD的I/O调度改进,这些不是你用yum update升个软件包能获得的。
容器和虚拟化支持。 Docker、Kubernetes对内核特性有明确要求,比如cgroup v2、overlayfs、iptables模块等。如果你的内核太老,很多东西要么跑不起来,要么性能很差。很多人在CentOS 7上装新版Docker失败,根子就在内核版本。
嵌入式场景的稳定性。 做嵌入式Linux开发的人更清楚,内核源码里的驱动和平台支持是跟着版本走的。新内核往往意味着更完善的外设驱动框架、更稳定的设备树支持,以及更好的实时性配置选项。
1.3 不升级会怎样
有人可能会说:我的服务器跑得好好的,为什么要升?这话有道理,但得分场景。
如果只是一台跑着旧应用的内部虚拟机,不直连新硬件、不接触外网、没有特殊的内核特性需求,那你确实可以不升。但如果你是跑生产环境的物理机,上面有数据库、有容器平台、有对外服务,那内核停留在老版本的风险就非常直接:出现安全漏洞没有修复手段,新硬件没法接入,数据库的内核参数调优选项缺失。真等到出问题再临阵升级,压力是翻倍的。
1.4 升级的真正代价是什么
升级内核不是零成本的,你必须清楚这几笔账:
- 驱动兼容性:现有机器上的硬件驱动,特别是显卡驱动、网卡驱动、存储阵列卡驱动,不一定能直接在全新内核上工作。
- 第三方内核模块:像NVIDIA驱动、VirtualBox虚拟机扩展、ZFS文件系统这类带内核模块的软件,几乎每次内核升级之后都需要重新编译模块,否则直接白屏起不来。
- 重启风险:内核升级后必须重启才能生效,而重启意味着业务中断。在不能接受重启的生产服务器上,升级内核本身就是一次需要走变更流程的动作。
所以我的建议是:升级内核前先想清楚你要解决什么问题,而不是为了“追新”而升级。内核不是越新越好,而是越适合你的场景越好。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 升级前必须做好的三件事:版本确认、备份与硬件梳理
2.1 确认当前系统环境和架构
升级之前先摸清家底,这是所有操作的前提。
bash复制# 查看当前内核版本
uname -r
# 查看操作系统发行版信息
cat /etc/os-release
# 查看系统架构
uname -m
这三个命令足以让你确认:你是什么发行版、什么版本,系统架构是x86_64还是aarch64,当前跑的内核是什么。后面的所有操作都要基于这些信息展开。
这里特别提醒一下:不要只看发行版版本号,内核版本和发行版版本是两回事。比如CentOS 7.9默认内核是3.10.0-1160,而Ubuntu 22.04默认内核是5.15.0。同样是Linux,内核版本差异非常悬殊。你判断“要不要升级内核”,不能只看发行版是不是新的。
2.2 备份:别拿生产环境开玩笑
很多新手升级内核栽跟头,就是因为少了备份这一步。升级内核涉及修改/boot分区、/lib/modules目录、GRUB引导配置,任何一个环节出错都可能导致系统无法启动。
我建议至少完成以下备份:
- 备份/boot目录:里面存放了内核镜像vmlinuz、initramfs和GRUB配置文件。把它拷贝一份到安全位置,出了问题还能手动恢复。
- 备份/etc/default/grub:GRUB的默认配置都在这个文件里,升级内核时可能被修改。
- 备份/lib/modules/当前版本:旧的模块目录保留一份,回滚时会用到。
- 如果是虚拟机,先做个快照:这是最省事的方案。快照之后随便折腾,翻车了直接回滚到快照点。
bash复制# 备份/boot目录
cp -a /boot /boot.bak.$(date +%Y%m%d)
# 备份GRUB配置
cp /etc/default/grub /etc/default/grub.bak.$(date +%Y%m%d)
2.3 梳理硬件驱动和第三方内核模块
升级内核之前,先搞清楚这台机器上有哪些“特殊”驱动。执行下面的命令看看:
bash复制# 查看当前加载的内核模块
lsmod
# 查看PCI设备
lspci -nnk
# 查看是否有DKMS管理的第三方模块
dkms status
重点关注三类情况:
- NVIDIA/AMD显卡驱动:这俩是最容易出问题的。NVIDIA驱动以内核模块形式存在,新内核如果没有对应版本的驱动,重启后大概率黑屏。
- VirtualBox / VMware虚拟机扩展:它们同样带内核模块,需要重新编译。
- ZFS、OpenZFS等文件系统模块:这些模块对内核版本非常敏感,版本不匹配直接挂载失败。
如果机器上有这些组件,升级前先去官网确认支持的内核版本范围,或者在升级后立即安装匹配的新版驱动。我自己的习惯是:先把新内核装好,但不重启,然后把第三方驱动模块全部重编一次,确认无误后再重启。
3. 最省事的路线:用包管理器升级内核
3.1 Ubuntu/Debian系:apt一行命令搞定
Debian系发行版的包管理机制做得比较完善,升级内核最直接的方式就是:
bash复制sudo apt update
sudo apt upgrade
这个命令会把你系统里所有软件包升级到当前发行版软件源里的最新版本,其中就包括内核。升级完成后,新内核会出现在GRUB菜单里,重启时选中新内核即可。
但这里有个需要说明的点:apt upgrade 默认只会升级到当前Ubuntu版本官方仓库里的最新内核。比如Ubuntu 22.04的官方仓库里,内核会随着HWE(Hardware Enablement)更新到更高版本,但不会一下子跳到最新的主线内核。换句话说,这种方式拿到的是一个“当前发行版支持的、经过充分测试的最内核版本”,而不是“世界上最内核的新版本”。
如果想启用HWE内核获取更新的内核,可以安装:
bash复制sudo apt install linux-generic-hwe-22.04
HWE内核是Ubuntu专为桌面和服务器提供的“硬件支持内核”,版本比默认内核更新,但仍在官方支持范围内。生产环境用这个比盲目追主线内核要稳得多。
3.2 Ubuntu安装主线内核的方法
如果你明确需要某个最新版本的内核,Ubuntu上可以手动下载主线内核包来安装。Ubuntu Kernel Team提供了mainline builds,下载对应的.deb文件后用dpkg安装即可。
具体做法是去Ubuntu主线内核页面找到你想要的版本,下载这些文件:
linux-headers-*.deblinux-image-*.deblinux-modules-*.deb
然后执行:
bash复制sudo dpkg -i linux-*.deb
安装完成后同样需要更新GRUB:
bash复制sudo update-grub
每次手动下载都稍微有点繁琐,所以有人写了ubuntu-mainline-kernel.sh这类脚本来自动化这个过程。不过我提醒你:主线内核没有经过Ubuntu的完整测试,生产环境慎用。
3.3 CentOS/RHEL系:yum默认不升级内核大版本
CentOS上的情况就不太一样了。CentOS默认仓库里的内核版本更新非常保守,yum update 通常只会升级到当前小版本的最新补丁,而不会跨大版本升级。比如CentOS 7默认是3.10.0,用yum update升一百次也还是3.10.0系列。
所以要给CentOS/RHEL系升级内核,常规做法是借助第三方仓库,最主流的就是ELRepo。这个我放到下一章单独讲。
3.4 为什么优先选择包管理器而不是编译安装
很多刚接触Linux的人会有个误解:以为源码编译安装的内核“更高级”。其实对于绝大多数场景,包管理器安装是唯一推荐的生产级方案,原因很实在:
- 签名验证:官方仓库的每个包都有GPG签名,能确保内核来源可信、没有被篡改。
- 依赖处理:内核配套的模块、头文件、固件包都会被自动处理,省心。
- 回滚容易:用包管理器安装的内核,卸载就是把包删掉,非常干净。编译安装的内核,卸载起来就只能手动清理文件。
- 和系统深度整合:比如Ubuntu装完内核后自动跑update-initramfs、自动更新GRUB菜单,这些步骤如果手动做,漏一步都可能出问题。
编译安装当然有它的价值,但那更适合特定场景:嵌入式系统定制、需要为特定硬件编译特殊选项、或者你就是要搞明白内核怎么工作。对于常规服务器升级,用包管理器就够了。
4. ELRepo路线:CentOS/RHEL系升级内核的标准姿势
4.1 安装ELRepo仓库并导入GPG密钥
ELRepo(Extra Packages for Enterprise Linux)是给RHEL系发行版提供新内核和硬件驱动包的第三方仓库,也是CentOS/RHEL升级内核的事实标准。
先导入ELRepo的GPG密钥,然后安装仓库包:
bash复制# 导入GPG密钥
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
# CentOS 7安装ELRepo
rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm
# CentOS 8/9相应安装对应版本
# CentOS 8: rpm -Uvh https://www.elrepo.org/elrepo-release-8.0-2.el8.elrepo.noarch.rpm
安装完成后验证一下:
bash复制yum repolist
能看到elrepo仓库出现在列表里就说明添加成功了。
4.2 kernel-lt还是kernel-ml:长期支持版和最新主线版的选择
ELRepo提供两个内核包,选择时要注意区分:
| 包名 | 含义 | 适用场景 |
|---|---|---|
kernel-lt |
长期支持内核 | 生产环境、追求稳定、不需要最新特性的服务器 |
kernel-ml |
最新主线内核 | 需要新硬件支持、追求新功能的场景 |
安装命令分别如下:
bash复制# 安装长期支持版
yum install kernel-lt
# 安装最新主线版
yum install kernel-ml
个人建议:生产环境选kernel-lt,桌面或实验环境选kernel-ml。kernel-ml的内核更新非常频繁,基本是跟着上游主线走的,但相对的测试时间也短,出问题的概率更高。kernel-lt更新节奏慢,但每个版本都经历了更长时间的打磨,更适合做生产基线。
4.3 设置默认内核启动项:这一步容易忘
装完新内核后,重启并不会自动进入新内核。GRUB默认会按照菜单里的顺序选择启动项,而新装的kernel-lt或kernel-ml的菜单项通常排在比较靠后的位置。所以需要手动指定默认启动项。
先查看当前系统里有哪些可用的内核启动项:
bash复制# 查看GRUB菜单里的内核列表
awk -F\' '$1=="menuentry " {print $2}' /etc/grub2.cfg
输出大概长这样:
code复制CentOS Linux (5.15.32-1.el7.elrepo.x86_64) 7 (Core)
CentOS Linux (3.10.0-1160.62.1.el7.x86_64) 7 (Core)
每个启动项在GRUB菜单里都对应一个序号,从0开始。假设新内核在第一项,序号就是0。接下来设置默认启动项:
bash复制# 设置默认启动项为第0项
grub2-set-default 0
# 查看当前默认启动项
grub2-editenv list
输出里能看到saved_entry=0,说明设置成功了。如果是UEFI启动的机器,GRUB配置文件路径可能不同,需要确认一下实际生效的grub.cfg路径。
有一步容易漏掉:有些系统在grub2-set-default之后还需要重新生成GRUB配置。稳妥起见可以执行:
bash复制grub2-mkconfig -o /boot/grub2/grub.cfg
注意:如果你的机器是UEFI启动,路径可能是/boot/efi/EFI/centos/grub.cfg,要用对应路径。
4.4 重启后的验证
设置好默认启动项后重启:
bash复制reboot
重启完第一时间验证内核版本:
bash复制uname -r
如果输出的版本号已经变成你新装的内核版本,说明升级成功。同时可以看看系统运行是否正常:
bash复制# 查看系统运行时间,确认不是从旧内核启动
uptime
# 查看启动日志中有没有异常
dmesg | grep -i error
5. 自己动手编译内核:从下载源码到安装全流程
5.1 下载内核源码
编译安装适合什么场景?比如你做嵌入式Linux开发,需要为目标板卡裁剪内核;或者你的硬件需要打开某个默认关闭的编译选项;又或者你纯粹想研究内核源码,那编译就是必经之路。
先去内核官网下载源码包:
bash复制# 到kernel.org找最新的稳定版,例如linux-6.1.56.tar.xz
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.1.56.tar.xz
# 解压
tar xf linux-6.1.56.tar.xz
cd linux-6.1.56
国内网络如果不能直接从kernel.org下载,可以找国内镜像源。实际上很多做嵌入式开发的人手里都有一份经过验证的内核源码树,可能来自芯片厂商(比如瑞芯微、全志)的SDK,用法大同小异,只是版本和默认配置不同。
5.2 安装编译工具链
编译内核需要完整的工具链,Debian系和CentOS系的安装命令不一样:
bash复制# Debian/Ubuntu
sudo apt install build-essential libncurses-dev flex bison bc libssl-dev libelf-dev
# CentOS/RHEL
sudo yum groupinstall "Development Tools"
sudo yum install ncurses-devel flex bison bc openssl-devel elfutils-libelf-devel
这些包里,libncurses-dev/ncurses-devel 是make menuconfig图形配置界面依赖的库,flex和bison是处理内核源码里的语法解析器,bc用来做数值运算,libssl-dev和libelf-dev是因为新版内核需要它们来支持模块签名和BTF信息。
一个常见的报错就是缺少这些依赖,编译到一半直接退出。所以装全还是比较重要的。
5.3 配置内核:不要从头配,先基于当前系统配置改
内核配置是整个编译过程中最核心也最复杂的环节。内核有几千个编译选项,手动一个个选不现实。最合理的做法是基于当前系统正在使用的配置来改:
bash复制# 把当前内核的配置文件复制过来作为起点
cp /boot/config-$(uname -r) .config
# 如果当前系统没有/boot/config文件,可以现在生成一个
# make defconfig
# 用旧配置对新内核源码做一次默认配置
make olddefconfig
make olddefconfig的意思是说:沿用旧配置文件里的选项,对于新内核里新增的选项,全部使用默认值。这是最稳的做法,能保证现有硬件和驱动的配置大部分被保留。
如果想进一步调整,可以打开图形化配置界面:
bash复制make menuconfig
这个界面虽然简陋,但实际操作起来并不难。上下键移动光标、空格键切换选项状态、回车进入子菜单。比如你想把某个驱动编译进内核(而不是编译成模块),进入Device Drivers -> Network device support,找到对应的驱动按空格切换成*即可。
嵌入式场景下,这一步尤其重要。你需要在menuconfig里裁剪掉板子上用不到的功能,比如去掉蓝牙、去掉桌面图形相关的驱动,把内核算小,从而缩短编译时间、降低运行时内存占用。
5.4 编译并安装:这条命令会跑很久
配置完成后就可以开始编译了。
bash复制# 用所有CPU核心并行编译,能快好几倍
make -j$(nproc)
这一步的时间取决于内核规模和机器性能。一颗8核的机器编译默认配置的x86_64内核,大概需要10到20分钟;如果编译全功能大内核或者机器性能差,等一两个小时也正常。编译期间你可以去喝杯咖啡,但别开其他重负载任务,免得内存不够被OOM杀掉。
编译完成后,依次执行安装命令:
bash复制# 安装内核模块
sudo make modules_install
# 安装内核本体、System.map和配置文件
sudo make install
make install 会自动做几件事:把vmlinuz拷贝到/boot目录、生成initramfs镜像、更新GRUB配置。在Debian系系统上它通常会自动调用update-initramfs和update-grub。在CentOS系上,make install也会更新GRUB菜单,但有时候不彻底,建议手动再执行一次:
bash复制# Debian/Ubuntu
sudo update-grub
# CentOS/RHEL
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
5.5 编译安装后的内核清理策略
编译装的没有包管理器记录,卸载只能手动删。删之前先列出来:
bash复制# 列出/boot目录下的内核文件
ls -lh /boot/vmlinuz-*
删除时手动移除vmlinuz、initramfs、System.map和/lib/modules下对应目录即可,但强烈建议保留旧内核至少一个月,确认新内核没问题再动手。我见过有人装完新内核第二天就手动删了旧的,结果新内核因为某个模块问题起不来,旧内核也没了,只能进rescue模式慢慢修。
6. 升级后验证与回滚:别急着删旧内核
6.1 重启后的第一件事:确认内核版本
不管是哪种方式升级,重启后第一件事都是确认新内核真的生效了:
bash复制uname -r
uname -a
cat /proc/cmdline
cat /proc/cmdline 可以看到当前内核启动时实际使用的参数,确认GRUB加载的是哪个vmlinuz、有没有带上预期的启动参数。
6.2 检查关键模块是否正常加载
内核版本号对了只是第一步,还得确认系统各部件正常工作。这里我按优先级列出几条检查项:
- 查看磁盘是否正常挂载:
df -h,确认根分区和数据分区都正常。 - 网络是否正常:
ip addr或ping一下网关,确认网卡驱动加载成功。 - 查看内核日志里的错误:
bash复制dmesg | grep -iE "error|failed|oops"
这条命令能快速暴露出新内核下的驱动问题。比如某些老网卡在新内核里没有对应驱动,dmesg里会直接报failed to load module。
- 检查关键服务是否正常:如果你的数据库、容器平台等依赖内核特性,启动后留意一下服务状态。
还有一点容易被忽略:检查/sys/kernel/btf/vmlinux是否存在。新版内核默认开启BTF,这是eBPF程序加载的基础。如果你后面要跑用eBPF的观测工具,比如bpftrace、Cilium,这个文件必须存在。
6.3 回滚方案:GRUB选择旧内核
升级后如果发现问题,不要慌。只要没删旧内核,回滚其实就是重启后选一下GRUB菜单的事。
重启进入GRUB菜单时,按上下键暂停自动启动,选择旧内核对应的启动项回车即可。如果GRUB菜单没显示,可能需要按Esc或Shift(取决于BIOS还是UEFI)呼出菜单。
进入旧内核后,如果确认要长期留在旧内核,重新设置默认启动项:
bash复制# 查看GRUB菜单里的启动项
awk -F\' '$1=="menuentry " {print $2}' /etc/grub2.cfg
# 假设旧内核在第二个位置,序号是1
grub2-set-default 1
grub2-mkconfig -o /boot/grub2/grub.cfg
Debian系则更简单:
bash复制sudo update-grub
GRUB会检测所有已安装内核并自动生成菜单,你只需要在下次重启时手动选择。
6.4 清理旧内核的正确姿势
确认新内核稳定运行一段时间后(我自己通常是观察一到两周),就可以清理旧内核释放/boot空间了。
Debian系:
bash复制sudo apt autoremove
这个命令会自动移除旧内核包,但建议先看一下将要删除什么:
bash复制sudo apt autoremove --dry-run
CentOS系:
bash复制# 先看已安装的内核包
rpm -qa | grep kernel
# 删除指定旧版本
yum remove kernel-3.10.0-1160.62.1.el7.x86_64
每次清理都保留当前内核和上一个内核,不要急着一口气全删完。这是个保命习惯。
7. 实战中遇到的高频坑:驱动兼容、GRUB引导与gcc版本
7.1 内核无法给PCIe桥接器分配足够内存映射空间(BAR地址不足)
这个坑很典型,尤其是升级到新内核之后,某些PCIe设备(比如显卡、NVMe控制器)会报错,dmesg里出现类似cannot reserve PCI memory BAR或者pcieport ... can't allocate memory的信息。原因在于老内核在启动时给PCIe设备预留的内存映射空间偏保守,而新内核改了资源分配策略后,BIOS预留的MMIO空间不够用了。
常见解决办法是在内核启动参数里加上pci=realloc或者pci=assign-busses,强制内核重新分配PCIe资源。修改GRUB配置:
bash复制vim /etc/default/grub
找到GRUB_CMDLINE_LINUX这一行,在引号里加上参数:
bash复制GRUB_CMDLINE_LINUX="... pci=realloc"
然后重新生成GRUB配置:
bash复制# Debian系
sudo update-grub
# CentOS系
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
重启后观察dmesg,这类问题一般就能解决。如果你是在嵌入式平台上遇到这个问题,还需要检查设备树里PCIe节点的ranges属性是否给足了地址空间,硬件层面预留不够的话,内核怎么配都没用。
7.2 gcc升级后为啥还是旧版本:编译内核必踩的环境变量问题
编译内核时依赖gcc,但很多人会遇到一个问题:明明用yum/apt升级了gcc,执行gcc --version还是显示旧版本。这种情况基本是下面几个原因之一:
- PATH环境变量里旧版本gcc的路径排在前面:你升级后的新gcc可能装在了
/usr/local/bin,而旧的在/usr/bin,而/usr/bin在PATH里更靠前。执行which gcc看看到底调的是哪个。 - Shell缓存了旧的命令路径:执行
hash -r清除一下命令哈希缓存,再试gcc --version。 - 多版本gcc共存,用的是alternatives机制:Debian系可以用
update-alternatives --config gcc切换默认版本。
编译内核时如果gcc版本不匹配,最典型的报错是error: code model kernel does not support PIC mode这类,其实不是代码问题,就是gcc编译器版本或者配置不对。我的经验是:编译内核时先单独跑一下gcc --version,确保编译器版本符合内核源码的Documentation/process/changes.rst里列出的要求。
7.3 第三方内核模块:DKMS让你少掉头发
升级内核后重启黑屏,多半是第三方内核模块没跟上。NVIDIA驱动、ZFS等这些带内核模块的软件,在新内核上不重新编译模块是不可能工作的。好在大部分软件已经用DKMS(Dynamic Kernel Module Support)机制解决这个问题了。
DKMS的作用是:当系统检测到新内核安装后,自动为它重新编译第三方模块。你只需要确认DKMS正常工作:
bash复制# 查看DKMS管理的模块状态
dkms status
输出类似:
code复制nvidia/535.54.01, 5.15.0-91-generic, x86_64: installed
如果新内核对应的显示是built或installed,那就没问题。如果显示missing,手动执行:
bash复制sudo dkms autoinstall
如果你在升级内核前没有装DKMS,可以在装新内核之前先安装:
bash复制# Debian系
sudo apt install dkms
# CentOS系
sudo yum install dkms
有了DKMS,内核升级时的驱动重编负担会小很多。
7.4 /boot分区空间不足:最容易被忽略的拦住升级的坑
很多老机器的/boot分区只有200MB甚至更小,装了好几个内核之后空间就所剩无几了。升级新内核时,安装过程可能因为空间不足直接失败,报错信息却往往不直观。
所以升级前先看一眼空间:
bash复制df -h /boot
如果可用空间已经低于100MB,先清理掉旧内核再升。我建议把/boot空间保持至少200MB以上的余量,因为新版内核的initramfs越来越大,200MB真的不算多。
如果真的已经满了导致装不上,可以先用uname -r确认当前跑的内核,然后删掉比当前版本更老的一个内核包腾出空间,再继续升级。千万别把当前正在运行的内核删了。
8. 聊聊我自己的升级习惯
最后说点实在的。我的服务器和开发机加在一起十几台,升级内核踩了这么多年坑,总结下来有三条原则:
第一,升前必备份,升后留旧核。不管官方文档说得多简单,我永远会留一个旧内核可回滚。真出问题的时候,能多点选择总是好的。
第二,生产环境永远走发行版官方源或ELRepo,不追主线。想尝鲜就去虚拟机里编译主线内核随便折腾,生产环境用长期支持版就够了。嵌入式开发则反过来,跟着芯片厂商SDK的推荐内核版本走,别自己随便升,因为BSP里很多驱动补丁是跟特定内核版本绑死的。
第三,升级内核一次只做一件事。不要同时升内核、升驱动、改GRUB配置、换文件系统,多个变更叠在一起出了问题,你根本不知道是谁的锅。一次只改一个变量,出了问题也好定位。
内核升级这件事,本质上跟汽车保养差不多:定期检查、按需更换、换完留个备用胎。只要提前准备好,实操起来并没有想象中那么可怕。希望这篇文章能帮你少走些弯路。
