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 install15、查看引导项是否已配好
$cat /boot/grub/grub.conf16、假如是多系统的话,将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)拷贝到windows下的menu.lst后为:
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
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