Yocto学习笔记
Posted Jocelin47
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
以上是关于Yocto学习笔记的主要内容,如果未能解决你的问题,请参考以下文章