Xenomai实现RTOS(1)Ubuntu20.04下,Xenomai3.2.1+Linux5.10.76安装

最后更新于2021年12月23日 10:21:40

写在前面:我这不会是全网首发吧,吐了,搞的跟营销号一样。

CPU:Intel® Core™ i7-10700 CPU @ 2.90GHz
虚拟机:Ubuntu20.04用作内核替换,18.04用作编译

下载源码,打好patch

下载一个Xenomai3.2.1的源码包:下载地址。我就直接把源码包解压在Download/目录下了。
我使用的是Ubuntu20.04.2,cat /proc/version_signature查看当前的内核版本。我现在的内核版本是5.11.0-40.44~20.04.2-generic,mainline base的版本号是5.11.22。
Xenomai需要添加一个i-pipe层到内核中(一个特殊的内核补丁,可以对外部中断提供快速和确定的响应时间,还有与标准Linux内核无缝集成的服务??根据官网资料翻译来的,半通不通的看不懂。)
目前的i-pipe对内核的支持只到Linux 5.4,5.10开始就要用到dovetail这个patch了。

失败尝试第一次:下载一个Ubuntu Linux kernel source tree(方便起见我下的跟现在内核一样版本号的源码)。下载链接 三个东西tar.gz, diff.gz, .dsc放在一个文件夹里,用 dpkg-source -x *.dsc命令解压。从dovetail下载网站下一个对应版本的patch,放在解压好的内核源码文件夹里面。打补丁!发生错误!放弃!

失败尝试第二次:那就换个Linux 5.10.46加上patch-5.10.46-dovetail1.patch,这个组合好使,能打上patch但是后面编译出现巨大未知问题!放弃!

失败尝试第三次:那就换原生的Linux 5.10.46内核,这个总是好使的吧。同样的问题,放弃!
导入内核命令(先cd到内核源码根目录下):~/Downloads/xenomai-v3.2.1/scripts/prepare-kernel.sh --arch=x86_64 --dovetail=patch-5.10.46-dovetail1.patch

失败尝试第四次:下载官方做好的内核源码(地址在这里)这再编译报错我就一刀砍下Xenomai官方的狗头。全版本号为linux-dovetail-v5.10.76-dovetail3
和前两次一样的错误,找不到udp_sock。
导入内核命令:~/Downloads/xenomai-v3.2.1/scripts/prepare-kernel.sh --arch=x86_64

成功尝试:退版本。到Ubuntu18.04运行试试。
sudo apt-get install flex bison
导入内核命令:~/Downloads/xenomai-v3.2.1/scripts/prepare-kernel.sh --arch=x86_64
其实以上的第二三四次错误尝试都不是内核源码的问题,只不过是我没在18.04下编译而已。我的18.04默认的是GCC 7.5.0版本,所以说不知道是Ubuntu还是GCC的问题。

menuconfig

使用make menuconfig来配置kernel configurations。某些kernel配置有互相依赖的情况,按顺序取消吧,善用键盘上的/键进行搜索。如果缺少flex和另一个库,用apt install安上就行。

这段可以不看
官网上重点提到的,需要取消的CONFIG(按顺序取消):
CONFIG_APM这个一般来说就是默认取消的(Advanced Power Management)
CONFIG_SCHED_MC
CONFIG_CPU_FREQ
CONFIG_ACPI_PROCESSOR
CONFIG_CPU_IDLE

好多中文的Xenomai安装资料都会提到下面这一大段,这应该是下面配置的来源吧,没人问过为什么要这么配置

Recommended options:
#在来源的基础上我增减了一些自己的配置内容和解释。
* General setup
  --> Local version - append to kernel release: -jiayu
  # `uname -a`会额外显示的自定义文本,写什么无所谓吧。
  --> Timers subsystem
      --> High Resolution Timer Support (Enable)
* Pocessor type and features
  --> Multi-core scheduler support (Disable)
  --> Processor family
      --> Core 2/newer Xeon (if "cat /proc/cpuinfo | grep family" returns 6, set as Generic otherwise)
      # 上述命令返回6,选择Core 2/newer Xeon,否则一概选择Generic。
  --> SGI Ultraviolet (Disable) 
  # make编译时报错了,参见https://www.mail-archive.com/[email protected]/msg21300.html
