前言
Intel ECI是一个用于工业领域边缘控制的软硬件平台,我们今天主要探索的是软件部分,也就是系统镜像。区别于传统的Ubuntu或者Debian,ECI的强大之处在于它的实时性以及对于Intel自家芯片的缓存优化能力极强。
那么让我们来探索一下
编译/安装ECI
BIOS的设置可以参考
Appendix — ECI documentation (intel.com)
然后进入主题,我们来编译和安装ECI Core-Jammy
Get Started — ECI documentation (intel.com)
当然啊,可能会对ECI这个介绍感到眼花缭乱,不知道从哪里下手,其实很简单,只要申请一个账号,然后下载ECI的Release Archive就可以。当然对于系统的要求还是存在的,我们需要用Ubuntu22.04这个环境去编译它的Core-Jammy或者Core-bullseye的系统镜像,因为它采用的方式和Yocto是一样的,都需要bitbake的方式去编译,当然也要连接外网,不然很多github的链接都会挂了。
Download ECI — ECI documentation (intel.com)
然后我们就可以按照网页给出的方式去构建Intel的ECI,这里推荐选择上面的三个,当然都是没有桌面环境的,如果有需要可以自己在后续的环境中安装
apt-get install lightdm以及apt-get install lightdm xfce4
Build ECI — ECI documentation (intel.com)
这里倒是没有什么难点,主要是网络的问题,编译完后可以按照文档的提示去制作启动U盘。这里倒是吐槽一下,Intel这个做的链接有点不好找。Install Debian-based ECI Images (Generic) — ECI documentation (intel.com)
ECI上手
安装到对应的机子上以后我们就可以进去系统查看了,
默认的用户名和密码都是eci-user,对应的最高权限的用户名和密码都是root
我们可以用cyclictest去做一下实时性的测试,在没有用stress-ng去加压的情况下,intel i7-12700上采用ECI-Core-Jammy的最大时延48h差不多在20个us左右
cyclictest --smp --mlockall --priority=99 --policy=fifo --interval=1000 --histogram=400 --secaligned=50 --duration=10m
当然啊,Intel也是推荐我们把所有和实时性相关的任务都放到隔离核上去运行,所以我们也可以设置一下隔离核,这样实时性还会提高不少。相关的可以参考一下这个文档啊
Appendix — ECI documentation (intel.com)
对应修改/etc/default/default里面的内核参数,需要注意的是,修改完之后我们对CPU的核进行了隔离,所以不能再用--smp的这种方式去运行cyclictest了,因为--smp无法在被隔离的核上去调用。所以会影响实时性的效果。这里我们隔离了CPU1-CPU8。
# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
# info -f grub -n 'Simple configuration'
GRUB_DEFAULT=0
#GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=3
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash nohpet no_timer_check ignore_loglevel log_buf_len=16M consoleblank=0 console=hcv0 i915.nuclear_pagefilp=1 i915.avail_planes_per_pipe=0x070F00 x2apic_phys mce=ignore_ce idle=poll isolcpus=nohz,domain,1-8, rcu_nocbs=1-8, nohz_full=1-8"
GRUB_CMDLINE_LINUX=""
# Uncomment to enable BadRAM filtering, modify to suit your needs
# This works with Linux (no patch required) and with any kernel that obtains
# the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)
#GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef"
# Uncomment to disable graphical terminal (grub-pc only)
#GRUB_TERMINAL=console
# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command `vbeinfo'
#GRUB_GFXMODE=640x480
# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux
#GRUB_DISABLE_LINUX_UUID=true
# Uncomment to disable generation of recovery mode menu entries
#GRUB_DISABLE_RECOVERY="true"
# Uncomment to get a beep at grub start
#GRUB_INIT_TUNE="480 440 1"
可以看到啊,如果还用之前的--smp去跑,时延一下子就破12了,这是因为cpu1-cpu8其实都没有跑任务,因为他们被隔离了,这样所有的12个线程就会被分配到cpu0和剩下的cpu9-11去跑,因此这个测试的结果其实不太好。(本来--smp的意思就是每一个核心上去运行一个线程,但是cpu1-cpu8被隔离了,所以这个线程就没法去加载到cpu1-cpu8,从而都加载到别的cpu上了)
那么我们可以针对CPU1-CPU8里的任意一个CPU去做测试,比如我们指定-a 1-8表示将程序绑定到cpu1至cpu8去运行测试。
通过taskset -p -c <PID>可以查看到这个程序运行在哪个cpu核心上
通过这种方式,可以看到,基本上在48H测试的结果上来说,测试了几次最大时延基本在10-16us之间。
自定义内核参数
当然ECI也提供了让我们去自定义修改内核参数的方法,可以参考ECI的链接
Configure and Build Linux Kernel — ECI documentation (intel.com)
链接里提供了两种方式:
第一种就是根据我们编译ECI的环境,去进行kernel的修改。这里只有一个地方要注意,当我们选择manual build的时候,下面会给出几行命令,我们需要修改一下KAS的那行,把build targets/xxx 改成shell targets/xxx 就可以进入bitbake,然后在按照上面链接里的方式去编译即可。最后生成deb文件,拷贝到目标系统里 用dpkg -i 去安装就可以了。
第二种是在已经运行ECI的目标机器上去编译内核
这里有一个要注意的地方Step3这里有坑,我们要把这个patchset的文件夹拷贝一份到build-full这个目录里面,然后去做对应的tar zxf /proc xxxxx这部操作,否则在编译的时候会提示找不到patcheset文件夹。
还有一个地方要注意,Step5里这个dir是错的,其实真正要进的目录就是我们编译的这个目录,比如linux-intel-lts-lts-v5.15.113-rt64-preempt-rt-230530T192215Z这个目录
编译完以后它会自动安装上,我们直接重启系统就可以了,两种方法都很方便,当然我比较推荐第一种,因为第二种要在ECI的目标机器上安装很多依赖库。。会整的我们的目标机器变得更庞大。因为作为工业机器,我们希望越简单越好。