手动编译安装Linux RT实时补丁
发布时间:2026-06-23 10:28:12.888 文章来源:AiSoftCloud 浏览次数:68 下载次数:1 

Ubuntu 手动编译 RT 实时内核完整教程

环境说明

适用:Ubuntu 20.04 / 22.04 / 24.04
目标:打 PREEMPT_RT 实时补丁,手动编译安装实时内核
硬件推荐:x86_64 PC / NVIDIA Jetson 嵌入式(步骤通用,仅源码分支有区别)

安装依赖

  1. sudo apt update
  2. sudo apt install build-essential libncurses-dev bison flex libssl-dev libelf-dev dwarves git cpufrequtils
  3. # 可选:用于打包deb内核
  4. sudo apt install libdebconf-kde-dev

下载内核源码 + 对应 RT 补丁

1、版本匹配核心规则
内核版本必须和 RT 补丁版本完全一致
例:linux-6.6.38 → rt 补丁 patch-6.6.38-rt49.patch.xz

uname -a查看当前系统内核版本,例如:

  1. Linux ubuntu-YogaPro-16s-IRP8 6.8.0-124-generic #124~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue May 26 21:05:19 UTC x86_64 x86_64 x86_64 GNU/Linux

Ubuntu 22.04,当前内核 6.8.0-124-generic,x86_64 笔记本 Yoga Pro 16s IRP8
必须下载 6.8 系列主线内核 + 同版本 rt 补丁

查看当前主线稳定RT版本:
https://cdn.kernel.org/pub/linux/kernel/projects/rt/

安装全套编译依赖

  1. sudo apt update
  2. sudo apt install -y build-essential libncurses-dev bison flex libssl-dev libelf-dev dwarves git cpufrequtils rt-tests

下载 6.8 内核源码与对应 RT 补丁

  1. mkdir ~/kernel_rt_6.8 && cd ~/kernel_rt_6.8
  2. # 主线6.8源码
  3. wget -c https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/linux-6.8.2.tar.xz
  4. # 6.8 系列rt补丁合集
  5. wget -c https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/6.8/patch-6.8.2-rt11.patch.xz
  6. # 解压源码
  7. tar -xf linux-6.8.2.tar.xz
  8. cd linux-6.8.2
  9. # 打入RT补丁
  10. xz -dc ../patch-6.8.2-rt11.patch.xz | patch -p1

拷贝当前系统硬件配置:

  1. cp /boot/config-$(uname -r) .config

设置编译选项:

  1. make menuconfig

编译:

  1. make menuconfig
  2. # 1. 根儿案例setup -> Preemption Model 选 Fully Preemptible Kernel (RT)
  3. # 2. Timer frequency = 1000Hz
  4. # 3. Local version 填 -rt11
  5. # 保存退出
  6. yes "" | make olddefconfig
  7. # 编译
  8. make -j$(nproc)
  9. make modules -j$(nproc)
  10. # 安装
  11. # 安装模块时自动删除调试符号,模块体积直接缩水90%
  12. sudo make INSTALL_MOD_STRIP=1 modules_install
  13. sudo make install

脚本设置.config

  1. # 1. 设置 Fully Preemptible Kernel (RT)
  2. ./scripts/config --enable CONFIG_PREEMPT_RT
  3. # 2. 设置 Timer frequency 1000Hz
  4. ./scripts/config --set-val CONFIG_HZ 1000
  5. # 3. 设置 Local version
  6. ./scripts/config --set-val CONFIG_LOCALVERSION "-rt11"
  7. # 修复证书编译报错核心两行
  8. ./scripts/config --disable CONFIG_SYSTEM_TRUSTED_KEYS
  9. ./scripts/config --disable CONFIG_SYSTEM_REVOCATION_KEYS
  10. # 自动补齐依赖、校验配置(必执行)
  11. make olddefconfig

1、开启 RT 完全抢占(6.x内核为CONFIG_PREEMPT_RT,5.x为CONFIG_PREEMPT_RT_FULL)

  1. ./scripts/config --enable CONFIG_PREEMPT_RT

内部会自动配套开启:CONFIG_PREEMPT、CONFIG_PREEMPT_RT 相关依赖,不用手动开。
2、定时器 1000Hz

  1. ./scripts/config --set-val CONFIG_HZ 1000

