【Linux / Ubuntu20.04 | 安装实时内核补丁PREEMPT_RT】
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内核页面下载对应的内核源码。
- RT补丁:https://www.kernel.org/pub/linux/kernel/projects/rt/
- 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_kernal
sudo 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 su
xz -cd linux-5.10.225.tar.xz | tar xvf -
cd linux-5.10.225
xzcat ../patch-5.10.225-rt117.patch.xz | patch -p1
5.配置内核
如果之前操作都正确,目前应该是在linux-5.10.225的root用户路径下
所以接下来的操作都没有sudo命令前缀
如果不是root,使用sudo su进入
- 复制系统当前内核的.config文件(无论当前是哪个内核版本都可以)
cp /boot/config-5.15.0-64-generic .config
- 进入图形化界面配置.config文件
make menuconfig
- 需要改动的地方如下:
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取消
- 编辑.config文件并修改以下内容
gedit .config
CONFIG_SYSTEM_TRUSTED_KEY=“”
CONFIG_SYSTEM_REVOCATION_KEYS=“”
CONFIG_DEBUG_INFO=n
不然新内核带debug信息超大
- 下面正式开始编译后,全部按enter选择默认选项即可
6.编译带RT补丁的内核
其中-j$(nproc)
表示使用本机的全部线程数进行编译,加快速度
本机共20个线程,下面四步完整编译过程大约30分钟
make -j$(nproc)
make modules_install -j$(nproc)
make install
7.校验结果
cd /boot
ls
查看/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补丁
reboot
uname -r
8.设置用户权限以使用RT实时调度(关键一步)
为了能够以用户权限调度线程(驱动程序将执行此操作),您需要通过更改/etc/security/limits.conf
文件来修改用户的限制
建议为实时用户设置一个组,而不是将固定的用户名写入配置文件:
sudo groupadd realtime
sudo 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: 计数器。线程的时间间隔每达到一次,计数器加1
I: 时间间隔为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.其他设置
-
检查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'
-
-
检查CPU核心隔离:
taskset -cp $$
taskset
是一个用于设置或获取进程的 CPU 亲和性的命令
-c
:表示显示或设置 进程的 CPU 亲和性
-p
:表示显示或设置 指定进程的 CPU 亲和性
$$
表示正在运行该命令的当前 shell 进程的 ID- 判断CPU大小核:使用一种很傻瓜的逻辑,如果有更好的方法,请在下方评论区告诉我,感谢大佬指点!
-
查看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
-
CPU节能模式下,执行
stress --cpu 20
来让所有核满负载工作ps:
stress
是个小工具,可以用sudo apt install stress
安装;20
代表CPU核数量,不知道几核的话可以用更大的数字代替,向下兼容,写100
都可以) -
再执行
cat /proc/cpuinfo | grep -E "processor|cpu MHz"
,频率最小的几个就是小核(E核),其余都是大核,输出类似如下:processor : 0 cpu MHz : 4500.000 processor : 1 cpu MHz : 4500.002 processor : 2 cpu MHz : 4500.000 processor : 3 cpu MHz : 4500.000 processor : 4 cpu MHz : 4500.000 processor : 5 cpu MHz : 4500.002 processor : 6 cpu MHz : 4500.000 processor : 7 cpu MHz : 4500.000 processor : 8 cpu MHz : 4500.000 processor : 9 cpu MHz : 4500.002 processor : 10 cpu MHz : 4500.000 processor : 11 cpu MHz : 4500.000 processor : 12 cpu MHz : 4500.000 processor : 13 cpu MHz : 4500.002 processor : 14 cpu MHz : 4499.997 processor : 15 cpu MHz : 4500.000 processor : 16 cpu MHz : 3334.881 processor : 17 cpu MHz : 3334.670 processor : 18 cpu MHz : 3334.540 processor : 19 cpu MHz : 3334.407
可以看出这里16-19都是小核,其余16个是8个大核(带超线程),符合我的CPU12700的架构,8P核+4E核
-
- 隔离CPU核心:
- 编辑
sudo nano /etc/default/grub
- 找到
GRUB_CMDLINE_LINUX=""
改成GRUB_CMDLINE_LINUX="isolcpus=x,x,x"
,这里的x
表示将要隔离的核心ID - 使改变生效
sudo update-grub
,重启即可
- 编辑
- 判断CPU大小核:使用一种很傻瓜的逻辑,如果有更好的方法,请在下方评论区告诉我,感谢大佬指点!