3. PREEMPT_RT内核编译
构建一个具备实时能力的 Linux 内核是进行 PREEMPT_RT 性能调优的第一步。本章将详细讲解从获取源码、配置内核选项到编译与安装的完整流程,确保你能够搭建一个稳定、可重复的实时内核实验环境。
3.1 获取内核源码与 RT 补丁
PREEMPT_RT 内核的构建基于主线 Linux 内核源码加上对应的 RT 补丁。获取方式有两种主流途径:
| 方式 | 来源 | 适用场景 |
|---|---|---|
| 主线 + 补丁 | kernel.org + rt.wiki.kernel.org | 最新特性、自定义调试 |
| 发行版 RT 内核 | Ubuntu/Debian/Fedora 仓库 | 快速部署、生产环境 |
以下步骤以主线 + 补丁方式为例,这是性能调优专家最常用的方法,能够精确控制内核版本与配置。
关键版本匹配规则: RT 补丁的版本号必须与主线内核版本号完全一致。例如,补丁 patch-6.1.19-rt10.patch.xz 只能应用于 linux-6.1.19.tar.xz 源码。
# 1. 下载主线内核源码
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.1.19.tar.xz
tar -xf linux-6.1.19.tar.xz
cd linux-6.1.19
# 2. 下载对应的 RT 补丁
wget https://cdn.kernel.org/pub/linux/kernel/projects/rt/6.1/older/patch-6.1.19-rt10.patch.xz
xz -d patch-6.1.19-rt10.patch.xz
# 3. 应用补丁
patch -p1 < patch-6.1.19-rt10.patch
3.2 内核配置:启用 PREEMPT_RT 选项
配置是决定内核实时性能的核心环节。在 make menuconfig 界面中,必须将抢占模型设置为 Fully Preemptible Kernel (Real-Time)。
配置路径: General setup → Preemption Model → 选择 Fully Preemptible Kernel (Real-Time)。
除了抢占模型,以下关键选项对实时性能有直接影响,建议根据硬件平台进行微调:
| 配置项 | 推荐值 | 说明 |
|---|---|---|
CONFIG_PREEMPT_RT |
y | 启用完整实时抢占 |
CONFIG_HZ_1000 |
y | 1000Hz 时钟中断,提高调度精度 |
CONFIG_NO_HZ_FULL |
y | 全无滴答模式,减少周期性中断干扰 |
CONFIG_RCU_NOCB_CPU |
y | 将 RCU 回调卸载到专用 CPU |
CONFIG_CPU_FREQ |
n | 关闭动态调频,避免延迟抖动 |
配置陷阱: 如果启用了 CPU_FREQ 或 CPU_IDLE 的深度睡眠状态,中断延迟可能从微秒级恶化到毫秒级。在实时调优阶段,建议先关闭这些节能特性。
以下 SVG 图展示了内核配置中抢占模型的选择流程与关键依赖关系:
3.3 编译与安装
配置完成后,进入编译阶段。对于实时内核,建议使用以下参数以平衡编译速度与内核优化:
# 清理之前的编译产物
make clean
# 编译内核与模块(使用所有 CPU 核心加速)
make -j$(nproc)
# 编译内核模块
make modules_install
# 安装内核与 System.map
make install
编译优化提示: 在 Makefile 中设置 CFLAGS 为 -O2 而非 -Os,可以避免编译器为了减小体积而牺牲实时性能。对于 x86_64 平台,建议添加 march=native 以启用当前 CPU 的所有指令集优化。
安装完成后,需要更新引导加载程序。以 GRUB 为例:
# 更新 GRUB 配置
update-grub
# 重启并选择新内核
reboot
# 验证内核版本与抢占模型
uname -r
# 预期输出: 6.1.19-rt10
# 检查 PREEMPT_RT 是否启用
cat /proc/sys/kernel/sched_rt_runtime_us
# 如果输出 -1,表示 RT 调度器已启用
3.4 编译后验证清单
安装完成后,建议执行以下验证步骤,确保内核正确运行:
| 验证项 | 命令 | 预期结果 |
|---|---|---|
| 内核版本 | uname -r |
包含 -rt 后缀 |
| 抢占模型 | zcat /proc/config.gz | grep PREEMPT |
CONFIG_PREEMPT_RT=y |
| 时钟频率 | cat /proc/interrupts | grep timer |
中断频率接近 1000 Hz |
| RT 调度器 | chrt -m |
显示 SCHED_FIFO/SCHED_RR 优先级范围 |
以下 SVG 图展示了从源码获取到内核启动的完整编译安装流程:
3.5 常见编译错误与解决方案
编译实时内核时,可能会遇到以下典型问题:
- 补丁冲突: 如果主线内核版本与补丁版本不匹配,
patch命令会报告Hunk #1 FAILED。解决方案是重新下载匹配的版本对。 - 缺少依赖: 编译过程中提示
fatal error: openssl/opensslv.h: No such file or directory。安装libssl-dev即可解决。 - 模块签名失败: 如果启用了
MODULE_SIG但未配置密钥,编译会中断。在make menuconfig中临时禁用该选项,或生成签名密钥。 - GRUB 未更新: 安装后重启仍进入旧内核。手动运行
grub-mkconfig -o /boot/grub/grub.cfg并检查/boot目录下新内核的 vmlinuz 文件是否存在。
调试技巧: 如果编译失败,不要盲目重新开始。先查看 make 输出的最后 20 行错误信息,定位到具体的源文件或配置项。使用 make V=1 可以输出详细的编译命令,帮助定位链接错误。
完成以上步骤后,你的系统将运行一个完整的 PREEMPT_RT 内核,为后续的中断延迟与调度延迟测量提供坚实的底层平台。