Linux内核实时补丁PREEMPT_RT安装

时间:2023-01-21 08:52:05

Linux打实时内核PREEMPT_RT补丁,及编译内核过程总结如下:

1、下载内核kernel及preempt-rt;

Kernel:http://www.kernel.org/pub/linux/kernel/   (尽量下载形如linux-2.6.33.tar.gz的,形如linux-2.6.33.7tar.gz的没有complete preemption(Real-Time)选项,且打补丁时也可能出错)

PREEMPT_RT:http://www.kernel.org/pub/linux/kernel/projects/rt/

2、解压kernel及preemp-rt;

3、在/usr/src/目录下mkdir rt-preempt-linux;

4、copy kernel(linux-2.6.33.6) and preempt(patch-2.6.33.3-rt26) to the rt-preempt-linux;

5、copy preempt-rt(patch-2.6.33.3-rt26) to the kernel(linux-2.6.33.6) directory;

6、change directory to kernel(linux-2.6.33.6) directory;

7、patch -p1 < patch-2.6.33.3-rt26

下面是内核配置过程:

8、

$ make mrproper    删除目录下残留的.o文件和其他从属文件,

拷贝原系统的.config 到 新下载的内核文件根目录下;(假如使用下载的内核自带的.config文件可能会出现module找不到现象)

copy /usr/src/kernel/2.6.32-431.el6.i686/.config /usr/src/rt-preempt-linux/linux-2.6.33.6/

也可以直接执行 make oldconfig, 而不用copy。

9、

$make menuconfig
选择processor type and features

        ->preemption mode

            ->complete preemption(Real-Time)

10、

选择Thread Softing 和 Thread Hardings

11、

返回上一级

选择Device Driver

        ->去掉Staging Drivers

下面是内核编译过程:

12、

$make -jn
(n 是要衍生的作业书,在实际中,每个处理器上一般衍生一个或两个作业。例如在一个双核处理器上可以使用$make -j4)

13、

$make  modules_install
$mkinitrd /boot/initramfs-2.6.33-rt7.img 2.6.33-rt7

14、

$make install
15、查看引导项是否已配好

