> 技术文档 > 【Linux / Ubuntu20.04 | 安装实时内核补丁PREEMPT_RT】_ubuntu 实时补丁

【Linux / Ubuntu20.04 | 安装实时内核补丁PREEMPT_RT】_ubuntu 实时补丁


ubuntu20.04安装PREEMPT_RT实时内核及测试

  • 1.前置准备工作
  • 2.从官方下载内核的源码和对应RT补丁
  • 3.安装依赖项
  • 4.创建内核+补丁的环境
  • 5.配置内核
  • 6.编译带RT补丁的内核
  • 7.校验结果
  • 8.设置用户权限以使用RT实时调度(关键一步)
  • 9.测试实时性
  • 10.启动设置
  • 11.其他设置

1.前置准备工作

大多数教程都说:“首先要通过uname -r查看当前版本内核,注意查找离自己目前内核最接近的 kernal 并下载,然后根据下载的内核版本下载补丁,内核版本和补丁版本要保持一致。”但据我的测试,我在5.15.0-64-generic的基础上,分别安装了5.15.167-rt79和5.10.225-rt117,都是可以正常运行rt内核的,实时性都是OK的。不清楚大家为什么这么说?

2.从官方下载内核的源码和对应RT补丁

正确的顺序应该是,先去rt页面找到哪个版本有对应的rt补丁,再去linux内核页面下载对应的内核源码。

  1. RT补丁:https://www.kernel.org/pub/linux/kernel/projects/rt/
  2. linux内核源码:https://www.kernel.org/pub/linux/kernel

本文使用的是在ubuntu20.04内核5.15.0-64-generic基础上,安装了linux5.10.225内核以及对应的5.10.225-rt117实时补丁,已通过测试。

【需要注意】RT补丁尽量和linux内核版本上完全保持一致,有的教程也说可以接近就行,但没尝试过,不确定稳定性如何。

3.安装依赖项

sudo apt-get install libncurses5-dev libssl-dev build-essential openssl zlibc libelf-dev minizip libidn11-dev libidn11 bison flex zstd

4.创建内核+补丁的环境

假如下载的是xz后缀,以5.10.225为例:

sudo mkdir /usr/src/rt_kernalsudo cp ~/Downloads/linux-5.10.225.tar.xz /usr/src/rt_kernal/sudo cp ~/Downloads/patch-5.10.225-rt117.patch.xz /usr/src/rt_kernal/cd /usr/src/rt_kernal/sudo suxz -cd linux-5.10.225.tar.xz | tar xvf -cd linux-5.10.225xzcat ../patch-5.10.225-rt117.patch.xz | patch -p1

5.配置内核

如果之前操作都正确,目前应该是在linux-5.10.225的root用户路径下
所以接下来的操作都没有sudo命令前缀
如果不是root,使用sudo su进入

  1. 复制系统当前内核的.config文件(无论当前是哪个内核版本都可以)
cp /boot/config-5.15.0-64-generic .config
  1. 进入图形化界面配置.config文件
make menuconfig
  1. 需要改动的地方如下:

General Setup -> Timers subsystem -> Timer tick handling 设置为 Full dynticks system
General Setup -> Timers subsystem 开启 High Resolution Timer Support
General Setup -> Preemption Model 设置为 Fully Preemptible Kernel (Real Time)
Processor type and features -> Timer frequency 设置为 1000 HZ
Device Drivers -> staging drivers 设置为 不开启 ——[ ] 默认开启,按N取消

  1. 编辑.config文件并修改以下内容
gedit .config

CONFIG_SYSTEM_TRUSTED_KEY=“”
CONFIG_SYSTEM_REVOCATION_KEYS=“”
CONFIG_DEBUG_INFO=n
不然新内核带debug信息超大

  1. 下面正式开始编译后,全部按enter选择默认选项即可

6.编译带RT补丁的内核

其中-j$(nproc)表示使用本机的全部线程数进行编译,加快速度

本机共20个线程,下面四步完整编译过程大约30分钟

make -j$(nproc)make modules_install -j$(nproc)make install 

7.校验结果

cd /bootls

查看/boot 目录下是否有生成的rt核心,应该包括以下4个文件:

config-5.10.225-rt117
System.map-5.10.225-rt117
initrd.img-5.10.225-rt117
vmlinuz-5.10.225-rt117

如果都有,则重启电脑,在开机引导中选择linux-5.10.225-rt117,开机后检查当前内核版本号,若为5.10.225-rt117则表示正确安装了RT补丁

rebootuname -r

8.设置用户权限以使用RT实时调度(关键一步)

为了能够以用户权限调度线程(驱动程序将执行此操作),您需要通过更改/etc/security/limits.conf文件来修改用户的限制

建议为实时用户设置一个组,而不是将固定的用户名写入配置文件:

sudo groupadd realtimesudo usermod -aG realtime $(whoami)

