> 文章列表 > 构建Yocto项目

构建Yocto项目

构建Yocto项目

前言

Yocto Project简称YP, 是一个致力于帮助开发者构建自己的Linux嵌入式的项目,除了Yocto还有其它的开源项目例如:Debian,著名的Ubuntu就是基于Debian来构建的发行版。

什么是Yocto Project?

Yocto Project (YP)是一个开源协作项目, 可帮助开发人员创建基于Linux内核的自定义系统, 而无需考虑其硬件体系结构。

该项目提供了一套灵活的Build工具, 开发者可以更快的上手去构建自己的Linux操作系统, 经过许多年的发展Yocto已经支持了许多架构, 例如:

  1. Intel

  1. ARM

  1. MIPS

  1. AMD

  1. PPC

同时这些厂商也加入到Yocto项目的维护当中,并为这些架构开发BSP包来让Yocto适配自己的架构。

Yocto与Linux内核的关系

Yocto诞生的目的是为完善Linux内核,一个完整的操作系统是由多个部分组成的,其中内核是最关键的部分,这和CPU是一个道理,一个完整的PC如果光只有CPU是无法运行的,我们还需要有总线、内存、显示器、键盘、鼠标才能构成可供我们使用的PC电脑,而控制这些设备的核心部分就是CPU,操作系统也亦是如此,构成一个完整的操作系统需要有文件系统,桌面应用服务、shell、基本设施程序(ls、cd、rm), 最早开发人员如果想用Linux内核来构建自己的系统是非常麻烦的,你需要去进行适配然后移植文件系统、开发各种工具才能让Linux在你的架构上运行起来并提供给别人使用。

Yocto诞生的目的就是为了加快构建Linux操作系统,开发者们可以基于Yocto来快速构建自己的Linux操作系统,Yocto里集成了大量开发包、软件包、文件系统,集成了一个完整操作系统的所有部分,并且提供了Build工具来统一化管理与构建项目。

所以YoctoLinux之间的关系就像是CPU与PC之间的关系一样,为Linux内核提供完整操作系统的功能。

为何Yocto还需要进行架构上的适配?

虽然Linux内核已经对许多架构进行了适配,可以很轻易的移植到不同的架构上,但是一系列软件包并没有,所以Yocto需要对这些组成部分也进行移植适配才能更好的运行在这些架构上。

Open Embedded

Open Embedded是以工业界标准的开放式系统为基础而开发出来的嵌入式系统,针对特定的硬件体系结构, 利用专门的指令系统开发出来的嵌入系统, Yocto是实现Open Embedded的一种方式,除此之外还有Debian,著名的apt-get工具就是出自Debian项目。

开始!构建你的Yocto项目

准备工作

Yocto是一个庞大的项目,如果你想要构建Yocto首先你的电脑需要具备以下条件:

  1. 一个基于Linux内核构建的发行版操作系统,例如Ubuntu20.04

  1. 可利用的磁盘分区大小至少达到70GB以上(可能会更大), 建议准备100GB以上的磁盘

  1. 网络通顺,并且能够科学上网

获取Yocto项目

Yocto官方提供了一个示例Open Embedded Os: Poky, 这个项目不光是一个示例项目还包含了完整的Yocto的构建服务,开发者们可以基于Poky来构建自己的发行版

官方Git链接:git://git.yoctoproject.org/poky

Github链接:https://github.com/YoeDistro/poky.git

可以选择一个适合你下载的链接,Github与官方的Git是同步维护的

git clone https://github.com/YoeDistro/poky.git
cd poky

下载的是最新版本的yocto项目,这里建议大家使用稳定长期维护的版本,你可以在这里找到你想要的分支名:https://wiki.yoctoproject.org/wiki/Releases

不同的分支里它们的构建语法可能有所不同,但大同小异,这里使用的分支是Hardknott:

git fetch --tags
git checkout -t  origin/hardknott -b t_hardknott

下面是对Yocto的项目文件结构的介绍

文件名

作用

bitbake

工具目录bitbake,是一metedate解释器,读取metedate并执行定义的task。执行bitbake命令时,其实执行的就是bitbake/bin/下面的文件

build

用户配置文件和工程构建输出目录,build目录在建立环境变量时进行创建并进行配置文件初始化。构建的所有文件都在该目录下组织存放。