3、内核版本后缀 -rt11

  1. ./scripts/config --set-val CONFIG_LOCALVERSION "-rt11"

编译后 uname -r 会显示类似 5.15.xx-rt11。

验证是否修改成功

  1. # 查看抢占模式
  2. grep CONFIG_PREEMPT_RT_FULL .config
  3. # 查看时钟频率
  4. grep CONFIG_HZ .config
  5. # 查看本地版本
  6. grep CONFIG_LOCALVERSION .config

异常问题

编译时如果报如下错误:

  1. ubuntu@ubuntu-YogaPro-16s-IRP8:~/kernel_rt_6.8/linux-6.8.2$ make -j$(nproc)
  2. mkdir -p /home/ubuntu/kernel_rt_6.8/linux-6.8.2/tools/objtool && make O=/home/ubuntu/kernel_rt_6.8/linux-6.8.2 subdir=tools/objtool --no-print-directory -C objtool
  3. mkdir -p /home/ubuntu/kernel_rt_6.8/linux-6.8.2/tools/bpf/resolve_btfids && make O=/home/ubuntu/kernel_rt_6.8/linux-6.8.2 subdir=tools/bpf/resolve_btfids --no-print-directory -C bpf/resolve_btfids
  4. INSTALL libsubcmd_headers
  5. INSTALL libsubcmd_headers
  6. CALL scripts/checksyscalls.sh
  7. make[3]: *** No rule to make target 'debian/canonical-certs.pem', needed by 'certs/x509_certificate_list'. Stop.
  8. make[2]: *** [scripts/Makefile.build:481: certs] Error 2
  9. make[2]: *** Waiting for unfinished jobs....
  10. CHK kernel/kheaders_data.tar.xz
  11. make[1]: *** [/home/ubuntu/kernel_rt_6.8/linux-6.8.2/Makefile:1921: .] Error 2
  12. make: *** [Makefile:240: __sub-make] Error 2

报错原因
Ubuntu 官方内核打包依赖 debian/canonical-certs.pem 证书文件,主线源码 / RT 补丁源码里没有这个文件,编译签名证书环节直接中断。

两种根治方案(推荐方案 1,关闭内核签名,最省事)
方案 1:命令行关闭系统证书签名(无需下载证书,一键修复)
在内核源码根目录执行:

  1. # 关闭Canonical系统信任证书
  2. ./scripts/config --disable CONFIG_SYSTEM_TRUSTED_KEYS
  3. # 关闭系统吊销证书列表
  4. ./scripts/config --disable CONFIG_SYSTEM_REVOCATION_KEYS
  5. # 无交互刷新配置
  6. yes "" | make olddefconfig

然后再编译:

  1. make -j$(nproc)

方案 2:如果你需要开启证书签名(不推荐,麻烦)
手动创建空文件绕过检测:

  1. mkdir -p debian
  2. touch debian/canonical-certs.pem

然后再执行编译,但后续模块签名会失效,本地编译自用完全没必要。

安装后重新启动报

  1. error: out of memory

原因为:
你直接 make modules_install 没有剥离调试符号,编译出来的内核模块体积巨大,Ubuntu 自动生成的 initrd.img-6.8.2-rt11 动辄几百 MB,开机加载内存盘直接爆内存 OOM 卡死。

开机按delete或F2键,选择正常内核进入系统,然后修改:

  1. sudo vi /etc/initramfs-tools/initramfs.conf

MODULES=most改为MODULES=dep
most:打包几乎所有硬件驱动(体积爆炸,你当前问题元凶)
dep:仅自动识别你当前电脑挂载根盘必需的驱动,体积直接压缩 70% 以上

  1. # 删除boot下旧的rt内核文件
  2. cd /boot
  3. sudo rm -f vmlinuz-6.8.2-rt11 initrd.img-6.8.2-rt11 config-6.8.2-rt11 System.map-6.8.2-rt11
  4. # 删除臃肿未剥离符号的模块
  5. sudo rm -rf /lib/modules/6.8.2-rt11

重新编译:

  1. cd ~/kernel_rt_6.8/linux-6.8.2
  2. # 安装模块时自动删除调试符号,模块体积直接缩水90%
  3. sudo make INSTALL_MOD_STRIP=1 modules_install
  4. sudo make install

