4、PREEMPT_RT内核编译与部署:获取源码、配置内核选项、编译与安装、启动验证
好,咱们进入正题。这一章讲的是PREEMPT_RT内核的编译与部署。说白了,就是怎么把那个“实时补丁”打到内核里,然后编译、装上去,最后验证它到底能不能跑出实时效果。
我刚开始接触这块的时候,也踩过不少坑。比如编译完了启动直接panic,或者跑起来发现延迟比标准内核还高……嗯,这些我都会在下面提到。你跟着我的步骤走,能省不少时间。
4.1 获取源码:从哪里下载?
首先,你得拿到两样东西:标准内核源码和PREEMPT_RT补丁。这两者版本必须严格对应,差一个patch level都不行。
- 标准内核源码:去
kernel.org下载。我个人习惯用长期支持版(LTS),比如5.10.y或5.15.y。稳定,社区支持好。 - PREEMPT_RT补丁:去
rt.wiki.kernel.org找。页面里有个“Patch”列表,找到对应你内核版本的 .patch.xz 文件。
下载命令示例:
# 下载内核源码
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.145.tar.xz
# 下载RT补丁
wget https://cdn.kernel.org/pub/linux/kernel/projects/rt/5.15/older/patch-5.15.145-rt83.patch.xz
# 解压
tar -xf linux-5.15.145.tar.xz
cd linux-5.15.145
# 打补丁
xzcat ../patch-5.15.145-rt83.patch.xz | patch -p1
打完补丁后,源码目录里会多出一些RT相关的文件。你可以用 git diff 看看改动量,通常有几百个文件被修改。嗯,这很正常。
4.2 配置内核选项:打开实时开关
源码准备好了,接下来就是配置。这一步最关键,也最容易漏东西。
我建议你基于现有的配置文件来改。比如从 /boot/config-$(uname -r) 复制一份过来,然后运行 make menuconfig。
你需要手动开启以下几个关键选项:
| 配置项 | 路径 | 说明 |
|---|---|---|
CONFIG_PREEMPT_RT_FULL |
General setup → Preemption Model | 选择“Fully Preemptible Kernel (RT)” |
CONFIG_HIGH_RES_TIMERS |
General setup → Timers subsystem | 高精度定时器,RT必备 |
CONFIG_NO_HZ_FULL |
General setup → Timers subsystem | 减少定时器中断干扰,建议开启 |
CONFIG_IRQ_FORCED_THREADING |
Kernel Features → IRQ subsystem | 强制中断线程化,减少关中断时间 |
CONFIG_ARM_GIC 和 CONFIG_ARM_ARCH_TIMER 是否开启。我曾经在树莓派上忘了开GIC中断控制器支持,结果系统响应延迟直接飙到毫秒级,排查了两天才发现。
配置完成后,保存退出。你可以用 grep PREEMPT .config 确认一下:
grep PREEMPT .config
# 应该看到:
# CONFIG_PREEMPT_RT_FULL=y
# CONFIG_PREEMPT_RT=y
4.3 编译与安装:耐心等待
配置好了,开始编译。这里我建议你用多核编译,能快不少。
# 编译内核和模块
make -j$(nproc) bzImage
make -j$(nproc) modules
# 安装模块
sudo make modules_install
# 安装内核
sudo make install
编译时间取决于你的机器。我自己的笔记本(8核)编译5.15内核大概需要15分钟。如果你用的是嵌入式开发板交叉编译,那时间会更长,建议用 distcc 或 ccache 加速。
make olddefconfig,它会自动把新选项设为默认值。这样你只需要手动改那几个RT相关的选项,省事很多。
安装完成后,检查一下 /boot 目录:
ls /boot/vmlinuz-*
# 应该能看到类似 vmlinuz-5.15.145-rt83 的文件
4.4 启动验证:到底有没有生效?
重启系统,在GRUB菜单里选择新内核启动。如果GRUB没自动识别,你可以手动更新:
sudo update-grub
启动后,第一件事就是确认内核版本:
uname -a
# 输出应该包含 "PREEMPT RT" 字样
# 例如:Linux host 5.15.145-rt83 #1 SMP PREEMPT_RT ...
如果看到 PREEMPT_RT,说明补丁生效了。但光看这个还不够,你得实际测一下实时性能。
我常用的测试工具是 cyclictest(来自rt-tests包):
# 安装rt-tests
sudo apt install rt-tests
# 运行测试,测量1000次,间隔1000微秒
sudo cyclictest -l 1000 -m -n -p 99 -i 1000 -h 100
输出结果里,重点关注 最大延迟(Max Latency)。在标准内核上,这个值可能几百微秒甚至几毫秒。在PREEMPT_RT内核上,通常能控制在50微秒以内。我自己的测试环境(x86_64)跑出来最大延迟是23微秒,嗯,这个水平对于大多数工业控制场景已经够用了。
避坑指南:如果你发现最大延迟还是很高(比如超过200微秒),别急着怀疑内核。先检查一下:
- BIOS里有没有关闭CPU调频、C-State省电模式?
- 有没有其他高优先级中断在干扰?比如网卡、显卡。
- 你的测试程序本身有没有被调度到同一个CPU核心上?
我曾经在笔记本上测,最大延迟一直下不来,后来发现是ACPI的省电策略在捣鬼。关掉之后,延迟直接降了一个数量级。
4.5 知识体系总览
下面这张图,我把整个流程串起来了。你对照着看,心里就有数了。
这张图把四个步骤串起来了:获取源码 → 配置内核 → 编译安装 → 启动验证。每个环节都有对应的关键动作和检查点。你照着这个流程走,基本不会出大问题。
好了,这一章的内容就到这里。PREEMPT_RT内核的编译部署,说白了就是“打补丁、开选项、编译、测试”这四步。每一步都有坑,但只要你细心对照我上面说的检查点,应该能顺利搞定。