* Xenomai/cobalt
  --> Sizes and static limits 
    --> Number of registry slots (512)
    # The Xenomai kernel runs the size of the kernel resource object storage tank, 
	# which is used to allocate the maximum size of the system, such as signals, mutex (MUTEX), semaphore. 
	# 看起来是一个存储信号量的内存池???
    --> Size of system heap (Kb) (4096) #默认就是
    --> Size of private heap (Kb) (256) #默认就是
    --> Size of shared heap (Kb) (256) #默认就是
    --> Maximum number of POSIX timers per process (256)
  --> Drivers
    --> RTnet
    # RTnet 允许在实时环境下严格限制收发信息,这里我暂时没有配置。
        --> RTnet, TCP/IP socket interface (Enable)
            --> Drivers
                --> New intel(R) PRO/1000 PCIe (Enable)
                --> Realtek 8169 (Enable)
                --> Loopback (Enable)
        --> Add-Ons
            --> Real-Time Capturing Support (Enable)
* Power management and ACPI options
  # 和官网内容相同。
  --> CPU Frequency scaling
      --> CPU Frequency scaling (Disable)
  --> ACPI (Advanced Configuration and Power Interface) Support
      --> Processor (Disable)
  --> CPU Idle
      --> CPU idle PM support (Disable)
* Memory Management Options
# Xenomai will issue a warning about CONFIG_MIGRATION, disable those in this order
  --> Transparent Hugepage Support (Disable) 
  # 禁用透明大页,减小内存读取开销。
  --> Allow for memory compaction (Disable)
  # 允许对大内存页(huge pages)进行压缩.主要是为了解决大内存页的碎片问题。
  #	建议在使用大内存页的情况下开启此项,否则建议关闭。
  # 今天在《现代操作系统》这本书中看到了这项技术,学名应为“内存紧缩”。
  # 由于内存与硬盘的进程交换,会在内存中产生小的没有数据的空洞。
  # 这项技术是通过把所有进程向下移动,将小的空闲区合成一大块空闲内存
  --> Contiguous Memory Allocator (Disable)
  --> Page Migration (Disable)
  # 允许在保持虚拟内存页地址不变的情况下移动其所对应的物理内存页的位置。
  # 这主要是为了解决两个问题:(1)在NUMA系统上,将物理内存转移到相应的节点上,
  # 以加快CPU与内存之间的访问速度.(2)在分配大内存页的时候,可以避免碎片问题。
* Device Drivers
   --> Unisys visorbus driver (Disable) 

编译内核映像、模组

配置好之后保存为.config文件,然后使用make -j4 bzImage开始编译内核镜像,编译时会报错:make[1]: *** No rule to make target 'debian/canonical-certs.pem', needed by 'certs/x509_certificate_list'. Stop.
这问题确实比较迷。我现在的解决办法是comment掉.config文件里面的CONFIG_SYSTEM_TRUSTED_KEYS="debian/canonical-certs.pem"这一句。然后在使用make -j4 bzImage命令的时候他就会让你输入这个字段,直接敲回车给它置为空。

我感觉在menuconfig的这个位置改应该是一样的呀:

