第4章:Poky参考发行版初探:Poky目录结构、meta层的作用、构建第一个最小镜像

4.1 初见Poky:它到底是什么?

说实话,很多刚接触Yocto的朋友,第一反应就是:「Poky是不是就是Yocto?」

嗯,这个问题我当年也困惑过。简单来说:Poky是Yocto项目的一个参考发行版。它不是一个独立的系统,而是Yocto官方提供的一个「样板间」——里面包含了构建嵌入式Linux所需的核心组件、元数据、以及默认配置。

我个人习惯把Poky比作「毛坯房里的水电管线」。你拿到Poky,就有了构建系统的基础框架。至于装修成什么风格(你的嵌入式产品),那是你后面要干的事。

核心要点:Poky = BitBake构建引擎 + OpenEmbedded核心元数据 + 一组默认的参考配置。

4.2 Poky目录结构:别被吓到,其实很有规律

我第一次解压Poky源码时,看到满屏的文件夹,说实话有点懵。但用久了你会发现,它的结构非常清晰。咱们挑几个最重要的来说。

目录/文件 作用 我的经验
bitbake/ BitBake构建引擎本体 一般不动它,除非你改构建逻辑
meta/ 核心元数据层(OE-Core) 最常用的层,基础配方都在这里
meta-poky/ Poky发行版专属配置 定义了默认的发行版策略
meta-yocto-bsp/ 参考板级支持包 模拟器qemu的配置就在这
scripts/ 辅助工具脚本 我经常用oe-pkgdata-util查包信息
oe-init-build-env 环境初始化脚本 每次构建前必执行,没有例外

你可能会问:「为什么要有这么多meta目录?」

这就是Yocto的设计哲学——分层。每一层只负责一件事,互不干扰。你想想看,如果所有配方都塞在一个目录里,那维护起来得多痛苦?

4.3 meta层的作用:积木式管理

meta层,说白了就是一组配方的集合。每个meta层就像一盒乐高积木,你挑需要的积木,拼出你的系统。

我在项目中遇到过最典型的场景:客户要求加一个Wi-Fi驱动。我只需要添加一个包含该驱动配方的meta层,然后在配置里声明一下,BitBake就会自动去下载、编译、打包。完全不用动其他层。

我的建议:永远不要把所有配方写在一个层里。按功能拆分——比如meta-bsp放板级支持,meta-app放应用层,meta-vendor放厂商定制。这样后续升级、移植都省心。

常见的meta层类型:

  • 核心层:如meta,提供基础配方,谁都用得上
  • BSP层:如meta-yocto-bsp,针对特定硬件
  • 功能层:如meta-qt5,提供Qt图形框架
  • 发行版层:如meta-poky,定义发行版策略

4.4 构建第一个最小镜像:动手吧

光说不练假把式。咱们现在就来构建一个最小镜像。这个镜像小到什么程度?小到只能启动、登录、跑几个基本命令。但它是你理解整个构建流程的起点。

4.4.1 准备环境

首先,确保你的Ubuntu系统装好了必要的依赖包。我曾经因为漏了chrpath这个包,卡了整整一下午。所以建议你直接跑下面这条命令:

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 \
pylint3 xterm python3-subunit mesa-common-dev zstd liblz4-tool

注意:不同Ubuntu版本依赖包名可能略有差异。如果你用的是22.04,上面这个列表基本够用。如果是更老的版本,记得检查一下。

4.4.2 下载Poky并初始化

我个人习惯把Poky放在~/yocto目录下。你可以按自己的喜好来:

cd ~
mkdir yocto && cd yocto
git clone git://git.yoctoproject.org/poky -b kirkstone
cd poky
source oe-init-build-env build_minimal

执行完source命令后,你会看到终端提示符变了,并且自动进入了build_minimal目录。这说明环境已经初始化好了。

嗯,这里要注意:source oe-init-build-env这个命令,每次打开新终端都要执行一次。它设置了BitBake需要的环境变量,比如TMPDIRBBPATH这些。忘了执行?那BitBake会一脸懵地告诉你找不到配置。

4.4.3 配置目标机器

build_minimal/conf/local.conf文件里,找到MACHINE变量。默认是qemux86-64,也就是QEMU模拟的x86_64机器。咱们就用这个,省得折腾硬件:

MACHINE ??= "qemux86-64"

如果你想构建其他目标,比如树莓派,那就改成MACHINE = "raspberrypi4-64"。不过那是后面章节的事了。

4.4.4 开始构建

构建最小镜像的命令很简单:

bitbake core-image-minimal

然后,你就可以去泡杯咖啡了。第一次构建会下载大量源码包,包括GCC工具链、glibc库、Linux内核等等。在我的机器上(8核、16G内存),大概需要40分钟到1小时。

避坑指南:我曾经在构建到一半时,发现磁盘空间不够了。Yocto构建产物很占地方,一个最小镜像大概需要5-10G的临时空间。建议你确保build目录所在分区至少有50G空闲。

4.4.5 验证成果

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

NOTE: Tasks summary: Attempted 1234 tasks of which 0 didn't need to be rerun, all succeeded.

镜像文件在哪?在build_minimal/tmp/deploy/images/qemux86-64/目录下。你会看到:

  • core-image-minimal-qemux86-64.rootfs.ext4 —— 根文件系统镜像
  • core-image-minimal-qemux86-64.rootfs.tar.bz2 —— 打包的根文件系统
  • bzImage —— Linux内核

用QEMU启动它:

runqemu qemux86-64

你会看到一个终端窗口弹出,里面是正在启动的Linux系统。登录用户名是root,没有密码。

看到登录提示符的那一刻,说实话,我第一次做的时候还挺有成就感的。虽然它只是一个啥都没有的最小系统,但这是你亲手从源码构建出来的。

4.5 本章小结

咱们这一章干了三件事:

  1. 搞清楚了Poky的目录结构——知道什么东西放在哪里
  2. 理解了meta层的作用——积木式管理,各司其职
  3. 亲手构建了第一个最小镜像——从源码到可运行系统

下一章,咱们会深入配方文件的写法。到时候你会发现,理解了meta层,写配方其实就是填空。