$cat /boot/grub/grub.conf
16、假如是多系统的话,将grub.conf 拷贝到Windows的c:\NST\menu.lst后,并把对应的盘符修改成在windows下的表示即可。(参考 点击打开链接

例如:安装linux-3.12.24后,在CentOS的/boot/grub/grub.conf(or /etc/grub.conf)为:

title CentOS (3.12.24-rt37)
root (hd2,5)
kernel /boot/vmlinuz-3.12.24-rt37 ro root=UUID=7482efc1-7e35-4a09-a3b7-64256ce7aee2 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
initrd /boot/initramfs-3.12.24-rt37.img

拷贝到windows下的menu.lst后为: 

title CentOS (3.12.24-rt37)
root (hd1,5)
kernel (hd1,5)/boot/vmlinuz-3.12.24-rt37 ro root=UUID=7482efc1-7e35-4a09-a3b7-64256ce7aee2 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
initrd (hd1,5)/boot/initramfs-3.12.24-rt37.img

备注:假如出现modules 找不到的错误,尝试yum -y upgrade kernel kernel-devel 后在make install;或者参考本文后的网络参考#2;万一不行换一个linux版本编译。

测试用cyclictest 下载:https://rt.wiki.kernel.org/index.php/Cyclictest


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
网络参考#1:

一、RTPREEMT_RT简介

标准的Linux 内核只能能够满足软中断的要求,为用户空间提供简基本的Posix操作,但是不对固定的时间点做保证。Ingo Molnar's 的实时抢占补丁(文中为:PREEMPT_RT)和 ThomasGleixner的具有高分辨率的通用时钟事件层,Linux增加了硬事实能力。

PREEMPT_RT 补丁因起了工业界的关注。由于它简洁的设计和与内核的mainline的一致性,所以,它的硬实时和企业实时应用程序出现在专业的视频到工业控制领域。(根据[1]翻译)

 

二、获取PREEMPT_RT

方法一:通过git下载最新的代码

http://git.kernel.org/?p=linux/kernel/git/rostedt/linux-rt.git;a=summary 

这样下载后的代码不需要打补丁,已经是最新的代码了。

 

方法二: 分别下载内核代码和补丁

Kernel:http://www.kernel.org/pub/linux/kernel/

PREEMPT_RT:http://www.kernel.org/pub/linux/kernel/projects/rt/

下载的内核和补丁要对应,如kernel为linux-2.6.33.7.tar.bz2,补丁为patch-2.6.33.7.2-rt30.bz2。

 

三、打补丁的方法(通过git获取的不需要打补丁)

$tar xfv linux-2.6.33.7.tar.bz2 $ cd linux-2.6.33.7 $ bzcat ../patch-2.6.33.7.2-rt30.bz2 | patch -p1

四、内核配置

$make menuconfig

4.1在“Processor typeand features”中

(1)选择“Complete Preemption(Real-Time)”

 

(2)选择“ThreadSoftirqs”和“ThreadHardirqs”

 2. 在”Device Drivers”中,去掉“Staging Drivers”

 

由于Staging不稳定,导致编译报错[2]:

LD [M] drivers/net/bnx2x.o

make: *** [drivers] 错误 2

unanao@debian:~/Experiment/linux/linux-2.6.33.7$ make

CHK include/linux/version.h

CHK include/generated/utsrelease.h

CALL scripts/checksyscalls.sh

CHK include/generated/compile.h

VDSOSYM arch/x86/vdso/vdso-syms.lds

VDSOSYM arch/x86/vdso/vdso32-int80-syms.lds

VDSOSYM arch/x86/vdso/vdso32-syscall-syms.lds

VDSOSYM arch/x86/vdso/vdso32-sysenter-syms.lds

VDSOSYM arch/x86/vdso/vdso32-syms.lds

LD arch/x86/vdso/built-in.o

LD arch/x86/built-in.o

LD drivers/staging/built-in.o

CC [M] drivers/staging/comedi/drivers/quatech_daqp_cs.o

drivers/staging/comedi/drivers/quatech_daqp_cs.c:70: error: field ‘eos’has incomplete type

drivers/staging/comedi/drivers/quatech_daqp_cs.c: In function‘daqp_interrupt’:

drivers/staging/comedi/drivers/quatech_daqp_cs.c:291: error: implicitdeclaration of function ‘up’

drivers/staging/comedi/drivers/quatech_daqp_cs.c: In function‘daqp_ai_insn_read’:

drivers/staging/comedi/drivers/quatech_daqp_cs.c:405: error: implicit declarationof function ‘sema_init’

drivers/staging/comedi/drivers/quatech_daqp_cs.c:418: error: implicitdeclaration of function ‘down_interruptible’

drivers/staging/comedi/drivers/quatech_daqp_cs.c: In function‘daqp_cs_attach’:

drivers/staging/comedi/drivers/quatech_daqp_cs.c:1045: warning: assignmentfrom incompatible pointer type

make[4]: *** [drivers/staging/comedi/drivers/quatech_daqp_cs.o] 错误 1

make[3]: *** [drivers/staging/comedi/drivers] 错误 2

make[2]: *** [drivers/staging/comedi] 错误 2

make[1]: *** [drivers/staging] 错误 2

make: *** [drivers] 错误 2

 

五、编译

$make -jn

(n 是要衍生的作业书,在实际中,每个处理器上一般衍生一个活两个作业。例如在一个双和处理器上可以使用$make -j4)[3]

#make install

#make modules_install

#cd /boot

#mkinitramfs -k -o initrd.img-2.6.33.7.2-rt 2.6.33.7.2-rt30

(这一步是必须的,否则是起不来系统的)

 

六、修改grub.cfg

在grub.cfg中找到debian原有的一段配置文件,修改红色部分就可以了。

menuentry 'Debian GNU/Real Time Linux, with Linux2.6.33.7.2-rt30' --class debian --class gnu-linux --classgnu --class os {

insmod part_msdos

insmod ext2

set root='(hd0,msdos2)'

search --no-floppy --fs-uuid --set a9f7fdc4-3975-4e23-aa13-6e22d35d6ad9

echo 'Loading Linux 2.6.33.7.2--rt30 ...'

linux /boot/vmlinuz-2.6.33.7.2-rt30root=UUID=a9f7fdc4-3975-4e23-aa13-6e22d35d6ad9 ro quiet

echo 'Loading initial ramdisk ...'

initrd /boot/initrd.img-2.6.33.7.2-rt

}

修改后,重启就可以选择进入系统了

 

七、基准测试

在这里下载基准测试程序:

http://www.kernel.org/pub/linux/kernel/people/tglx/rt-tests/

下载后解压,

$make all

测试:

非实时内核:

root@debian:/home/unanao/Experiment/linux/rt-tests# ./cyclictest -t1 -p 80-n -i 10000 -l 10000

policy: fifo: loadavg: 0.02 0.16 0.14 2/303 3109

T: 0 ( 2599) P:80 I:10000 C: 10000 Min: 8 Act: 48 Avg: 108 Max: 8294

root@debian:/home/unanao/Experiment/linux/rt-tests# ./cyclictest -t1 -p 80-i 500 -l 100000

policy: fifo: loadavg: 0.21 0.14 0.12 1/306 3129

T: 0 ( 2690) P:80 I:500 C: 10000 Min: 10 Act: 31 Avg: 77 Max: 7943

 

实时内核:

root@debian:/home/unanao/Experiment/linux/rt-tests# ./cyclictest -t1 -p 80-n -i 10000 -l 10000

policy: fifo: loadavg: 0.02 0.16 0.14 2/303 3109

T: 0 ( 3107) P:80 I:10000 C: 10000 Min: 6 Act: 54 Avg: 65 Max: 282

root@debian:/home/unanao/Experiment/linux/rt-tests# ./cyclictest -t1 -p 80-i 500 -l 100000

policy: fifo: loadavg: 0.21 0.14 0.12 1/306 3129

T: 0 ( 3129) P:80 I:500 C: 100000 Min: 12 Act: 75 Avg: 91 Max: 418

比较可知实时内核的实时性更好。

 

八、参考文档

[1] https://rt.wiki.kernel.org/index.php/RT_PREEMPT_HOWTO

[2] http://comments.gmane.org/gmane.linux.rt.user/5780

[3]《Linux 内核设计与实现》

 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

网络参考#2

yum install ncurses-devel (这个包在make menuconfig时要用到,本人测试过)

2、到www.kernel.org下载内核linux-2.6.22.6.tar.gz
将新内核copy到/usr/src

# tar -jxvf linux-2.6.27.tar.bz2 
# cd linux-2.6.27 
# make mrproper 
# make menuconfig (这里就是设置编译成模块或是否编译进内核或不选)
# make clean 
# make bzImage 
# make modules 
# make modules_install 后可以执行make install 自动化完成
# mkinitrd /boot/initrd_2.6.27.img 2.6.27

执行mkinitrd命令时,提示”No module dm-mem-cache found for kernel 2.6.27, aborting.”时,表明该版本的mkinitrd有bug。 
解决方法,1是当使用mkinitrd时,使用”-without-dmraid”这个参数。2是在使用mkinitrd之前,先创建一个noraid文件。创建方法如下:

# echo “DMRAID=no” > /etc/sysconfig/mkinitrd/noraid 
# chmod 755 /etc/sysconfig/mkinitrd/noraid

然后再运行mkinitrd命令。


这里我采用了第一种办法 
# mkinitrd /boot/initrd-2.6.27.img 2.6.27 –without-dmraid 
执行完mkinitrd后,就要在启动菜单中增加编译好的内核信息,以便启动时可以选择内核版本。 
# cp arch/x86/boot/bzImage /boot/vmlinuz-2.6.27 
# cp System.map /boot/System.map-2.6.27 
打开/etc/grub.conf文件,增加以下内容到文件结尾。

title CentOS (2.6.27) 
root (hd0,0) 
kernel /vmlinuz-2.6.27 ro root=LABEL=/ 
initrd /initrd-2.6.27.img

保存,重启,进行grub的启动菜单中,选择”CentOS(2.6.27)”,即可使用编译好的内核。


第二种方法 如果你觉得make modules_install后面的步骤太麻烦的话,就直接用下面的命令让系统帮你做好了 
# make install

下面是运行时的提示信息: 
sh /usr/src/linux-2.6.27/arch/x86/boot/install.sh 2.6.27 arch/x86/boot/bzImage System.map “/boot” 
WARNING: No module dm-mem-cache found for kernel 2.6.27, continuing anyway 
WARNING: No module dm-message found for kernel 2.6.27, continuing anyway 
WARNING: No module dm-raid45 found for kernel 2.6.27, continuing anyway

这些只是提示,对系统没有什么影响,经本人查阅相关的资料。

可能是内核和mkinitrd的BUG,大家可以参考一下这篇文章

https://bugzilla.redhat.com/show_bug.cgi?id=488991

通过给内核打dm-raid45这个补丁,可以解决掉”WARNING: No module dm-raid45 found for kernel 2.6.29.4, continuing anyway”这个提示 
http://people.redhat.com/~heinzm/sw/dm/dm-raid45/

至于其他的两个没有仍然找不到解决的办法

更简单的yum -y upgrade kernel kernel-devel



# make mrproper    删除目录下残留的.o文件和其他从属文件,
$ make mrproper    删除目录下残留的.o文件和其他从属文件,