* Cryptographic API
  --> Certificates for signature checking
  	   --> Additional X.509 keys for default system keyring (debian/canonical-certs.pem --> #清空,啥也不写)

但是好像就是不对,很奇怪。。。
其实之前我一共输入了好几条命令:
scripts/config --disable SYSTEM_TRUSTED_KEYS
scripts/config --set-str SYSTEM_TRUSTED_KEYS “”
#还有把.config文件里面的两处config改成如下样子:
CONFIG_SYSTEM_TRUSTED_KEYS=""
CONFIG_SYSTEM_REVOCATION_KEYS=""
这些玩意儿不知道哪个导致后面module install出错了。

完成后输入以下命令:

make -j4 bzImage
#静静等待编译结束
make modules
#静静静静等待编译结束
make modules_install INSTALL_MOD_PATH=/home/jiayu/
#安装驱动模组到自己选定的目录

安装

我的内核源码文件夹名为linux-dovetail-v5.10.76-dovetail3
linux-dovetail-v5.10.76-dovetail3/.config 拷贝到目标机器的/home/boot下,并重命名为config-5.10.76-jiayu(后缀跟生成的/lib/modules/linux-5.10.76-jiayu文件夹的后缀相同就行)
linux-dovetail-v5.10.76/arch/x86-64/boot/bzImage 拷贝到要替换内核系统的/boot下,并重命名为vmlinuz-5.10.76-jiayu
将生成的linux-dovetail-v5.10.76/System.map 拷贝到要替换内核系统的/boot下,并重命名为System.map-5.10.76-jiayu
将make modules_install生成的系统目录/lib/modules/linux-5.10.76-jiayu 拷贝到要替换内核系统的/lib/modules下。
在要替换新内核的系统的/lib/modules目录下执行以下命令:

update-initramfs -c -k5.10.76-jiayu # 生成/boot/initrd.img-5.10.76-jiayu

由于我原来安装的是5.11版本,现在改成了5.10,相当于退了版本,需要修改/etc/default/grub文件中的一句:

GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 5.10.76-jiayu"

然后输入:

update-grub
update-grub2
# 都输入一下吧,省心

最后reboot电脑,就行了。
重启后用uname -a查看版本号是不是变了,然后:

$ dmesg | grep -i xenomai
[    3.503884] [Xenomai] scheduling class idle registered.
[    3.503884] [Xenomai] scheduling class rt registered.
[    3.504826] IRQ pipeline: high-priority Xenomai stage added.
[    3.506186] [Xenomai] Cobalt v3.2.1 [LTRACE]

输出是大概这样式儿的就行了。

安装库

前面下载好的源码包里面没有configure脚本和makefile,需要手动生成,在源码根目录下使用./scripts/bootstrap命令。
然后使用以下命令进行配置:

./configure --with-pic --with-core=cobalt --enable-smp --disable-tls --enable-dlopen-libs --disable-clock-monotonic-raw
# 参数解释:位置无关代码、使用cobalt微内核、对称多处理、线程本地存储、动态加载基于Xenomai的库、使用单调递增时间来计时
make
sudo make install

就行了,开始测试!

sudo /usr/xenomai/bin/latency
== 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|     -0.898|     17.767|   2987.899|     315|     0|     -0.898|   2987.899
RTD|     -0.474|     23.186|    517.607|    1161|     0|     -0.898|   2987.899
RTD|     -0.791|     20.259|    502.317|    1735|     0|     -0.898|   2987.899
RTD|     -0.990|     20.669|    542.073|    2379|     0|     -0.990|   2987.899
RTD|     -0.397|     17.620|    515.873|    2696|     0|     -0.990|   2987.899
RTD|      0.137|     21.552|    497.643|    3416|     0|     -0.990|   2987.899
RTD|     -0.331|     20.812|    497.061|    4018|     0|     -0.990|   2987.899
RTD|     -1.103|     20.868|    506.101|    4620|     0|     -1.103|   2987.899
RTD|     -0.475|     18.350|    504.543|    4981|     0|     -1.103|   2987.899
^C---|-----------|-----------|-----------|--------|------|-------------------------
RTS|     -1.103|     20.120|   2987.899|    4981|     0|    00:00:10/00:00:10

大概就是这个样子,但是我是用的虚拟机,latency不知道抖到哪里去了,看个乐就好,流程是没问题的。做到这步,就算安完啦!有bug什么的请看官方文档,我这里管杀不管埋。。。

后续文章

没想到有需求,要在ARM64的板子上面加装Xenomai一个试试,我对嵌入式就更不精通了。那就写个小系列,慢慢探索吧!

其他奇怪问题

编译这一步如果用Ubuntu20.04,会出现非常恶心的问题,几乎把人逼疯:
问题1:

FAILED unresolved symbol udp_sock
make: *** [Makefile:1205: vmlinux] Error 255

这个问题只要打上Dovetail的patch就出现了,完全没有修改menuconfig也会出现该问题,不清楚成因。
完完全全是看不懂的未知错误,Ubuntu内核还是Linux原生内核都一样,网上也找不到相关的资料,直接给Xenomai项目组发邮件了,希望能有回音。
过了几个小时了还没有回音,美国人真恶心啊,他们就不能半夜从床上爬起来看一眼邮件吗?
退版本到18.04了,解决了,原理不清楚。
18使用的gcc版本是7.5.0,20使用的版本是9.4.0。不知道是gcc问题还是Ubuntu问题。

问题2:
在给Linux4.x打ipipe补丁时,CONFIG_HYPERV可能与CONFIG_IPIPE冲突,导致编译报错implicit declaration of function ‘arch_mangle_irq_bits’等等一大堆,关闭即可。

* Device Drivers
  --> Microsoft Hyper-V guest support
      --> Microsoft Hyper-V client drivers (Disable)

问题3:
x86_64架构下,Ubuntu16.04 添加 Linux 4.19.207时出现的:

[Xenomai] SMI-enabled chipset found, but SMI workaround disabled
		  (see xenomai.smi parameter). You might encounter

见官方文档:Dealing_With_X86_SMI_Troubles

参考资料:

linux4.9.90+xenomai3.0.9安装教程
实时xenomai3.0.5/3.0.9+linux4.9.38/4.9.90简要配置及BUG大记实
Linux内核编译配置选项简介
Xenomai kernel analysis - real-time memory management - xnheap
Linux传统Huge Pages与Transparent Huge Pages再次学习总结
Linux内核配置选项简介(5)
Installing_Xenomai_3
Index of /downloads/
Configuring_For_X86_Based_Dual_Kernels
How do I get the kernel source code?
How to compile and install Linux Kernel 5.6.9 from source code
linux系统替换新内核(编译安装替换与打包替换) 我是非本机编译的,按照这个博客替换的内核。

你可能感兴趣的:(RTOS开发,linux,Xenomai)