检查内核版本

  1. uname -a
  2. Linux ubuntu-YogaPro-16s-IRP8 6.8.2-rt11 #1 SMP PREEMPT_RT Tue Jun 23 18:14:36 CST 2026 x86_64 x86_64 x86_64 GNU/Linux
  1. 先看当前抢占模式简易判断

    1. cat /sys/kernel/realtime

    输出 1 = PREEMPT_RT 已启用;0 = 普通抢占内核。

  2. 查看内核启动参数抢占标识

    1. cat /proc/cmdline

    RT 内核通常会带 preempt=full 或 preempt=rt。

输出结果:

  1. BOOT_IMAGE=/boot/vmlinuz-6.8.2-rt11 root=UUID=fd505579-ee80-4ad3-9cad-5e1ec31f1043 ro quiet splash vt.handoff=7

修改/etc/default/grub
找到 GRUB_CMDLINE_LINUX_DEFAULT,替换成(示例隔离 CPU4、5,你可根据自己 CPU 核心数调整):

  1. GRUB_CMDLINE_LINUX_DEFAULT="quiet splash vt.handoff=7 preempt=rt isolcpus=4,5 nohz_full=4,5 rcu_nocbs=4,5 rcu_nocb_poll"
  2. sudo update-grub

修改完之后必须执行sudo update-grub

  1. 读取已安装内核的 config 文件(最稳)
    内核编译配置一般存在 /boot/config-$(uname -r)
    1. grep PREEMPT /boot/config-$(uname -r)
    正常 RT 内核输出示例:
    1. CONFIG_PREEMPT=y
    2. CONFIG_PREEMPT_RT=y
    3. CONFIG_PREEMPT_COUNT=y
    4. CONFIG_PREEMPT_DYNAMIC=y

配套实时内核前置检查完整命令集

  1. # 1. 确认实时开关
  2. cat /sys/kernel/realtime
  3. # 2. 读取内核完整配置
  4. grep PREEMPT /boot/config-$(uname -r)
  5. # 3. 检查用户实时权限
  6. ulimit -r -l
  7. # 4. 临时设置CPU性能模式(降低延迟)
  8. sudo cpupower frequency-set -g performance

测试

系统基础实时配置(测试前必须优化)
1、关闭 CPU 节能:禁用 cpufreq、intel_pstate、turbo boost

  1. # 固定CPU最高频率
  2. echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
  3. # 关闭节能C-state
  4. echo 1 | tee /sys/devices/cpu/cpu*/cpuidle/state*/disable

2、隔离 CPU 核心(irqaffinity、isolcpus)
内核启动参数添加:
isolcpus=18,19 nohz_full=18,19 rcu_nocbs=18,19
3、关闭内存交换、透明巨页

  1. swapoff -a
  2. echo never > /sys/kernel/mm/transparent_hugepage/enabled

4、提升测试进程实时优先级

  1. chrt -f -p 99 ./test_app # SCHED_FIFO 最高优先级99

核心时延测试工具(分内核态 / 用户态)

  1. cyclictest(最标准实时时延测试,推荐)
    安装
    1. # Debian/Ubuntu
    2. apt install rt-tests
    3. # RHEL/CentOS
    4. dnf install rt-tests
    基础用法
    1. # 单CPU隔离测试,跑30分钟,打印统计
    2. sudo cyclictest -t1 -p99 -i1000 -l1800000 --histfile=hist.txt -m
    参数说明:
    -t1:1 个测试线程
    -p99:FIFO 优先级 99
    -i1000:1ms 周期定时
    -l1800000:总循环 180 万次(30min)
    -h hist.txt:输出时延直方图

多核隔离标准测试(核心用法)

  1. # 使用隔离CPU 2,禁止迁移,高精度时钟
  2. cyclictest -a2 -p99 -m -S -i10000

-a2:绑定线程到 CPU2
-m:锁内存 mlockall,避免缺页中断
-S:标准统计输出(min/avg/max)

结果解读
运行结束输出:

  1. T: 0 ( 2827) P:99 C:12345 Min:0 Avg:7 Max:487
  2. # Min最小时延、Avg平均、Max最大时延(单位us)

