第2章:Yocto环境搭建:配置Poky、构建最小系统镜像

好,咱们正式开始动手了。

上一章我们聊了嵌入式Linux启动优化的整体思路,说白了就是「怎么让系统跑得更快」。但光有思路不行,你得有个趁手的工具。Yocto就是那个工具。而Poky,是Yocto的参考构建系统,也是我们入门的起点。

2.1 什么是Poky?为什么选它?

Poky这个名字听起来挺萌的,但它干的事一点都不含糊。它本质上是一个包含了BitBake构建引擎、OpenEmbedded核心元数据(meta层)以及一系列工具的集合体。你把它下载下来,配置好,就能直接开始构建嵌入式Linux系统。

我个人习惯把Poky比作「乐高基础包」。它提供了最常用的积木块——比如GCC编译器、glibc库、Linux内核源码、Busybox等。你不需要从零开始拼,直接在这个基础上加你自己的模块就行。

核心要点:Poky = BitBake + OpenEmbedded Core + 参考BSP。它是Yocto项目的官方参考实现,也是学习Yocto的最佳起点。

2.2 环境准备:别在第一步翻车

我在项目中遇到过不少新手,上来就git clone Poky,然后直接跑bitbake,结果编译到一半报错。为什么?因为宿主机环境没配好。

Yocto对宿主机的依赖其实挺多的。你想想看,它要在你的PC上交叉编译整个Linux系统,缺了哪个工具链都不行。这里我列一个我常用的检查清单:

软件包 用途 安装命令(Ubuntu/Debian)
gcc / g++ 宿主机编译器 sudo apt install build-essential
make / cmake 构建工具 sudo apt install make cmake
chrpath / diffstat 路径处理与统计 sudo apt install chrpath diffstat
texinfo / python3 文档生成与脚本 sudo apt install texinfo python3
gawk / wget 文本处理与下载 sudo apt install gawk wget

我的小技巧:如果你用的是Ubuntu 20.04或22.04,直接跑 sudo apt 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 这一条命令,基本能覆盖90%的依赖。

2.3 下载Poky:选对版本很重要

嗯,这里要注意。Yocto每半年发布一个版本,每个版本都有对应的代号。比如kirkstone、honister、dunfell。我个人建议初学者选一个LTS(长期支持)版本,比如kirkstone(4.0.x)。

为什么?因为LTS版本bug少,社区支持时间长。你想想看,如果选了一个非LTS版本,学了一半发现官方不维护了,那多闹心。

下载方式很简单:

# 克隆Poky仓库,指定kirkstone分支
git clone git://git.yoctoproject.org/poky -b kirkstone
cd poky

下载完成后,你会看到poky目录下有几个关键的子目录:

  • meta/ — OpenEmbedded核心层,包含基础配方和类
  • meta-poky/ — Poky的发行版配置层
  • meta-yocto-bsp/ — 参考板级支持包(比如qemu模拟器)
  • bitbake/ — BitBake构建引擎本身
  • scripts/ — 各种辅助脚本

2.4 初始化构建环境

这一步很关键。Yocto不像普通的Makefile项目,你直接在源码目录下make就行。它需要先初始化一个构建环境,说白了就是设置一堆环境变量,告诉BitBake去哪里找配方、用什么架构、输出目录在哪。

运行以下命令:

source oe-init-build-env build

这条命令做了几件事:

  • 创建了一个 build/ 目录(如果不存在的话)
  • 自动cd到该目录
  • 设置 TEMPLATECONF 等环境变量
  • 从模板复制 local.confbblayers.confbuild/conf/

运行成功后,你会看到终端提示符前面多了个 (build) 标记。嗯,这说明环境已经激活了。

我曾经踩过的坑:每次打开新终端都要重新 source oe-init-build-env。别问我为什么,问就是环境变量只在当前shell生效。如果你忘了source,直接跑bitbake,它会告诉你「找不到命令」。

2.5 配置local.conf:定制你的构建

现在打开 build/conf/local.conf,这是Yocto构建的核心配置文件。我挑几个最重要的参数说一下:

# 目标机器架构
MACHINE ??= "qemuarm64"

