Yocto学习笔记

一、Yocto介绍

1、什么是Linux构建系统

在这里插入图片描述

2、Yocto Project是什么

yocto Project参考Gentoo Linux的eBuild构建系统设计(从Portage派生而来,Portage包含两个组件:ebuild和emerge),目的为构建定制化的嵌入式Linux发行版提供一系列模板、工具和方法。

BitBake使用和Portage构建脚本相同的元数据语法,但是引入了新
的特性,例如由类提供的继承机制、追加(appending)菜谱和全局配置
文件等。

yocto :基于python的方言 bitcake 以此之上构建生态。

在这里插入图片描述
buildroot适合简单的基本验证,如果要做复杂的发行版 支持不同的场景使用yocto。
yocto的缺点就是太过于灵活,一个实现方式可以有不同的写法,无一个规范的操作。

3、Yocto Project组成

在这里插入图片描述
在这里插入图片描述

OpenEmbedded和yocto 相关于孪生兄弟的关系,分不开。

yocto将其中的前两个OpenEmbedded Core和BitBake拿过来和POKY组成发行版

基于POKY衍生出右边的外围的东西

4、Yocto的基本流程

在这里插入图片描述
Source Materials像做菜一样 ,将各种原材料准备好
灰色部分就像你如何去做,基本的配方

中间蓝色部分就相当于厨房去做了,
Source Fetching:拉取软件包或者自己下载下来解压
Patch Application:为某些软件打上补丁
Config/Compile/Autoconf as need:为所有的菜装盘
可以构建后面三种形式软件包
QA Tests:测试软件包是否合适

Pakeage Feeds:买现成的东西回来热一下就行,相当于将别人已经编译好的代码仓库直接拿过来生成image和SDK。
在这里插入图片描述

5、初识Bitbake

5.1 bitbake是什么?

bitbake是一个灵活强大的构建引擎,基于python之上构建的语言
在这里插入图片描述
bitbake最后将构建的matadata,将python或shell写的脚本,决定哪些先执行,哪些后执行.

5.2 构建元数据

有了bitbake的核心机制后,就需要准备元数据
在这里插入图片描述
下面红色的三个是全局的配置,
上的Layer相当于不同的菜系,layer里面的conf相当于有哪些菜,最重要的是recipe(软件包配方)

5.3 bitback中的基于task的执行流

bitback最核心的还是基于task确定如何去做,基本的bb文件的执行流如下:
在这里插入图片描述

6、POKY

在这里插入图片描述

二、Bitbake

2.1 bitbake构建系统

Yocto项目中,采用的是BitBake工具来构建嵌入式Linux系统的。通过repo获取了Yocto项目的同时,也一起获取BitBake工具,直接使用即可。使用BitBake的最主要目的是生成一些安装包、内核、SDK以及一个完整的嵌入式Linux发行版(包括:U-Boot、Kernel、Rootfs、DeviceTree),这些安装包或目标文件就构成了一个完成的嵌入式Linux发行版 。

BitBake命令格式为:bitbake target
其中Freescale为imx6ull提供了几个target镜像文件,可供选择,需要注意的是,镜像文件支持的功能越多,(根)文件系统就越大:
在这里插入图片描述
在软件包的source目录下面可以找到这些bb文件。
在这里插入图片描述
实际上,在软件包的build目录下通过运行bitbake imx-image-multimedia命令,bitbake会找到/sources/meta-imx/meta-sdk/recipes-fsl/images路径下的imx-image-multimedia.bb文件,根据imx-image-multimedia.bb文件中的配置进行系统的构建。同时,在/sources/meta-imx/meta-sdk/recipes-fsl/images路径下还可以看到fsl-image-core.bb等文件,与上表中提到的镜像文件相对应。运行bitbake imx-image-multimedia命令后,就开始使用bitbake工具构建嵌入式Linux系统。

等待下载需要的软件包:
在这里插入图片描述

系统构建完成后,在包的build目录fsl-release-yocto/build/tmp/deploy/images/imx6ull14x14evk路径下输出manifest文件, 这个文件里包含了对应文件系统中已安装的软件包。同时,该路径下,还生成了一些其他文件:
在这里插入图片描述

2.2 bitbake构建系统解析

BitBake工具最主要的目的是编译生成相应的软件安装包、内核镜像文件、SDK或者用来构建嵌入式Linux发行版(Linux内核、BootLoader、根文件系统)。当然,也可以用于编译单个的recipe文件,实现获取、清除数据等。通过命令: bitbake target(例如:bitbake fsl-image-qt5)即可启动BitBake构建系统过程。

1. 解析Metadata基本配置