然后:

sudo nano /etc/security/limits.conf

确保/etc/security/limits.conf文件包含以下内容:

@realtime soft rtprio 99@realtime soft priority 99@realtime soft memlock 204800@realtime hard rtprio 99@realtime hard priority 99@realtime hard memlock 204800

其中,rtprio是实时调度的优先级,memlock是内存锁定的大小,单位为KB,防止应用程序的内存被交换到磁盘(即锁定内存),从而保证高性能

使用 ulimit -r 命令来验证当前用户的实时优先级限制,这个命令会返回用户的最大实时优先级。正常情况下,输出应该是 99。如果不是,说明配置没有正确应用

9.测试实时性

安装rt_test测试工具

sudo apt-get install rt-tests 

运行测试 5个线程,线程优先级99,以ms单位显示时间

sudo cyclictest -t 5 -p 99 -N -m
  • -t 5:启动 5 个线程
  • -p 99:设置线程的优先级为 99
  • -N: 测试结果使用精度更高的ns显示(默认是us)
  • -m: 将当前和接下来的内存通过mlock锁定内存,禁止内存交换到磁盘,减少延迟波动

测试结果中各项含义如下

T: 线程P: 线程优先级C: 计数器。线程的时间间隔每达到一次,计数器加1I: 时间间隔为1000微秒(us)Min: 最小延时(us)Act: 最近一次的延时(us)Avg: 平均延时(us)Max: 最大延时(us) 

10.启动设置

/etc/default/grub中配置开机自动选择

sudo gedit /etc/default/grub
 GRUB_TIMEOUT=10 %超时时间,单位s GRUB_DEFAULT=\"1>2\" %1代表默认启动第2个内核,2代表所启动内核1中的第3个(序号从0开始)

然后更新grub

sudo update-grub

11.其他设置

  1. 检查SMT状态:查看/sys/devices/system/cpu/smt/下的文件

    cat /sys/devices/system/cpu/smt/active # 1-已启动smt 0-已禁用smt
    • 关闭SMT

      sudo sh -c \'echo off > /sys/devices/system/cpu/smt/control\'
  2. 检查CPU核心隔离:

    taskset -cp $$

    taskset 是一个用于设置或获取进程的 CPU 亲和性的命令
    -c:表示显示或设置 进程的 CPU 亲和性
    -p:表示显示或设置 指定进程的 CPU 亲和性
    $$ 表示正在运行该命令的当前 shell 进程的 ID

    • 判断CPU大小核:使用一种很傻瓜的逻辑,如果有更好的方法,请在下方评论区告诉我,感谢大佬指点!
      1. 查看cpu工作模式:

        cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

        返回powersave则为节能模式,performance则为高性能模式,如果是高性能则直接执行第3步,否则从2开始执行。

        ps:启动高性能模式:
        1)推荐:BIOS中找到PCI-ASPM或类似的(一般在电源管理内)设置成disable
        2)临时:
        a.安装sudo apt-get install linux-tools-common linux-tools-generic工具
        b.执行sudo cpupower frequency-set --governor performance

      2. CPU节能模式下,执行stress --cpu 20来让所有核满负载工作

        ps:stress是个小工具,可以用sudo apt install stress安装;20代表CPU核数量,不知道几核的话可以用更大的数字代替,向下兼容,写100都可以)

      3. 再执行cat /proc/cpuinfo | grep -E \"processor|cpu MHz\",频率最小的几个就是小核(E核),其余都是大核,输出类似如下:

        processor: 0cpu MHz: 4500.000processor: 1cpu MHz: 4500.002processor: 2cpu MHz: 4500.000processor: 3cpu MHz: 4500.000processor: 4cpu MHz: 4500.000processor: 5cpu MHz: 4500.002processor: 6cpu MHz: 4500.000processor: 7cpu MHz: 4500.000processor: 8cpu MHz: 4500.000processor: 9cpu MHz: 4500.002processor: 10cpu MHz: 4500.000processor: 11cpu MHz: 4500.000processor: 12cpu MHz: 4500.000processor: 13cpu MHz: 4500.002processor: 14cpu MHz: 4499.997processor: 15cpu MHz: 4500.000processor: 16cpu MHz: 3334.881processor: 17cpu MHz: 3334.670processor: 18cpu MHz: 3334.540processor: 19cpu MHz: 3334.407

        可以看出这里16-19都是小核,其余16个是8个大核(带超线程),符合我的CPU12700的架构,8P核+4E核

    • 隔离CPU核心:
      1. 编辑sudo nano /etc/default/grub
      2. 找到GRUB_CMDLINE_LINUX=\"\"改成GRUB_CMDLINE_LINUX=\"isolcpus=x,x,x\",这里的x表示将要隔离的核心ID
      3. 使改变生效sudo update-grub,重启即可