一、实时内核补丁移植:从零开始的实战之路
大家好,我是老李。做嵌入式Linux实时系统这行,掐指一算也有十多年了。今天咱们聊的,是实时内核补丁移植最核心的一步——把PREEMPT_RT补丁打进去,让普通Linux内核变成实时内核。
说实话,我第一次做这个移植的时候,也踩了不少坑。补丁打不上、编译报错、系统起不来……这些我都经历过。所以今天这篇文章,我会把每一步的关键点、容易出错的地方,都掰开揉碎了讲清楚。
核心知识点速览
- 下载正确版本的内核源码
- 获取匹配的PREEMPT_RT补丁
- 应用补丁并解决冲突
- 配置内核实时选项
1.1 下载内核源码——版本匹配是命门
我个人习惯,去 kernel.org 下载主线内核。但这里有个关键点:PREEMPT_RT补丁只支持特定版本。你想想看,补丁是跟着主线走的,不是随便拿个版本就能打。
举个例子,如果你下载了5.15.0的内核,但RT补丁只出到5.15.10,那肯定打不上。我建议去 RT补丁官方页面 先看看当前支持哪些版本。
我的经验:选LTS版本最稳妥。比如5.10.x、5.15.x、6.1.x这些长期支持版,RT补丁维护得也最久。我曾经图新鲜用了个最新主线,结果补丁打了三天没打上……
# 下载内核源码(以5.15.10为例)
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.10.tar.xz
tar -xf linux-5.15.10.tar.xz
cd linux-5.15.10
1.2 获取PREEMPT_RT补丁
补丁文件通常是一个 .patch.xz 压缩包。注意:补丁版本必须和内核版本完全一致。比如内核是5.15.10,补丁就得是 patch-5.15.10-rt*.patch.xz。
这里有个坑——补丁命名规则。我记得有一次,我下载了 patch-5.15.10-rt30.patch.xz,但内核是5.15.10,结果打补丁时一堆冲突。后来才发现,补丁的基线版本号必须精确匹配。
# 下载RT补丁
wget https://cdn.kernel.org/pub/linux/kernel/projects/rt/5.15/older/patch-5.15.10-rt30.patch.xz
xz -d patch-5.15.10-rt30.patch.xz
1.3 应用补丁——最考验耐心的环节
补丁下载好了,接下来就是应用。命令很简单:
# 进入内核源码目录
cd linux-5.15.10
# 应用补丁
patch -p1 < ../patch-5.15.10-rt30.patch
嗯,这里要注意。如果补丁应用成功,你会看到类似 patching file kernel/sched/core.c 这样的输出,没有任何错误信息。但现实往往没那么顺利……
警告:如果出现 Hunk #1 FAILED at 123. 之类的错误,说明有冲突。千万别慌,也别直接放弃。这是正常的,尤其是当你的内核源码和补丁的基线版本有微小差异时。
1.4 解决补丁冲突——实战中的硬骨头
冲突来了怎么办?我一般分三步走:
- 查看.rej文件:补丁失败时,会生成
.rej文件,里面记录了哪些地方没打上。 - 手动编辑源文件:打开对应的
.c或.h文件,找到冲突位置,根据.rej文件的内容手动修改。 - 重新应用补丁:手动修改后,再次运行
patch -p1,这次应该能通过了。
我曾经在一个项目中,因为内核源码里有个驱动文件被厂商改过,导致RT补丁打不上。我花了整整一个下午,手动对比了300多行代码,才把冲突解决掉。说实话,那次之后我学乖了——尽量用纯净的主线源码。
避坑指南:
- 不要用发行版自带的内核源码(比如Ubuntu的),它们经常被修改过
- 如果冲突太多,检查一下内核版本和补丁版本是否匹配
- 可以用
patch --dry-run先模拟运行,看看有没有冲突
# 模拟运行,提前发现冲突
patch -p1 --dry-run < ../patch-5.15.10-rt30.patch
1.5 配置内核实时选项
补丁打上之后,内核源码里就有了实时相关的配置项。接下来要做的,就是通过 make menuconfig 开启实时功能。
具体操作路径:
make menuconfig
然后找到:
General setup --->
Preemption Model (Voluntary Kernel Preemption (Desktop)) --->
(X) Fully Preemptible Kernel (Real-Time)
选择 Fully Preemptible Kernel (Real-Time),这就是PREEMPT_RT的核心选项。除此之外,我建议再检查一下:
Timer frequency设置为1000 Hz(实时系统需要高精度定时)CPU Isolation相关选项(如果有需要隔离CPU的场景)RCU相关选项(实时RCU会有一些特殊配置)
小技巧:配置完成后,可以搜索 RT 或 PREEMPT_RT,看看还有哪些实时相关的选项没开。我一般会检查 CONFIG_PREEMPT_RT=y 是否真的被选中了。
1.6 验证补丁是否成功
配置完成后,编译内核。如果编译通过,可以查看 /proc/config.gz 或 /boot/config-* 确认:
zcat /proc/config.gz | grep PREEMPT_RT
CONFIG_PREEMPT_RT=y
CONFIG_PREEMPT_RT_FULL=y
看到这两个选项是 y,说明实时内核已经移植成功了。
好了,这就是实时内核补丁移植的完整流程。说白了,就是下载、打补丁、解决冲突、配置、编译这几步。但每一步都有细节,尤其是补丁冲突那一步,最考验耐心。我刚开始做的时候也经常卡住,但多做几次就熟练了。
希望这篇文章能帮你少走弯路。如果你在移植过程中遇到问题,欢迎交流。
公众号:蓝海资料掘金营,微信deep3321