documentation

说明文件

meta

Open EmbeddedCore的Metedata,包括recipes,comon classes等

meta-poky

poky发行版本的配置数据

meta-yocto-bsp

yocto工程包含的一些参考的BSP配置,通常厂商自己会增加自己的bsp目录

meta-selftest

Open Embedded自测的recipes和append 文件

meta-skeleton

BSP和kernel开发用的一些临时recipes

scripts

脚本文件,用来提供一些特性的功能。该路径会被添加到环境变量中

oe-init-build-env

构建Open Embedded的环境

在项目文件体系里没有包含一些核心code,例如Linux内核,Yocto是一个通过分布配方组成的项目,拉取下来的原始项目只包含了Build配置文件,这些文件里包含了其它发行版以及架构的配置信息,在build的时会读取这些配置信息来下载对应的源代码,所以为什么很多人会说Yocto编译非常庞大与麻烦的原因就在这里,Yocto只会在构建阶段才会去根据你指定的配置来去下载对应的Code在进行配置与编译

在开始之前需要安装一些构建时所需要的Tools:

sudo apt install gcc g++ cpp chrpath cpio diffstat gawk make wget python3 python3-pip

开始构建

首先初始化环境变量:

source oe-init-build-env

如果初始化成功会提示如下输出:

You can now run 'bitbake <target>'Common targets are:core-image-minimalcore-image-full-cmdlinecore-image-satocore-image-westonmeta-toolchainmeta-ide-supportYou can also run generated qemu images with a command like 'runqemu qemux86'Other commonly useful commands are:- 'devtool' and 'recipetool' handle common recipe tasks- 'bitbake-layers' handles common layer tasks- 'oe-pkgdata-util' handles common target package tasks

当初始化完成之后Yocto提供了三个工具:

工具名

作用

devtool

可以使用该工具有选择地将构建的内容集成到OpenEmbedded构建系统构建的映像中,同时该工具可以快速修改源码

bitbake

是一个类似于GNU的make的构建工具,主要是为了管理嵌入式Linxu交叉编译的各个版本和包。

oe-pkgdata-util

处理常见的目标包任务

这里解释一下上面生成几个镜像的差异:

镜像名

作用

core-image-minimal

最小镜像,不能再这个基础上精简,这个镜像仅仅能启动而很多功能还无法使用,因为缺乏应用层软件

core-image-full-cmdline

仅控制台映像,安装了更多功能齐全的Linux系统功能

core-image-sato

在core-image-full-cmdline基础上添加一个叫sato的GUI演示

core-image-weston

这是基于Wayland协议和Weston参考合成器的镜像

meta-toolchain

生成通用SDK工具链

meta-ide-support

此命令将生成可在Yocto构建环境之外使用的跨工具链

如果你想知道每个镜像安装了哪些包可以使用如下命令来查看

bitbake -g core-image-minimal

执行之后会在本地生成一个pn-buildlist的文件,里面存放了要安装的包名称, 如果想查看包的版本可以使用如下命令-s:

bitbake -s

需要值得注意的是每个分支都有一些不同的开发者组织维护的,它们生成时在别的分支上可能有所不同

这里构建一个仅有CMD命令的镜像:

bitbake core-image-full-cmdline

在构建时你可能会遇到这样的问题:

Please use a locale setting which supports UTF-8 (such as LANG=en_US.UTF-8).
Python can't change the filesystem locale after loading so we need a UTF-8 when Python starts or things won't work.

这个原因是因为本地语言设置的问题, bitbake工具需要本地语言环境为en_US.UTF-8, 解决方案如下:

首先安装语言包

sudo apt-get install locales

然后设置语言:

sudo dpkg-reconfigure locales

使用上述命令之后会弹出语言选择画面,选择en_US.UTF-8的数字编号就可以了

(Enter the items you want to select, separated by spaces.)Locales to be generated: 158Many packages in Debian use locales to display text in the correct language for the user. You can choose a default locale for the system from the
generated locales.This will select the default language for the entire system. If this system is a multi-user system where not all users are able to speak the default
language, they will experience difficulties.1. None  2. C.UTF-8  3. en_US.UTF-8 
Default locale for the system environment: 2

然后生效设置:

sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8

