3. Yocto核心概念与架构剖析

很多刚接触Yocto的朋友,第一个问题就是:Poky到底是什么?

说实话,我刚开始也被这个概念绕了一下。Poky不是一个新的操作系统,也不是一个独立的工具链。它更像是一个「参考实现」——一个能让你快速跑起来、看到Yocto到底能干什么的完整示例。

3.1 Poky的本质

Poky是Yocto项目的官方参考构建系统。它包含了构建嵌入式Linux系统所需的一切:

  • BitBake:任务调度引擎,负责解析配方、执行构建任务
  • OpenEmbedded-Core (OE-Core):核心元数据层,提供基础配方和类
  • 一系列默认配置:让你开箱即用,不需要从零开始写配置

说白了,Poky就是Yocto团队帮你搭好的一个「样板间」。你可以在它的基础上修改、扩展,最终构建出你自己的嵌入式Linux系统。

关键理解:Poky ≠ Yocto。Yocto是项目名称,Poky是Yocto提供的参考构建系统。你实际工作中用的可能是基于Poky定制的内部发行版。

3.2 下载Poky源码

下载Poky源码,我推荐用Git克隆。这样方便后续切换分支、查看历史、回退版本。

我个人习惯把Yocto相关的工作目录放在 ~/yocto 下,方便管理。

# 创建并进入工作目录
mkdir -p ~/yocto
cd ~/yocto

# 克隆Poky源码(以kirkstone长期支持版本为例)
git clone git://git.yoctoproject.org/poky -b kirkstone

这里我选了kirkstone分支。为什么?因为它是LTS(长期支持)版本,稳定性好,社区支持周期长。我在项目中吃过非LTS版本的亏——升级太频繁,配方兼容性问题一堆。从那以后,我坚持用LTS版本做产品。

克隆完成后,目录结构是这样的:

poky/
├── bitbake/        # BitBake构建引擎
├── meta/           # OE-Core核心层
├── meta-poky/      # Poky参考发行版配置
├── meta-yocto-bsp/ # 参考板级支持包
├── scripts/        # 辅助脚本
├── oe-init-build-env  # 环境初始化脚本
└── README

小技巧:如果你在公司内网或网络受限,可以先下载tar包再解压。但我还是建议用Git——后续更新、切换分支都方便。

3.3 首次构建前的准备

在跑第一次构建之前,有几件事要先确认好。不然构建到一半报错,很浪费时间。

3.3.1 检查系统依赖

Yocto对宿主机的软件包有要求。以Ubuntu 20.04/22.04为例,需要安装以下依赖:

sudo apt-get update
sudo apt-get install gawk wget git diffstat unzip texinfo gcc build-essential \
  chrpath socat cpio python3 python3-pip python3-pexpect xz-utils debianutils \
  iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev \
  xterm python3-subunit mesa-common-dev zstd liblz4-tool

嗯,这里要注意:不同Ubuntu版本、不同Yocto版本,依赖列表会有差异。最稳妥的做法是看Poky源码里的 documentation/poky.yaml.in 文件,里面有官方列出的依赖清单。

3.3.2 初始化构建环境

每次开始构建前,都需要初始化环境。这一步会设置环境变量,并创建构建目录。

cd ~/yocto/poky
source oe-init-build-env build-qemuarm64

执行后,你会看到类似这样的输出:

You had no conf/local.conf file. This configuration file has therefore been
created for you with some default values. You may wish to edit it to use a
different MACHINE (target hardware) or enable parallel build options.

You had no conf/bblayers.conf file. This configuration file has therefore been
created for you with some default values.

同时,当前目录会切换到 ~/yocto/poky/build-qemuarm64。这个目录就是你的构建工作区。

注意:每次打开新终端,都要重新执行 source oe-init-build-env。环境变量只在当前shell会话中有效。

3.4 配置构建目标

初始化完成后,有两个配置文件需要关注:

配置文件 路径 作用
local.conf build-qemuarm64/conf/local.conf 本地构建配置,如目标硬件、并行任务数、下载目录等
bblayers.conf build-qemuarm64/conf/bblayers.conf 声明哪些元数据层参与构建

对于首次构建,我们只需要修改 local.conf 中的几个关键参数:

# 目标硬件:这里用QEMU模拟的ARM 64位平台
MACHINE ?= "qemuarm64"

# 并行编译任务数,建议设为CPU核心数的2倍
BB_NUMBER_THREADS ?= "8"
PARALLEL_MAKE ?= "-j 8"

# 下载源码包的缓存目录,避免重复下载
DL_DIR ?= "${TOPDIR}/../downloads"

为什么把 DL_DIR 设置到构建目录外面?因为如果你有多个构建目录(比如同时构建arm和x86),共享下载目录可以节省大量带宽和磁盘空间。这个经验是我在同时维护三个产品线时总结出来的。

3.5 启动首次构建

配置完成后,就可以开始构建了。我们构建一个最小的QEMU镜像:

bitbake core-image-minimal

这条命令会触发一系列操作:

  1. 解析所有配方和配置文件
  2. 下载所有源码包(约1-2GB)
  3. 编译交叉工具链
  4. 编译内核、根文件系统
  5. 打包生成镜像文件

第一次构建时间会比较长,取决于你的网络和机器性能。我见过最快的是30分钟(32核服务器),最慢的跑了6个小时(4核笔记本+慢速网络)。

节省时间:如果网络条件不好,可以先用 bitbake -c fetchall core-image-minimal 把所有源码包下载完,再执行完整构建。这样即使中途断网,也不会卡在下载环节。

3.6 验证构建结果

构建完成后,输出文件在 tmp/deploy/images/qemuarm64/ 目录下:

tmp/deploy/images/qemuarm64/
├── core-image-minimal-qemuarm64.qemuboot.conf
├── core-image-minimal-qemuarm64.rootfs.ext4
├── core-image-minimal-qemuarm64.rootfs.manifest
├── core-image-minimal-qemuarm64.rootfs.tar.bz2
├── Image           # 内核镜像
├── Image-qemuarm64.bin
└── modules--5.15.xx.tgz

用QEMU启动验证:

runqemu qemuarm64 nographic

看到登录提示符后,输入 root 登录(默认无密码)。你就成功进入了自己构建的嵌入式Linux系统!

首次构建成功标志:看到 root@qemuarm64:~# 提示符。这意味着你从源码构建了一个完整的、可运行的嵌入式Linux系统。

3.7 Poky构建流程全景图

下面这张图展示了从下载Poky到最终生成镜像的完整流程:

Poky首次构建流程 Poky首次构建流程 下载Poky源码 source oe-init-build-env 修改 local.conf bitbake core-image-minimal 生成镜像文件 解析配方(.bb/.bbappend) 下载源码包(fetch) 编译(compile) 打包(package) 组装根文件系统 关键说明 左侧:用户操作步骤 右侧:BitBake内部执行流程 虚线箭头:操作触发内部流程

3.8 常见问题与避坑

第一次构建,几乎每个人都会遇到问题。我把最常见的几个列出来:

问题1:磁盘空间不足

构建过程中,tmp/ 目录会膨胀到10-20GB。确保你的磁盘有至少50GB空闲空间。我曾经在只剩15GB的机器上跑构建,结果半夜收到磁盘满的告警,构建失败,白等了一晚上。

问题2:网络超时导致下载失败

Yocto从多个上游仓库下载源码,有些仓库在国内访问很慢。建议配置代理,或者使用国内镜像源。在 local.conf 中添加:

# 使用国内镜像(以清华源为例)
PREMIRRORS_prepend = "\
git://.*/.* http://mirrors.tuna.tsinghua.edu.cn/yocto/sources/ \n \
https?://.*/.* http://mirrors.tuna.tsinghua.edu.cn/yocto/sources/ \n"

问题3:Python版本不兼容

Yocto kirkstone要求Python 3.8+。如果你的系统Python版本太低,BitBake会直接报错退出。检查方法:

python3 --version
# 确保输出 >= 3.8

3.9 构建后的思考

第一次构建成功,你可能会觉得:嗯,好像也不难?

但我想说,这只是万里长征的第一步。Poky帮你搭好了架子,真正的挑战在于:

  • 如何添加自己的软件包?
  • 如何修改内核配置?
  • 如何定制根文件系统?
  • 如何为真实硬件构建?