# 并行编译线程数,建议设为CPU核心数+1
BB_NUMBER_THREADS = "8"
PARALLEL_MAKE = "-j 8"

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

# 共享状态缓存目录,加速重复构建
SSTATE_DIR ?= "${TOPDIR}/../sstate-cache"

这里我重点说一下 MACHINE。它决定了你为哪个硬件平台构建系统。Poky自带了几个参考机器:

MACHINE值 目标平台 说明
qemuarm ARM 32位 适合学习,QEMU模拟
qemuarm64 ARM 64位 推荐,现代嵌入式主流
qemux86 x86 32位 PC兼容
qemux86-64 x86 64位 PC兼容

我个人习惯用 qemuarm64 做测试。因为ARM64架构在嵌入式领域越来越主流,而且QEMU模拟起来速度也快。

2.6 构建最小系统镜像

好,配置完了,该动真格的了。Yocto里有一个叫 core-image-minimal 的镜像配方,它构建出来的系统只包含最基本的组件——内核、根文件系统、Busybox、一些基础库。说白了就是「能启动、能跑shell」的最小系统。

构建命令就一行:

bitbake core-image-minimal

然后...就是漫长的等待。第一次构建需要下载大量源码包,编译整个工具链、内核、根文件系统。在我的机器上(8核i7,32GB内存),第一次构建大概需要40分钟到1小时。

省时间的小技巧:第一次构建时,你可以去泡杯咖啡,或者看看文档。但如果你后续修改了配置,可以利用 sstate-cache 加速。说白了就是只重新编译变化的部分,没变的部分直接用缓存。

构建成功后,你会看到类似这样的输出:

NOTE: Tasks summary: Attempted 1234 tasks of which 1234 didn't need to be rerun.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 1 seconds

生成的镜像文件在 build/tmp/deploy/images/qemuarm64/ 目录下。你会看到:

  • core-image-minimal-qemuarm64.rootfs.ext4 — 根文件系统镜像
  • core-image-minimal-qemuarm64.rootfs.tar.bz2 — 根文件系统压缩包
  • zImage — 内核镜像
  • Image — 如果是ARM64,内核文件叫这个

2.7 用QEMU验证构建结果

构建完了,怎么知道它能不能用?Poky自带了QEMU启动脚本,直接跑:

runqemu qemuarm64

这个命令会自动找到刚才构建的内核和根文件系统,启动一个QEMU虚拟机。你会看到一个终端窗口弹出,里面是Linux的启动日志。等几秒钟,就能看到登录提示符:

Poky (Yocto Project Reference Distro) 4.0.12 qemuarm64 ttyAMA0

qemuarm64 login: root

输入root,不需要密码,直接登录。然后你就可以在QEMU里跑各种命令了:

# 查看系统信息
uname -a
# 查看内存使用
free -m
# 查看进程
ps aux

嗯,看到这个界面,说明你的Yocto环境已经搭建成功了。从零到能跑起来,这一步很关键。

2.8 避坑指南:我踩过的那些坑

最后,分享几个我实际项目中遇到的坑,希望能帮你省点时间:

  • 磁盘空间不足:Yocto构建非常吃磁盘。一个完整的构建可能占用30-50GB。我建议至少预留100GB。我曾经在只有60GB的虚拟机上构建,结果编译到一半磁盘满了,那叫一个崩溃。
  • 网络问题:Yocto需要从多个源下载源码包。如果你在公司内网,可能需要配置代理。在 local.conf 里加 BB_GENERATE_MIRROR_TARBALLS = "1" 可以生成本地镜像,方便后续离线构建。
  • Python版本冲突:Yocto kirkstone要求Python 3.8以上。如果你系统自带的Python版本太低,建议用 apt install python3.10 或者用conda管理。
  • 不要用root用户构建:Yocto官方明确说不建议用root跑bitbake。因为构建过程中会创建一些文件,root权限可能导致后续清理困难。我习惯用一个普通用户,比如 yocto,专门用来做构建。

好了,这一章的内容就到这里。你跟着做一遍,应该能成功构建并启动一个最小系统。下一章我们会深入Poky的目录结构,看看那些meta层到底是怎么组织的。