我们知道yocto可以用于操作系统版本构建,它与openembedded相辅相成。
而我们的工作内容中,我们是通过livebuild(u系系统)的方式构建的操作系统。这种方式是预先通过服务器进行预编译的二进制,我们通过livebuild工具执行一次构建操作,从而生成一个操作系统版本,这个优点是操作系统构建速度快,缺点是系统无法进行良好的定制扩展。
对于上述的问题,我们知道,对于livebuild的缺点,我们无法解决,因为软件的定制扩展需要依赖服务器的二进制发布,而针对yocto的缺点,我们可以解决,我们可以让yocto在构建系统的过程中,可选择性的执行全量编译,或部分编译,甚至进二进制构建的行为。
Yocto Project 是一个开源协作项目,可帮助开发人员为嵌入式产品和其他目标环境创建基于 Linux 的自定义系统,而不管硬件架构如何。该项目提供了一套灵活的工具和空间,世界各地的嵌入式开发人员可以在其中共享技术、软件堆栈、配置和最佳实践,这些技术、软件堆栈、配置和最佳实践可用于为嵌入式设备创建定制的 Linux 和 RTOS 映像
https://www.yoctoproject.org/development/technical-overview/
根据上面我们可以知道,yocto是一个可以创建基于Linux的自定义系统的工具,如果我们掌握yocto工具,那么可以为其他目标环境创建一个自定义的操作系统。
我们已经知道yocto是一套工具,它可以创建操作系统,那我们为什么要用yocto,而不去选择其他的系统构建工具呢,这里以livebuild为例,详细解释主要原因
对于yocto,它是基于源码构建操作系统的方式,如果系统中存在某个软件包需要根据实际情况定制修改,其步骤相比于livebuild更方便,如下:
对于livebuild:
在服务器上下载软件的源码 修改源码 编译源码生成二进制deb包 推送到二进制发布平台上 重新执行livebuild构建,形成新的操作系统
对于yocto:
修改源码,提供修改源码的patch文件 修改bb file,将patch文件通过quilt方式合入源码 执行recipes的编译 执行images的构建,形成新的操作系统
根据上面我们可以知道,对于livebuild,我们需要有专门的编译服务器,需要将编译的二进制包推送到发布平台,再通过livebuild脚本来执行构建,需要依赖的东西多,步骤复杂
而对于yocto,我们仅仅需要针对代码的patch,修改bb file,添加补丁,然后执行构建即可,在其规则内,简单方便即可完成定制需求
对于yocto,不同的bb file可以通过append方式修改和定制,不同的版本可以通过设置不同的layer实现,也就意味着基于yocto的构建版本,可以很好的处理多版本的现状,而livebuild很难做到,如下:
对于livebuild:
不同的定制版本需要上传到不同的二进制发布平台上 修改livebuild脚本,针对不同的版本设置不同的hook脚本,用于构建不同的版本 根据livebuild脚本构建操作系统镜像
对于yocto:
设置不同的meta-projectname的layer 构建不同的layer的操作系统镜像
根据上面我们可以知道,对于livebuild,如果定制版本特别多
例如上百量级,那么我们不同的二进制包需要上百个,二进制发布平台的源地址需要上百个,维护的hook脚本也有上百个
而yocto不同的是,我们所有的改动都放在一个layer中,那么我们只需要上百个layer即可。对应改动在layer上,而且yocto的layer之间可以实现overlay
也就意味着,我们不需要发布上百个二进制或源码配置,而仅仅是在原来的layer上做overlay,实现差分内容管理即可。
关于此概念,其实是构建系统的两个思路,如下解释:
根据这里,我们可以发现,正常情况下,如果我们的操作系统功能涵盖了一切,对于其用户需求而言,仅需要增加和减少两个功能,那么自顶向下的的方法并没有问题。所以它比较适用于例如服务器(对操作系统功能越丰富越好,性能问题无需格外关心),桌面(提供一个基本操作系统环境,用户通过安装包来提供新的功能)
但是它不适用于嵌入式,通常情况下,嵌入式是一个定制性非常强的系统,例如车机系统,机器人系统,工业控制系统等。每个系统的定制功能不同,但整体性能有限,所以无法安装服务器的版本(性能和空间受限),也无法使用桌面版本(操作系统环境无法定制)。
这里,livebuild是一种减法类操作系统构建工具,而yocto默认是一种加法类操作系统构建工具。
但是不一样的是:
所以我们可以发现,yocto比livebuild更优。
我们知道livebuild十分依赖本机环境,即使我们通过chroot进入一个新的环境,我们也是在chroot环境中进行构建版本,它没办法跨平台,例如在x86上构建arm64的操作系统。
当然,我们可以通过qemu static来实现跨平台的构建方式,但它并不友好。
yocto与其不同的是,yocto可以配置不同的平台层,使用不同的cross compile工具,使其能够从源码上构建不同平台的二进制软件
当然,yocto也可以通过qemu static来实现跨平台的二进制安装。
根据上述,我们可以知道,对于操作系统的二进制加减法,我们都可以通过qemu static工具实现,但是对于源码定制和构建,只有yocto能够做到。
放大了看,对于整个操作系统的构建行为,livebuild严格意义上是无法完成的,而yocto本身可以轻松的完成跨平台的构建系统版本,包括但不局限于如下:
x86 windows/linux 上构建 arm64 loongarch64 risc5-64 arm64 linux上构建x86-64 loongarch64 risc5-64 loongarch64 linux上构建 arm64 x86-64 risc5-64 risc5-64 linux上构建 arm64 x86-64 loongarch64
虽然我们通常是x64上构建其他平台,但是也足够说明了yocto可以做到其livebuild无法做到的事。
针对我们的行业,我们可以知道,我们主要提供操作系统的定制方案,我们已经获取了发布的操作系统版本。我们需要做的是,将这些操作系统版本应用到我们的行业场景上去。
假设我们是自顶向下的减法,定制操作系统版本,那么我们根据我们的各种行业,需要提供基于v10的各种版本。那么就会出现如下问题:
操作系统都叫V10,但是版本参差不齐,版本的数量太多,版本之间差异过多,但不清楚差异在哪,兼容困难 版本与版本之间都是通过kybuilder平台定制修改的,但是并没有直接明了的知道版本间的差异。
我们可能在某个行业,例如车载上有100个项目,那么这100个项目都集成某个基于车载的版本,最后衍生了100个项目版本。这100个项目版本均有差异。
操作系统都是车载V10版本,但是每个车载V10版本都不一样,只知道有100个车载项目版本要维护,但理不清楚每个车载版本的差异点 我们找不到这100个项目的差异,我们需要为这100个项目版本做好维护工作,而不是维护一个yocto配置这种行为。
统一的操作系统
yocto可以定义每个meta layer,我们可以根据行业来设置layer,不同的场景客户都基于原始v10版本上,新增layer。
这样,不同的layer中就是不同场景的定制功能需求,这些layer里面是各种功能的bb 文件
yocto可以为不同的项目设置项目的layer,然后项目的改动通过设置bbappend实现。bbappend可以针对原来的行业的layer上进行追加修改和定制。例如:
meta-vehicle-project/recipes-xxx/xxx_0.1/xxx.bbappend
这里xxx是具体功能,bbappend是对原meta-vehicle的定制追加
yocto可以统一拉取操作系统源码或二进制,统一输出镜像,能够使得成为真正意义上的全场景OS。
至此,我们的版本基于v10,提供了yocto的工程,根据此工程构建的版本都是基于v10,其他的衍生版本通过bb 和 bbappend实现。
如果客户拿到了我们的yocto仓库,客户不会认为我们存在100个不同的版本,而是1个统一的yocto版本,通过灵活构建生成了100个行业场景。