第一次构建时会下载大量包,此时需要保证你的网络通顺且能科学上网,否则可能会出现下载失败的情况,整个过程大概会需要3个多小时

NOTE: Fetching uninative binary shim http://downloads.yoctoproject.org/releases/uninative/3.5/x86_64-nativesdk-libc-3.5.tar.xz;sha256sum=e8047a5748e6f266165da141eb6d08b23674f30e477b0e5505b6403d50fbc4b2 (will check PREMIRRORS first)
Initialising tasks: 100% |############################################################################################################| Time: 0:00:01Sstate summary: Wanted 1390 Local 0 Network 0 Missed 1390 Current 0 (0% match, 0% complete)
NOTE: Executing Tasks
Currently 16 running tasks (383 of 3770)  10% |##########                                                                                           |0: binutils-cross-x86_64-2.36.1-r0 do_fetch (pid 6256)   3% |##                                                                             | 1004K/s1: mpfr-native-4.1.0-r0 do_fetch (pid 6313)   0% |                                                                                                  |2: glibc-2.33-r0 do_fetch (pid 6561)  21% |####################                                                                              | 873K/s3: rpm-native-1_4.16.1.3-r0 do_fetch (pid 20145)  22% |##################                                                                    | 983K/s4: curl-native-7.75.0-r0 do_fetch (pid 29249)   0% |                                                                                                |5: cmake-native-3.19.5-r0 do_fetch (pid 30171)   3% |##                                                                                     | 25.5M/s6: linux-yocto-5.10.107+gitAUTOINC+24ab54209a_763c0dbc04-r0 do_fetch (pid 37703)   0% |                                                      | 767K/s7: patch-native-2.7.6-r0 do_configure - 14s (pid 56047)
8: bison-native-3.7.5-r0 do_configure - 8s (pid 75451)
9: linux-libc-headers-5.10-r0 do_unpack - 4s (pid 92723)
10: gcc-source-10.3.0-10.3.0-r0 do_unpack - 4s (pid 94125)
11: pkgconfig-native-0.29.2+gitAUTOINC+edf8e6f0ea-r0 do_compile - 1s (pid 107522)
12: rsync-native-3.2.3-r0 do_configure - 1s (pid 108818)
13: autoconf-archive-native-2019.01.06-r0 do_populate_sysroot - 0s (pid 110639)
14: gmp-native-6.2.1-r0 do_install - 0s (pid 110701)
15: unifdef-na

如果过程中出现了警告可以忽略,这个是Yocto里的某个源不可用了,但是没关系Yocto会去别的源上下载

WARNING: mpfr-native-4.1.0-r0 do_fetch: Failed to fetch URL https://www.mpfr.org/mpfr-4.1.0/mpfr-4.1.0.tar.xz, attempting MIRRORS if available
WARNING: curl-native-7.75.0-r0 do_fetch: Failed to fetch URL https://curl.haxx.se/download/curl-7.75.0.tar.bz2, attempting MIRRORS if available
WARNING: libmnl-1.0.4-r0 do_fetch: Failed to fetch URL https://netfilter.org/projects/libmnl/files/libmnl-1.0.4.tar.bz2;name=tar, attempting MIRRORS if available

编译完成之后生成build目录,在build目录下的downloads目录就是下载的包,如果想下次不这么麻烦可以把这个包打包一下,下次直接解压到build目录下就可以直接使用了

下面对build目录文件结构的介绍:

文件

作用

conf/local.conf

用户的配置文件,包含所有定制化的配置。该文件配置的所有变量都会覆盖其他文件相应变量的软赋值 (?= 形式)(注意=形式的硬编码无法覆盖)

conf/bblayers.conf

该文件用来定义BBLAYERS,BBLAYERS是决定哪些路径下的模块需要构建,哪些不需要构建,并将这些信息提供给BitBake

conf/sanity_info

可用性信息

downloads

构建过程中,下载的所有源码。可以将该目录放到一个公共目录下,提供每次的编译效率

sstate-cache

构建构成中的构建状态缓存。可以将该目录放到一个公共目录下,提供每次的编译效率

tmp

构建时所有的输出都存放在该目录下

tmp/buildstats

构建统计信息,每次构建,都会在该目录下生成一个日期目录

tmp/cache