实时指标标准(工业硬实时)
工控裸金属无负载:最大抖动<50us
带少量外设负载:<100us
若 max>1000us:存在严重抢占阻断(驱动、内核线程、中断干扰)

  1. hackbench:内核调度压力测试
    模拟大量进程 / 线程切换,施压调度器,放大实时抖动

    1. hackbench -l 100000

    配合 cyclictest 并行运行,复现高负载下最大时延。

  2. latencytop:定位内核时延来源(根因分析)
    安装

    1. apt install latencytop
    1. #捕获全局内核延迟阻塞点
    2. latencytop

    可直观看到:
    哪些内核函数关闭抢占(spinlock、驱动阻塞)
    中断处理耗时过长
    RCU、workqueue 延迟

  3. ftrace:内核级精准追踪(高级调试)
    用于定位最大时延根源,RT 内核排障神器
    开启抢占延迟追踪

    1. mount -t tracefs none /sys/kernel/tracing
    2. echo preemptirqsoff > /sys/kernel/tracing/trace_event
    3. echo 10000 > /sys/kernel/tracing/buffer_size_kb
    4. echo 1 > /sys/kernel/tracing/tracing_on
    5. # 后台跑cyclictest,完成后关闭
    6. echo 0 > /sys/kernel/tracing/tracing_on
    7. cat /sys/kernel/tracing/trace > delay_log.txt

    可抓到关中断 / 关抢占的完整调用栈,定位劣质驱动、内核模块。

  4. stress-ng:制造系统负载极限测试
    模拟 IO、内存、CPU、中断压力,验证极端场景实时性

    1. # 多核CPU+内存压力,后台跑cyclictest
    2. stress-ng --cpu 4 --vm 2 --timeout 30m

三、中断实时性测试(硬件关键项)

  1. 查看 IRQ 亲和性
    1. cat /proc/interrupts
    2. # 将设备中断绑定到非实时核心,避免抢占实时任务
    3. echo f0 > /proc/irq/xx/smp_affinity
  2. irqsoff 追踪中断关闭时长
    1. echo irqsoff > /sys/kernel/tracing/trace_event
    捕获长时间关中断代码,这是实时抖动头号来源。

四、自定义用户态实时程序测试(C 代码示例)
测试高精度周期任务,统计抖动,验证 SCHED_FIFO/SCHED_DEADLINE

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #include <sched.h>
  5. #include <time.h>
  6. #include <sys/mman.h>
  7. #define PERIOD_NS 1000000 // 1ms周期
  8. #define TEST_LOOP 1000000
  9. int main()
  10. {
  11. mlockall(MCL_CURRENT|MCL_FUTURE);
  12. struct sched_param sp;
  13. sp.sched_priority = 99;
  14. pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp);
  15. struct timespec t_start, t_now;
  16. long long min = 1e9, avg = 0, max = 0;
  17. clock_gettime(CLOCK_MONOTONIC, &t_start);
  18. for(int i=0; i<TEST_LOOP; i++){
  19. // 等待下一个周期
  20. t_start.tv_nsec += PERIOD_NS;
  21. if(t_start.tv_nsec >= 1000000000){
  22. t_start.tv_sec++;
  23. t_start.tv_nsec -= 1000000000;
  24. }
  25. clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t_start, NULL);
  26. // 计算实际延迟
  27. clock_gettime(CLOCK_MONOTONIC, &t_now);
  28. long long delta = (t_now.tv_sec - t_start.tv_sec)*1000000 + (t_now.tv_nsec - t_start.tv_nsec)/1000;
  29. if(delta < min) min = delta;
  30. if(delta > max) max = delta;
  31. avg += delta;
  32. }
  33. printf("Min: %lld us | Avg: %lld us | Max: %lld us\n", min, avg/TEST_LOOP, max);
  34. return 0;
  35. }

编译:gcc rt_test.c -o rt_test -lpthread -lrt
运行:sudo ./rt_test

补充:笔记本跑 RT 前必做优化(Yoga Pro 16s)
1、锁住 CPU 性能模式

  1. echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

2、关闭 swap 防止缺页抖动

  1. sudo swapoff -a

3、关闭透明大页

  1. echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
更多文章可关注公众号
aisoftcloud