BitBake构建的第一步是解析Metedata基本配置文件,这些基本配置文件确定了所构建嵌入式Linux系统发行版的一些功能及特征。在了解解析Metadata基本配置之前,需要先了解几个概念。

元数据

Yocto由一些Metadata组成,具体来说,通过repo获取Yocto项目后,在source目录下有一些文件夹,这些文件夹就是一个个的metadata。如下图所示,在这些文件夹中包含了许多的文件,用于构建嵌入式Linux系统。
在这里插入图片描述
在sources目录下有一些meta开头的meta-xxx文件夹,但是,针对不同的嵌入式Linux发行版的需求,需要使用不同的metadata,有可能需要增加新的metadata,也有可能减少一些metadata。对于使用哪些metadata(meta-xxx文件夹)是由在通过imx-setup-release.sh脚本初始化构建目录时确定的。

在使用imx-setup-release.sh脚本时,会创建一个build文件夹,在build/conf路径下,生成了一个bblayers.conf的配置文件,BitBake工具会根据该bblayers.conf文件中的定义,确定使用那些metadata用于构建嵌入式Linux发行版。

如下图中所示,bblayers.conf中的变量bbLAYERS的值定义了哪些metadata参与构建系统。
在这里插入图片描述

2. meta-xxx文件中(recipes、conf、classes)

在Metadata中,有许多文件存放于source/meta-xxx文件夹下,用于构建嵌入式Linux系统发行版。
在这里插入图片描述

  • class:该文件夹下的.bbclass文件,包含了一些在不同的metadata之间共享的信息,以及编译信息的抽象,例如:如何编译Linux内核。

    在这里插入图片描述

  • conf:该conf文件夹下的layer.conf文件定义了该metadata中使用那些.bb、.bbappend文件等参与构建嵌入式Linux系统

  • recipes-xxx:该文件夹中有许多的.bb或.bbappend文件,这些文件定义了构建嵌入式Linux系统需要的软件包或源码等,主要包括:

    软件包的基本信息:作者、主页、License等
    版本信息
    依赖文件
    从哪下载以及如何下载软件包
    软件包补丁信息:是否需要补丁、补丁下载地址及方式等
    如何配置、如何编译软件包、安装位置等
    在这里插入图片描述