BitBake解析metedata(包括recipes和config文件)后,将解析的结果缓存在该目录,以提高后续效率

tmp/deploy

部署文件目录,最终需要的文件(boot rootfs image等)都在该目录中

tmp/deploy/deb

存放系统产生的所有.deb类型的安装包

tmp/deploy/rpm

存放系统产生的所有rpm类型的安装包

tmp/deploy/ipk

存放系统产生的所有ipk类型的安装包

tmp/deploy/licenses

系统使用的各种软件的许可信息

tmp/deploy/images

存放boot rootfs image等文件

/tmp/deploy/sdk

工具链安装脚本

tmp/sstate-control

状态跟踪文件

tmp/sysroots-components

制作sysroots前需要额外添加的一些组件

tmp/sysroots

构建出的根文件系统内容

tmp/stamps

记录BitBake跟踪task执行时间的一些信息

tmp/log

日志信息

tmp/work

包含和CPU架构相关的工作目录

tmp/work-shared

工作信息缓存,为了提高效率

当完成构建之后可以使用qemu命令来测试镜像,bitbake默认生成的是qemu Intel x86-64架构的image:

runqemu qemux86-64

执行之后会弹出Qemu运行窗口:

加载画面

构建Yocto项目

Home画面

构建Yocto项目

镜像存放路径在build/tmp/deploy/images下,新版的Yocto项目会在images目录下生成一个架构平台名字的目录,里面就存放了生成的镜像文件

构建指定架构的Yocto

我们下载原生的Yocto项目提供的Poky演示嵌入式操作系统里只提供了Qemu架构的环境,你可以在meta/conf/machine里面找到支持的架构:

qemuarm.conf    qemumips64.conf  qemuppc64.conf  qemuriscv32.conf  qemux86-64.conf
qemuarm64.conf  qemuarmv5.conf  qemumips.conf    qemuppc.conf    qemuriscv64.conf  qemux86.conf

可以看到Poky仅提供了Qemu架构的配置文件,我们可以通过Poky这个项目来进项修改,参考它的方式来定制化自己的发行版,例如OpenstLinux就是基于Poky改过来的。

Yocto有两个关键变量MACHINE、DISTRO,这两个变量的意义如下:

MACHINE:架构,指定要生成的架构环境

DISTRO:发行版策略

目前DISTRO只有poky,MACHINE只有qemu的架构环境,所以从这些配置就可以看出poky只是Yocto提供的一个示例项目,期望开发者们基于这个项目来定制化自己的发行版,如果我们想要定制化自己的项目可以在meta-poky目录里找到示例写法,例如配置交叉编译器,定制策略与设备树文件这些信息

你可以在build/conf/local.conf文件里修改这两个内容,也可以指定环境变量,Yocto在构建时会去读取这两个环境变量,如果内容为空则读取local.conf里的内容作为默认值

下面构建一个arm64架构的Yocto

在重新构建之前需要清除上一次编译的缓存

bitbake -c cleansstate core-image-full-cmdline

重新初始化环境

export DISTRON=poky
export MACHINE=qemuarm64
source oe-init-build-env

构建

bitbake core-image-full-cmdline

在构建时可以看到输出信息, 可以看到构建时的MACHINE变更为了qemuarm64

Build Configuration:
BB_VERSION           = "1.50.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "aarch64-poky-linux"
MACHINE              = "qemuarm64"
DISTRO               = "poky"
DISTRO_VERSION       = "3.3.6"
TUNE_FEATURES        = "aarch64 armv8a crc cortexa57"
TARGET_FPU           = ""
meta                
meta-poky           
meta-yocto-bsp       = "my-hardknott:1cefabe0f0a2dd2ca8b6eb83e8e0824b72da941a"

如果你想要加快编译,加快make的执行速度,可以在conf/local.conf文件里添加如下内容:

PARALLEL_MAKE ?= "-j4"

和make使用多线程编译一样的用法,同时如果想要加快bitbake执行任务时的线程数可以增加如下内容:

BB_NUMBER_THREADS ?= "8"

这两个变量分别对应make的编译线程和bitbake执行工作任务时线程数,例如bitbake在执行下载任务时可以使用多线程来加快下载速度

当编译完成之后可以使用qemu来进项模拟运行:

runqemu qemuarm64