ksrc/子目录提供了内核空间的支持,被看做是Linux内核的一个内建扩展,并没有更多的作为单独树模块的一个集合。这种做法的直接好处是具有了将Xenomai实时子系统静态构建到目标内核的能力,或者是作为早期版本的可加载模块。因此,通常的Linux内核配置过程通常用于定义的Xenomai内核组件的各种设置。“准备目标内核”和“配置和构建内核”章节说明了这种内核空间支持的安装过程。
src/子目录包含由Xenomai框架提供的各种用户空间库和命令。这个目录的构架可以不用内核的支持,即使后者在构建系统里没有。“构建用户空间支持”这一节说明了用户空间支持的安装过程。
Xenomai提供一个实时子系统无缝集成到Linux,因此第一步是将它构建为目标内核的一部分。为此,scripts/prepare-kernel.sh是一个shell脚本适当的设定了目标内核。语法形式如下:
$scripts/prepare-kernel.sh --linux=<linux-srctree> [--adeos=<adeos-patch>] [--arch=<target-arch>] --linux 指定目标内核源码树的路径。这种内核树配置与否没有什么区别,是两种有效的方式。 --adeos 指定Adeos补丁的路径应用到对应的内核树。Xenomai合适的补丁可以在ksrc/arch<target-arch>/patches下获得。如果Adeos已经修补则这个参数可以省略,否则脚本会建议一个合适的补丁。无论如何,每当一个先前的补丁被探测到,脚本将不会再次尝试应用它。 --arch 告诉脚本目标体系结构。如果未注明,构建系统的架构将会被检测到并会作为一个默认合理的建议。 |
例如,下面的命令将会准备位于/usr/src/linux-2.6.23-ipipe为了包含Xenomai支持的Linux树:
$cd xenomai-2.4 $scripts/prepare-kernel.sh --linux=/usr/src/linux-2.6.23-ipipe |
注意:这个脚本将会从它在的Xenomai源码树中推断Xenomai内核代码。也就是说,如果/usr/src/scripts/prepare-kernel.sh 被执行了,则Xenomai的内核支持将会从/usr/src/xenomai-2.4/ksrc并势必会绑到目标内核。
2.2 配置和建立目标内核
一旦目标内核被准备完毕,内核应该按照其通常的配置过程被配置。所有的Xenomai配置选项都可以在“Real-time subsystem”(实时子系统)的顶层菜单中获得。
有很多重要的内核配置选项,有些在TROUBLESHOOTING指导手册中提到,其他的在"Typeical installation procedures"的您正在使用的体系结构中提到。
一旦被配置,内核必须像往常一样被构建。
如果你想要几个不同的配置/构建,你可以通过对每个调用增加O=../build-<target>用同样的资源。请查看“PowerPC体系结构下构建”的例子。
为了能交叉编译Linux内核,在make命令的时候传递给ARCH和CROSS_COMPLIE变量值。查看“PowerPC体系结构下构建”、“Blackfin的构建”、“ARM下的构建”和“NIOS II下的构建”章节。
2.3 构建用户空间的支持
提供了一个常规的autoconf脚本来准备构建用户空间的支持。以下列出的选项可以传递给这个脚本。那些选项只会影响作为Xenomai的用户空间支持的库的编译,无论如何,他们永远不会影响基于内核的支持。
2.3.1 功能冲突解决
由于内核和用户空降强烈的解耦和,Xenomai需要确认所有在配置是选择的用户空间的选项将会符合在运行时从目标内核获得实际的支持。例如,X86中在用户空间启动对TSC的支持,但是内核以禁用CONFIG_X86_TSC的形式编译,这一点如果你没有捕获,则肯定会导致运行时的问题。因为Xenomai和应用不允许他们的定时使用高精度的时钟。此外,大部分的这类问题不能在编译阶段探测到,因为目标和主机相比通常有不同的功能(特点),即使他们是相同的架构(例如 386vs686)。
为了解决潜在的问题,每个Xenomai体系结构的接口定义了一组测试一致性的接关键特点,每当用户空间的应用绑定自己到内核空间实时接口的时候。在这种情况下没有被解决的冲突将会被报告并且执行会立刻停止。
在两边需要完美匹配的选项在下面的列表中被标记为“strong”,其他的被标记为“weak”。Xenomai处理耐受性差异的方法取决于逐案基础和所考虑的选项。当不适用时,绑定的类型仍然是不确定的。
例如,UP和启用SMP的内核可以漠不关心地运行Up或启动SMP的用户空间的应用程序,因为SMP选项的比绑定是弱的。另一方面,基于x86的应用链接针对编译时开启x86-tsc选项的Xenomai库来说,必须运行以CONFIG_X86_TSC设置构建的内核上,因为x86-tsc选项是强绑定。
2.3.2 通用配置选项
名称 | 描述 | [绑定,]默认 |
--prefix | 安装目录 | /usr/xenomai |
--enable-debug | 开启调试标志(-g) | disable |
--enable-smp | 开始SMP支持 | weak, enabled |
--with-atomic-ops= | 在Xenomai库中选择采用哪个原子访问操作的实现: --with-atomic-ops= builtins选择GCC内建的,例如_sync*()服务。 --with-atomic-ops=ad-hoc 选择ad hocXenomai实现 当这个开关没有被指定,系统将会依据目标体系就够做一个保守的选择。 除非GCC工具链过时(也就是,不提供这些操作)或算坏了, --with-atomic-ops=builtins必须被使用。 | arch-dependent |
2.3.3 特定体系结构的配置选项
名称 | 描述 | [绑定,]默认 |
--enable-x86-sep | 未解决系统调用启用x86 SEP指令,你还需要NPTL | strong,enabled |
--enable-x86-tsc | 为了计时开启x86 TSC,你必须拥有TSC。 | strong,enabled |
--enable-arm-tsc | 开启ARM TSC仿真 | weak,kuser |
--enable-arm-quirks | 为特定的ARM片上系统开启quirks,当前支持sa1100和xscale3 | weak,disabled |
2.3.4 交叉编译
为了交叉编译Xenomai用户控件的支持,你需要给配置脚本传递一个--host和--build选项。--host选项允许为体系结构选择要构建的库和程序。--build选项允许选择编译的工具要运行的体系结构,即,系统运行配置脚本。
由于交叉编译需要特定的工具,这些工具通常以宿主机的体系结构名字为前缀;例如一个PowerPC体系结构的编译器会被命名为powerpc-405-linux-gnu-gcc。
当把选项--host=powerpc-405-linux-gnu-gcc传递给配置文件的时候,配置文件将会自动的使用powerpc-405-linux-gnu-gcc作为所有编译工具名字的一个前缀并且会从这个前缀中推断宿主机体系结构的名字。如果配置文件不能从交叉编译工具前缀中推断出宿主机体系结构的名字,你需要手工的去传递所有编译工具的名字。查看“PowerPC结构下构建”和“Blackfin下构建”章节,使用CC和LD变量的例子,或者“ARM下构建”使用--host参数的例子。
制作一个GNU交叉编译器最简单的方法可能包括使用crosstool-ng,在
可以获得。
如果你想避免构建自己的交叉编译器,你或许可以使用ELDK。它包含了GNU 交叉开发工具,例如;编译器、binutils、gdb等等。并且一些预构建的目标工具盒库需要提供一些目标系统的功能。点击
了解详情。
其他一些预构建的工具链:
- Mentor Sourcery CodeBench Lite Edition,点击获取;
- Linaro toolchain(针对ARM体系架构),点击获取。
3 典型的安装过程
以下章节中使用的例子遵循以下约定:
$linux_tree
目标内核源文件的路径
$xenomai_root
Xenomai源文件的路径
$build_root
一个干净的构建目录
$staging_dir
在将安装文件移动到他们最终的为之前暂时存储它们的目录;当使用交叉编译安装时,它通常是从目标根目录到本地构建主机的一个NFS挂载点,作为在宿主机上运行make DESTDIR=$staging_dir install的结果立即用安装的程序和库更新目标系统。
3.1 x86_32/64位下构建
从Linux 2.6.24 x86_32和x86_64树合并了。因此,为2.6.24或以后的版本构建Xenomai几乎相同,不管是32/64位问题。然而,你必须注意的是无法将使用x86_32编译的xenomai库运行在使用x86_64编译的内核上。
假设你想构建本地x86_64系统(从x86_64表示出的x86_32交叉构建选项在括号中),你将会运行:
$ $xenomai_root/scripts/prepare-kernel.sh --arch=x86 \ --adeos=$xenomai_root/ksrc/arch/x86/patches/adeos-ipipe-2.6.29.4-x86-X.Y-ZZ.patch \ --linux=$linux_tree $ cd $linux_tree $ make [ARCH=i386] xconfig/gconfig/menuconfig |
...配置内核(同时点击
查看建议设置)
启用Xenomai选项,那么安装需要:
$ make [ARCH=i386] bzImage modules $ mkdir $build_root && cd $build_root $ $xenomai_root/configure --enable-x96-sep \ [--host=i686-linux CFLAGS=“-m32 -O2” LDFLAGS="-m32"] $ make install |
现在,我们来讨论你真地想为一个基于奔腾 x86 32位平台运行一个传统2.6.23内核构建Xenomai,使用本地主机的工具链;典型的步骤如下:
$$xenomai_root/scripts/prepare-kernel.sh --arch=i386 \ --adeos=$xenomai_root/ksrc/arch/x86/patches/adeos-ipipe-2.6.23-i386-X.Y-ZZ.patch \ --linux=$linux_tree $cd $linux_tree $make xconfig/gconfig/menuconfig |
...配置内核(同时点击
查看建议设置)
启用Xenomai选项,那么安装需要:
$make bzImage modules $mkdir $build_root && cd $build_root $$xenomai_root/configure --enable-x86-sep $make install |
类似的,对于一个64位平台的传统内核,你将会使用:
$$xenomai_root/scripts/prepare-kernel.sh --arch=x86_64 \ --adeos=$xenomai_root/ksrc/arch/x86/patches/adeos-ipipe-2.6.23-x86_64-X.Y-ZZ.patch \ --linux=$linux_tree $cd $linux_tree $make xconfig/gconfig/menuconfig |
...配置内核(同时点击
查看建议设置)
启用Xenomai选项,那么安装需要:
$make bzImage modules $mkdir $build_root && cd $build_root $$xenomai_root/configure $make install |
一旦编译完成,/usr/xenomai就会包含用你构建调用Xenomai内核空间实时支持的应用程序的用户空间的库和头文件。
剩下的例子说明了怎样为不同的体系结构交叉编译Xenomai。当然,为了构建Xenomai你首先需要为目标系统安装适当的交叉编译工具链。
3.2 PowerPC体系结构下构建
PowerPC有一个传统的arch/ppc分支,和一个新的,当前arch/powerpc树。Xenomai对两者都支持,但是使用arch/powerpc是绝对推荐的。为帮助准备脚本选择正确的一个,你必须指定--arch=powerpc(当前)或--arch=ppc(传统)。接下来的工作就很简单了:
一个典型的交叉编译安装,为了为运行最近2.6.29.4内核的lite5200构建Xenomai,我们使用DENX's ELDK交叉编译器:
$$xenomai_root/scripts/prepare-kernel.sh --arch=powerpc \ --adeos=$xenomai_root/ksrc/arch/powerpc/patches/adeos-ipipe-2.6.29.4-powerpc-2.6-00.patch ←- \ --linux=$linux_tree $cd $linux_tree $make ARCH=powerpc CROSS_COMPILE=ppc_6xx- xconfig/gconfig/menuconfig |
...选择内核和Xenomai选项,保存配置
$make ARCH=powerpc CROSS_COMPILE=ppc_6xx- uImage modules |
...手工安装u-boot镜像和模块到适当的位置
$cd $build_root $$xenomai_root/configure --host=powerpc-unknown-linux-gnu \ CC=ppc_6xx-gcc AR=ppc_6xx-ar LD=ppc_6xx-ld $make DESTDIR=$staging_dir install |
另外一个交叉编译安装,为了为运行最近2.6.29.4内核的powerpc64 PA-Semi板子构建Xenomai:
$$xenomai_root/scripts/prepare-kernel.sh --arch=powerpc \ --adeos=$xenomai_root/ksrc/arch/powerpc/patches/adeos-ipipe-2.6.29.4-powerpc-2.6-00.patch ←- \ --linux=$linux_tree $cd $linux_tree $make ARCH=powerpc CROSS_COMPILE=powerpc64-linux- xconfig/gconfig/menuconfig |
...选择内核和Xenomai选项,保存配置
$make ARCH=powerpc CROSS_COMPILE=powerpc64-linux- |
...手工安装vmlinux镜像和模块到适当的位置
$cd $build_root $$xenomai_root/configure --host=powerpc64-linux \ CC=powerpc64-linux-gcc AR=powerpc64-linux-ar LD=powerpc64-linux-ld $make DESTDIR=$staging_dir install |
另一个交叉编译安装,这次是为一个基于PowerPC-405的运行传统arch/ppc 2.6.14内核的 系统构建Xenomai(我们确实最近也在支持这个平台):
$$xenomai_root/scripts/prepare-kernel.sh --arch=ppc \ --adeos=$xenomai_root/ksrc/arch/powerpc/patches/adeos-ipipe-2.6.14-ppc-1.5-*.patch \ --linux=$linux_tree $mkdir -p $build_root/linux $cd $linux_tree $make ARCH=ppc CROSS_COMPILE=ppc_4xx- O=$build_root/linux xconfig/gconfig/menuconfig |
...选择内核和Xenomai选项,保存配置
$make ARCH=ppc CROSS_COMPILE=ppc_4xx- O=$build_root/linux bzImage modules |
...手动安装内核镜像、系统映射和模块到适当的地方
$make $build_root/xenomai && cd $build_root/xenomai $$xenomai_root/configure --build=i686-pc-linux-gnu --host=ppc-unknown-linux-gnu \ CC=ppc_4xx-gcc LD=ppc_4xx-ld $make DESTDIR=$staging_dir install |
3.3 Blackfin下构建
Blackfin是一个没有MMU,DSP类型的体系结构,运行uClinux。
$ $xenomai_root/scripts/prepare-kernel.sh --arch=blackfin \ --adeos=$xenomai_root/ksrc/arch/blackfin/patches/adeos-ipipe-bf53x-*.patch \ --linux=$linux_tree $ cd $linux_tree $ make ARCH=blackfin CROSS_COMPILE=bfin-uclinux- xconfig/gconfig/menuconfig |
...选择内核和Xenomai选项,接下来编译:
$ cp images/linux /tftpboot/... |
...构建用户空间的支持
$mkdir $build_root && cd $build_root $$xenomai_root/configure --host=blackfin-unknown-linux-gnu \ CC=bfin-linux-uclibc-gcc AR=bfin-linux-uclibc-ar LD=bfin-linux-uclibc-ld $make DESTDIR=$staging_dir install |
要是想看看为Blackfin体系结构配置和构建Xenomai的描述,点击
查看。
注意:
在这个体系架构上Xenomai使用了FDPIC共享库格式。如果在运行测试用例的时候产生问题,请尝试重做最后的两步,并传递--disabled-shared选项给“配置”脚本。
3.4 ARM下构建
使用CodeSourcery的名为arm-none-linux-gnueabi-gcc工具链为CSB637板子(基于AT91RM9200)编译,典型的编译如下:
$$xenomai_root/scripts/prepare-kernel.sh --arch=arm \ --adeos=$xenomai_root/ksrc/arch/arm/patches/adeos-ipipe-2.6.20-arm-* \ --linux=$linux_tree $cd $linux_tree $mkdir -p $build_root/linux $make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- O=$build_root/linux \ csb637_defconfig $make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- O=$build_root/linux \ bzImage modules |
...手动安装内核镜像、系统映射和模块到适当的地方
$mkdir $build_root/xenomai && cd $build_root/xenomai $$xenomai_root/configure CFLAGS="-march=armv4t" LDFLAGS="-march=armv4t" \ --build=i686-pc-linux-gnu --host=arm-none-linux-gnueabi- $make DESTDIR=$staging_dir install |
重要:
与先前的相反,Xenomai无需传递任何arm体系架构下的特定标志,或FPU标志给gcc,所以,用户需要传递上例所表示的CFLAGS和LDFLAGS变量,AT91RM9200是基于ARM920T核心,实现armv4架构。下面的表格总结了CFLAGS和在先前版本中自动传递的但是现在需要显示的去配置的选项,对于支持的片上系统:
SOC | CFLAGS | configure options |
at91rm9200 | -march=armv4t -msoft-float | |
at91sam9x | -march=armv5 -msoft-float | |
imx1 | -march=armv4t -msoft-float | |
imx21 | -march=armv5 -msoft-float | |
imx31 | -march=armv6 -mfpu=vfp | |
imx51/imx53 | -march=armv7-a -mfpu=vfp3 | |
imx6q | -march=armv7-a -mfpu=vfp3 | |
ixp4xx | -march=armv5 -msoft-float | --enable-arm-tsc=ixp4xx |
omap3 | -march=armv7-a -mfpu=vfp3 | |
omap4 | -march=armv7-a -mfpu=vfp3 | |
orion | -march=armv5 -mfpu=vfp | |
pxa | -march=armv5 -msoft-float | |
pxa3xx | -march=armv5 -msoft-float | --enable-arm-quirks=xscale3 |
s3c24xx | -march=armv4t -msoft-float | |
sa1100 | -march=armv4t -msoft-float | --enable-arm-quirks=sa1100 |
为一个老的体系架构版本构建是可能的(v6替代v7,或者v4替代v5),如果你的工具链不支持目标体系架构,唯一的限制在是否启用了SMP,体系架构不能小于v6。
4 安装测试
4.1 测试内核
为了测试Xenomai的安装,首先你要尝试启动打过补丁的内核。内核启动信息必须打印如下信息:
I-pipe: head domain Xenomai registered. Xenomai: hal/<arch> started. Xenomai: scheduling class idle registered. Xenomai: scheduling class rt registered. Xenomai: real-time nucleus v2.6.1 (Light Years Away) loaded. Xenomai: debug mode enabled. Xenomai: starting native API services. Xenomai: starting POSIX services. Xenomai: starting RTDM services. |
<arch>是你使用的体系架构。如果内核启动失败或者日志信息暗示了一个错误状状态,请看故障检测指南。
4.2 测试用户空间支持
为了测试Xenomai用户空间的支持,启动延迟测试:
延迟测试应该每秒显示最小、最大和平均延迟值的信息,例如:
#
xeno latency -T 25
== Sampling period: 100 us
== Test mode: periodic user-mode task
== All results in microseconds
warming up...
RTT| 00:00:01 (periodic user-mode task, 100 us period, priority 99)
RTH|----lat min|----lat avg|----lat max|-overrun|---msw|---lat best|--lat worst
RTD| 1.615| 1.923| 9.846| 0| 0| 1.615| 9.846
RTD| 1.615| 1.923| 9.692| 0| 0| 1.615| 9.846
RTD| 1.538| 1.923| 10.230| 0| 0| 1.538| 10.230
RTD| 1.615| 1.923| 10.384| 0| 0| 1.538| 10.384
RTD| 1.615| 1.923| 11.230| 0| 0| 1.538| 11.230
RTD| 1.615| 1.923| 9.923| 0| 0| 1.538| 11.230
RTD| 1.615| 1.923| 9.923| 0| 0| 1.538| 11.230
RTD| 1.615| 1.923| 11.076| 0| 0| 1.538| 11.230
RTD| 1.615| 1.923| 10.538| 0| 0| 1.538| 11.230
RTD| 1.615| 1.923| 11.076| 0| 0| 1.538| 11.230
RTD| 1.615| 1.923| 10.615| 0| 0| 1.538| 11.230
RTD| 1.615| 1.923| 10.076| 0| 0| 1.538| 11.230
RTD| 1.615| 1.923| 9.923| 0| 0| 1.538| 11.230
RTD| 1.538| 1.923| 10.538| 0| 0| 1.538| 11.230
RTD| 1.615| 1.923| 10.923| 0| 0| 1.538| 11.230
RTD| 1.538| 1.923| 10.153| 0| 0| 1.538| 11.230
RTD| 1.615| 1.923| 9.615| 0| 0| 1.538| 11.230
RTD| 1.615| 1.923| 10.769| 0| 0| 1.538| 11.230
RTD| 1.615| 1.923| 9.153| 0| 0| 1.538| 11.230
RTD| 1.538| 1.923| 10.307| 0| 0| 1.538| 11.230
RTD| 1.615| 1.923| 9.538| 0| 0| 1.538| 11.230
RTT| 00:00:22 (periodic user-mode task, 100 us period, priority 99)
RTH|----lat min|----lat avg|----lat max|-overrun|---msw|---lat best|--lat worst
RTD| 1.615| 1.923| 11.384| 0| 0| 1.538| 11.384
RTD| 1.615| 1.923| 10.076| 0| 0| 1.538| 11.384
RTD| 1.538| 1.923| 9.538| 0| 0| 1.538| 11.384
-----|-------------|-----------|-------------|-----------|--------|-------------------------
RTS| 1.538| 1.923| 11.384| 0| 0| 00:00:25/00:00:25
#
如果延迟测试显示错误信息、卡死或者显示非期望的值,请查看故障检测指南。如果延迟测试成功,你应该尝试在有负载的情况下运行一个延迟测试来测试你的系统,xeno-test脚本允许你这么做。更多信息请查阅xeno-test(1)手册。