总的来说,解析Metadata的过程就是:
BitBake根据build/conf/bblayers.conf中定义的所使能的layers(meta-xxx),找到对应meta-xxx文件夹下的layer.conf文件,根据layer.conf文件中所使用的.bb或.bbappend文件中定义的软件包或源码的下载、配置、编译方式、安装目录等,将需要的软件包或源码编译进根文件系统(使用的软件包等最终是安装在根文件系统中。

可以通过BitBake提供的命令查看当前使用的配置文件和class文件:
bitbake -e > mybb.log

3. 解析recipes

BitBake解析了Metadata基本配置之后,BitBake根据build/conf/bblayers.conf中定义的所使能的layers(meta-xxx),找到对应meta-xxx文件夹下的conf文件夹下的layer.conf文件,在该layer.conf文件中,通过bbFILES和bbPATH指定了当前layer下所使用的Recipes。即通过bbPATH告诉BitBake在哪些路径下,找到哪些.bb和.bbappend文件(即bbFILES),通过这些bbFILES告诉BitBake,会使用哪些软件包或源码构建嵌入式Linux发行版。

通常来说,bbFILES以PN(package name)加PV(package version)命名,如:something_1.2.3.bb,PN=something,PV= 1.2.3。

当recipe解析完成后,会生成一个“任务列表”,接下来就是BitBake根据“任务列表”(bbFILES中定义的内容数据等)进行系统的构建。实际上,在构建系统过程中,就是以一个个task的形式进行的。

BitBake构建系统时,都会分为多个任务执行,例如:fetch, unpack, patch, configure以及compile 。对于构建系统所使用的主机是多核的情况,BitBake内部会对各任务的依赖关系进行处理,不需要用户干预。

4. Providers供应者

在解析了Recipes之后,将会生成一个“任务列表”,BitBake根据该“任务列表”开始编译目标文件。BitBake会查找每一个Recipes对应的PROVIDES列表。PROVIDES列表是由模块的PN(package name)隐式的确定或者由Recipe中的PROBIDES变量显式的决定。当Recipes中通过PROVIDES变量显式的定义了之后,那么该Recipes中定义的功能将由PROVIDES变量定义的recipe文件确定;否则,如果Recipes中没有通过PROVIDES变量显式的定义,那么该Recipes中定义的功能将由模块的PN值定义的recipe文件确定。例如,假设一个名为keyboard_1.0.bb的recipe,在keyboard_1.0.bb中包含了PROVIDES += “fullkeyboard”,那么对于recipes的PROVIDES列表,keyboard_1.0.bb是隐式的定义,而fullkeyboard.bb是显示的定义,该recipe中的功能将由fullkeyboard.bb确定。

5. Preferences优先级

对于确定所使用的目标recipe,PROVIDES列表仅仅是其中的一部分。由于目标recipe有可能会有多个PROVIDES,BitBake通过识别PROVIDES的优先级确定最终使用的provides。 例如,对于virtual/kernel来说,通常会有多个providers,通过类似下面的配置选择最优的providers:

PREFERRED_PROVIDER_virtual/kernel = “linux-yocto”

此外,还存在一种情况,同一个providers有多个版本的recipe文件。这时,一般情况下BitBake将会选择使用最新版本的的recipe文件,除非有其他特殊的设置。例如:

    存在一个a_1.1.bb文件,对于该文件其PN为“a”,PV为“1.1”;同时,存在另外一个a_1.2.bb文件,那么BitBake将默认采用a_1.2.bb构建系统。然后,如果在.conf文件中定义了PREFERRED_PROVIDER_a = "1.1",那么BitBake将会采用a_1.1.bb文件构建系统。 

6. 依赖关系

BitBake构建系统时,都会分为多个任务执行,例如:fetch, unpack, patch, configure以及compile 。对于构建系统所使用的主机是多核的情况,BitBake内部会对各任务的依赖关系进行处理,不需要用户干预。

7. 任务列表

BitBake通过providers和dependencies计算出需要运行的任务及各任务之间的顺序。BitBake构建任务的运行受限于bb_NUMBER_THREADS变量的值,而该值又由构建系统所使用的主机的内核数量确定。 只要有满足依赖关系以及准备好的任务需要运行,并且当前运行任务的数量没有超过线程的阈值。BitBake就会继续派生线程来运行该任务。

2.3 bitbake常用命令

在这里插入图片描述

三、Yocto开发过程

Yocto的开发一般包括:创建Layers、添加新的软件包、扩展或定制系统镜像以及移植到新的硬件平台(增加新的MACHINE)等。

3.1 创建Layers

Yocto使用的是OpenEmbeded来构建系统,并且支持以Metadata的形式来组织管理构建系统所使用的软件包、源代码、配置信息等。Metadata一定程度上可以理解为Layers,实际上就是一个个的文件夹(这些文件夹通常以meta-xxx的形式命名)。采用Layers的方式管理源数据,有利于保持模块化的设计方式,一个Layer包含了一些特定功能所需要的源数据,各Layer之间互不干扰,当所构建的系统需要的功能发生变化时,只需要修改该功能对应的Layer即可,保持了功能的独立性及模块化设计。

3.2 创建Layers的步骤

1.查看已存在的Layers
通常来说,http://layers.openembedded.org/layerindex/layers/ 列出了目前已经存在的公共的开放的Metadata,当需要创建新的Layer时,可以先在该网站上查看下是否已经有了现成的Metadata可供使用,如果有,直接使用即可。如果没有,就需要自己新创建。

2、创建一个文件夹,用来存放Layer里的数据,通常将该文件夹命名为meta-xxx。例如:meta-mylayer。

3、创建Layer配置文件。在新创建的Layer文件夹下(例如:meta-mylayer)创建conf/layer.conf 文件,该layer.conf文件基本框架如下:

# We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"

# We have recipes-* directories, add to BBFILES
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
   ${LAYERDIR}/recipes-*/*/*.bbappend"

BBFILE_COLLECTIONS += "mylayer"
BBFILE_PATTERN_mylayer = "^${LAYERDIR}/"
BBFILE_PRIORITY_mylayer = "5"
LAYERVERSION_mylayer = "3 

其中,各变量含义如下:

(1). bbPATH:将新增加的Layer路径增加至全局变量bbPATH中,BitBake在构建系统时,会根据该变量找到相对应的Layer。
(2). bbFILES:将新增加的Layer中的Recipe文件(即:.bb或.bbappend文件)增加至全局变量bbFILES中,BitBake在构建系统时,会根据该变量找到对应的recipe文件。
(3). bbFILE_COLLECTIONS:将layer名字追加到bbFILE_COLLECTIONS变量,即将Layer的文件夹名字meta-xxx中的xxx赋值给bbFILE_COLLECTIONS 即可。
(4). bbFILE_PATTERN:bbFILE_PATTERN变量为正则表达式,用来匹配bbFILES所在的层,按照基本框架修改即可。
(5). bbFILE_PRIORITY:Layer的优先级。当不同的Layer中定义了相同的recipe时,将按照bbFILE_PRIORITY所对应的高优先级使用相对应的recipe文件。
(6). LAYERVERSION:定义了Layer的版本信息。

4、增加内容。根据Layer的类型,有的Layer会增加machine和distro配置,因此,需要在Layer下的conf/machine/文件中添加机器配置,在该层的conf/distro/文件中添加发行版配置。

3.3 创建Layers时的一些原则

考虑到创建的Layers易于维护,且不会影响到其他Layer,创建Layers时,应该遵循一些原则:

避免覆盖其他Layer中的recipe。也就是说,尽量不要将其他Layer中的整个recipe复制到新创建的Layer中,并对其进行修改。而是采用追加文件.bbappend文件的方式,覆盖仅需要修改的部分。

避免重复包含文件。对于需要包含文件的recipe,使用.bbappend文件或者使用相对于原始Layer的相对路径在进行应用,例如:使用require recipes-core/package/file.inc代替require file.inc。

3.4 使能Layer

创建了新的Layer需要使能之后才能参与到系统的构建过程中。在build/conf/bblayers.conf中定义了参与构建系统使用到的Layers。
对于iMX6ULL,Freescale官方提供了imx-setup-release.sh脚本用于修改build/conf/bblayers.conf文件,在初始化Yocto构建目录时,调用imx-setup-release.sh脚本。因此,修改imx-setup-release.sh脚本即可,修改方式如下:
在这里插入图片描述

3.5 使用.bbappend文件

用于将Metadata附加到其他recipes的recipes称为BitBake附加文件。 BitBake附加文件使用.bbappend文件类型后缀,而要附加Metadata的相应的recipes则使用.bb文件类型后缀。通过.bbappend文件,可以使得创建的Layer在不拷贝其他recipe到新建的Layer中的情况下,以附加或改写的方式改变其他Layer中的内容。直观来看,就是新建的Layer中的.bbappend文件,与需要修改或附件额外内容的.bb文件处于不同的Layer。

附件文件(.bbappend)必须和对应的recipes(.bb)文件名(或文件名与版本号)一致。例如:附件文件someapp_2.1.bbappend只对someapp_2.1.bb文件有效,也就是说,当someapp_2.1.bb文件升级至someapp_2.2.bb或其他版本的.bb文件时,相应的附件文件someapp_2.1.bbappend也要进行相应的升级,如someapp_2.2.bbappend。在构建系统过程中,当BitBake检测到某个.bbappend文件没有对应的.bb文件时,将会报错

3.6 Layers管理

BitBake提供了Layer管理工具,用来查看Layers的一些基本信息。使用方式如下:

bitbake-layers command [arguments] 

可以使用的命令如下:

  • help:帮助命令。
  • show-layers: 显示当前配置的Layer。
  • show-recipes: 显示可用的recipes以及recipes提供的layers。
  • show-overlayed: 显示覆盖的recipes。高优先级Layer中的recipe将覆盖其他低优先级Layer中相同的recipes。
  • show-appends: 显示.bbappend文件,以及对应的recipe文件。
  • show-cross-depends: 显示不同Layer中recipes的依赖关系。
    在这里插入图片描述

3.7 创建Recipes

Metadata(Layer)是由一些Recipes组成的。从形式上来看,Recipes是在metadata文件夹下的一些文件夹(同样的,惯例以recipes-xxx命名)。recipes-xxx文件夹中的recipes(.bb文件)是Yocto工程的最基础组成部分。OpenEmbedded构建系统使用的软件包等组件都是在recipe中定义的。

1. 创建基础Recipes

有两种比较简便易行的创建新的recipes的方法:

  • recipetool:Yocto提供的工具,基于源文件自动创建基础recipe。

  • Exitsing Recipes:在一个功能需求相似的已有recipe基础上修改。

对于第二种构建方式。通常,recipe中定义了一些变量用于定义需要使用的软件包,其基本框架如下:

DESCRIPTION = ""
HOMEPAGE = ""
LICENSE = ""
SECTION = ""
DEPENDS = ""
LIC_FILES_CHKSUM = ""
SRC_URI = "" 

2. 存储和命名recipes

通常,创建了基础的recipes之后,需要按照一定的目录框架将recipes放在合适的位置,以确保OpenEmbedded构建系统时能够找到。OpenEmbedded是通过Layer(meta-xxx文件夹)下的conf/layer.conf中的变量bbFILES找到构建过程中所使用的recipes。其典型的应用如下:

BBFILES += "${LAYERDIR}/recipes-//.bb \  ${LAYERDIR}/recipes-//.bbappend" 

因此,必须确保新创建的recipe在layer中的正确路径。 此外,对于recipe文件的命名,也应该按照一定的规则,如下所示:

basename_version.bb 

3. 编译Recipes

对于新创建的recipe,往往需要不断的修改编译、反复迭代才能逐步实现完善最终的功能。在使用fls-setup-release.sh脚本初始化Yocto构建目录后,将自动进入build目录,在该路径下,通过如下命令即可编译recipe:

bitbake basename 

其中,basename是recipe的文件名。在编译过程中,OpenEmbedded编译系统会为每一个recipe创建一个临时的文件夹,用来存放解压文件、日志文件等。每一个recipe的临时文件夹都按照如下的方式组织:

BASE_WORKDIR ?= "${TMPDIR}/work"
WORKDIR = "${BASE_WORKDIR}/${MULTIMACH_TARGET_SYS}/${PN}/${EXTENDPE}${PV}-${PR}"

例如:假设生成的系统架构为qemux86-poky-linux,recipe文件为foo_1.3.0.bb ,那么,将生成如下的文件:

/build/tmp/work/qemux86-poky-linux/foo/1.3.0-r0

在该路径下,还可以看到image、packages-spilt和temp等文件夹。编译之后,可以通过查看这些文件夹里的内容确定编译过程是否正确。

4. 获取源码

构建系统的过程,实际上是将一些软件源码编译成系统镜像文件的过程,因此,recipe的第一步是定义如何获取相关的软件源码。在recipe中,通过SRC_URI变量定义了软件源码的位置。BitBake编译系统镜像文件的过程可以分为几个任务分步完成的,其中一个任务do_fetch会根据SRC_URI变量值的前缀确定使用哪个fetcher从什么地方获取软件源码。获取源码结束后,do_patch任务也会根据SRC_URI变量值来打补丁。

recipe中的SRC_URI定义了软件源码的唯一地址。推荐在SRC_URI变量中定义的软件源码地址包含${PV}的方式,以便在获取软件源码过程中使用recipe文件名中定义的版本,同时,后续当需要升级软件版本时,只需要将recipe文件名进行版本号升级即可。例如:meta/recipesdevtools/cdrtools/cdrtoolsnative_3.01a20.bb的recipe中,SRC_URI变量值使用了“PV”值。

SRC_URI = "ftp://ftp.berlios.de/pub/cdrecord/alpha/cdrtools-${PV}.tar.bz2"

还可以通过SCM(Source Control Managers)获取软件源码,例如Git。对于Git来说,还需要在recipe中定义SRCREV和SRCPV变量值,例如:meta/recipeskernel/blktrace/blktrace_git.bb:

SRCREV = "d6918c8832793b4205ed3bfede78c2f915c23385"
PR = "r6"
PV = "1.0.5+git${SRCPV}"
SRC_URI = "git://git.kernel.dk/blktrace.git \
			file://ldflags.patch"

其中,SRCPV = “${@bb.fetch2.get_srcrev(d)}”

此外,如果SRC_URI指向的软件源码地址不是从SCM,而是远程服务器或其他地址的软件源码包,则需要定义相对应的软件源码包校验值,以便BitBake在编译时通过校验值确定软件包的完整性。例如:

SRC_URI = "${DEBIAN_MIRROR}/main/a/apmd/apmd_3.2.2.orig.tar.gz;name=tarball \ ${DEBIAN_MIRROR}/main/a/apmd/apmd_${PV}.diff.gz;name=patch SRC_URI[tarball.md5sum] = "b1e6309e8331e0f4e6efd311c2d97fa8" SRC_URI[tarball.sha256sum] = "7f7d9f60b7766b852881d40b8ff91d8e39fccb0d1d913102a5c75a2dbb52332d" SRC_URI[patch.md5sum] = "57e1b689264ea80f78353519eece0c92" SRC_URI[patch.sha256sum] = "7905ff96be93d725544d0040e425c42f9c05580db3c272f11cff75b9aa89d430" 
5. 解压源码

如果获取的源码是压缩包的形式,在编译过程中,do_unpack任务会将压缩包进行解压。

6. 补丁代码

有时在获取了软件源码之后,需要进行打补丁。在SRC_URI中以.patch、.diff或者是这些后缀的压缩包(如:diff.gz)都是补丁代码。在执行do_patch任务时,会自动的应用补丁。

参考博客:https://space.bilibili.com/1674778427/article
https://blog.csdn.net/weixin_41965270/article/details/83016254

  • 6
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值