Debian/Unbutu Linux升级打RT实时内核补丁

xingyun86 2021-4-20 1635

Debian/Unbutu Linux升级打RT实时内核补丁

参考链接:

https://wiki.linuxfoundation.org/realtime/start

https://rt.wiki.kernel.org/index.php/HOWTO:_Build_an_RT-application#Application

https://www.cnblogs.com/harrychinese/p/pc-based-motion-control.html


******注意版本号一定要选一致******

下载linux内核
https://mirrors.tuna.tsinghua.edu.cn/kernel/v4.x/linux-4.19.188.tar.gz
下载RT补丁内核
http://cdn.kernel.org/pub/linux/kernel/projects/rt/4.19/patch-4.19.188-rt77.patch.gz

1.安装升级配置内核所需依赖库
sudo apt update
sudo apt install patch
sudo apt install libncurses-dev
sudo apt install bison
sudo apt install flex
sudo apt install libelf-dev
sudo apt install libssl-dev
sudo apt install bc
sudo apt install libnuma-dev


2.打补丁及编译配置
tar -xvf patch-4.19.188-rt77.patch.gz
gunzip patch-4.19.188-rt77.patch.gz
cp patch-4.19.188-rt77.patch ./linux-4.19.188/
cd linux-4.19.188
patch -p1 < patch-4.19.188-rt77.patch
make menuconfig

[make ARCH=i386 menuconfig 或 make ARCH=x86_64 menuconfig]

==========================================
2.1 首页进入General Setup ---> 按下回车进入Preemption Model (Fully Preemptible Kernel (RT)) ---> 按下回车进入 Fully Preemptible Kernel (RT)。选中该选项
2.2 首页进入Kernel hacking ---> 按下回车进入 Memory Debugging ---> 按下回车进入 Check for stack overflows。取消该项选中状态
2.3 首页切换菜单到 < Save > ---> 按下回车进入 .config (默认即可) ---> 选择 < Ok > 按下回车。完成

3.编译内核
cd linux-4.19.188
make
sudo make modules_install
sudo make install
sudo update-grub

常见错误及解决办法:
错误1:如果"No rule to make target 'debian/certs/debian-uefi-certs.pem', needed by 'certs/x509_certificate_list'. Stop
解决办法:
vi .config
CONFIG_SYSTEM_TRUSTED_KEYS = ""

4.测试

下载安装rt-tests源代码,cyclictes编译好。

tar xvf rt-test.tar.bz2
cd rt-tests
make
sudo ./cyclictest -t 5 -p 80 -n  //运行5个线程,线程的优先级为80,无线循环
sudo ./cyclictest -l10000000 -m -n -t1 -p99 -i2 -h100


另类方法安装rt内核:

debian官方给出了某些内核版本的rt包可以方便升级使用。

linux-image-4.9.0-14-rt-amd64_4.9.246-2_amd64.deb

使用简单。dpkg -i linux-image-4.9.0-14-rt-amd64_4.9.246-2_amd64.deb即可。


测试代码

在其中编写一个RT 线程的应用程序,通常需要如下步骤:

Setting a real time scheduling policy and priority.
Locking memory so that page faults caused by virtual memory will not undermine deterministic behavior.

Pre-faulting the stack, so that a future stack fault will not undermine deterministic behavior.

例子test_rt.c,其中的mlockall是为了防止进程的虚拟地址空间对应的物理页面被swap出去,而stack_prefault()则故意提前导致stack往下增长8KB,因此其后的函数调用和局部变量的使用将不再导致栈增长(依赖于page fault和内存申请):

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <sched.h>
#include <sys/mman.h>
#include <string.h>

#define MY_PRIORITY (49) /* we use 49 as the PRREMPT_RT use 50
                            as the priority of kernel tasklets
                            and interrupt handler by default */

#define MAX_SAFE_STACK (8*1024) /* The maximum stack size which is
                                   guaranteed safe to access without
                                   faulting */

#define NSEC_PER_SEC    (1000000000) /* The number of nsecs per sec. */

void stack_prefault(void) {

        unsigned char dummy[MAX_SAFE_STACK];

        memset(dummy, 0, MAX_SAFE_STACK);
        return;
}

int main(int argc, char* argv[])
{
        struct timespec t;
        struct sched_param param;
        int interval = 50000; /* 50us*/

        /* Declare ourself as a real time task */

        param.sched_priority = MY_PRIORITY;
        if(sched_setscheduler(0, SCHED_FIFO, ¶m) == -1) {
                perror("sched_setscheduler failed");
                exit(-1);
        }

        /* Lock memory */

        if(mlockall(MCL_CURRENT|MCL_FUTURE) == -1) {
                perror("mlockall failed");
                exit(-2);
        }

        /* Pre-fault our stack */

        stack_prefault();

        clock_gettime(CLOCK_MONOTONIC ,&t);
        /* start after one second */
        t.tv_sec++;

        while(1) {
                /* wait until next shot */
                clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL);

                /* do the stuff */

                /* calculate next shot */
                t.tv_nsec += interval;

                while (t.tv_nsec >= NSEC_PER_SEC) {
                       t.tv_nsec -= NSEC_PER_SEC;
                        t.tv_sec++;
                }
   }
}

编译运行:

gcc -o test_rt test_rt.c -lrt

上传的附件:
×
打赏作者
最新回复 (0)
只看楼主
全部楼主
返回