当前位置:首页>Linux>从零构建 Linux|06 Yocto 是什么

从零构建 Linux|06 Yocto 是什么

  • 2026-09-06 14:40:56
从零构建 Linux|06 Yocto 是什么
系列第 6 篇|从「使用 Linux」转向「制作 Linux」阅读顺序:为什么要构建 → Yocto 是什么 → 一张总图 → OE-Core 与 Poky → 源码目录 → Layer → Recipe → 构建时如何协作

到目前为止,我们做了两件事:

  1. 弄懂 Linux 如何从断电变成能跑程序;
  2. 弄懂在 Ubuntu 等发行版上,如何用 apt / yum 安装软件。

从本篇起,问题换成:

我不只想「使用」别人做好的 Linux,还想按自己的需求裁剪并生成一套 Linux 系统镜像。

本篇只建立概念,不要求你马上敲完整构建命令(那是第 7~8 篇)。建议按上面副标题的顺序读:先有总图,再分清 OE-Core 与 Poky,再进目录和文件,最后看它们在构建时怎么串起来。


1. 为什么需要自己构建一套系统

完整发行版(例如桌面版 Ubuntu)适合日常开发:软件多、装包方便。但做产品、做演示镜像、或要体积与行为都可控时,常会碰到:

  1. 镜像太大,里面有大量用不到的软件;
  2. 默认服务太多,启动慢或攻击面变大;
  3. 你希望明确控制:用哪个内核、带哪些驱动、rootfs 里有哪些命令;
  4. 过半年还能用同一套配置复现出几乎一样的镜像。

这时需要的是「按菜谱做饭」的构建系统,而不是永远从应用商店现吃。Yocto 就是工业界很常用的一种。


2. Yocto 是什么(先破除误会)

最常见的误会:

「Yocto 是不是和 Ubuntu 一样,也是一个 Linux 发行版?」

不是。更准确的说法是:

Yocto Project 是一套用来构建定制 Linux 系统的开源工程与工具 / 元数据生态。它帮你「做出发行版一样的东西」,但它本身不是你最终长期登录使用的那个 Ubuntu。
对象
类比
Ubuntu 安装盘
买来就能住的精装房
Yocto
建筑设计工具 + 施工流程 + 材料清单规范
你用 Yocto 构建出的镜像
按图纸盖好的那栋房子

和常见方案怎么选:

方案
适合场景
特点
完整发行版(Debian / Ubuntu)
开发机、服务器、要海量现成软件
现成系统,跑起来后再用 apt 装软件
Buildroot
快速做出较简单的嵌入式根文件系统
轻量的「配置菜单 + 生成 rootfs / 工具链」
Yocto Project
多机型、长期维护、团队协作的定制系统
分层、可复现、偏产品级的构建框架

结合第 5 篇记一句:

  • 发行版:系统跑起来之后再装软件;
  • Yocto:做系统的时候就把软件集成进去。

构建成功后,你通常会得到:内核与模块、rootfs、可写 U 盘 / 硬盘的镜像(如 wic、hddimg),有时还有 SDK。


3. 先建立一张总图(后面所有目录都挂在这张图上)

先别急着看文件夹。用「厨房」把五个词一次记牢:

BitBake     = 厨师(按菜谱一步步执行)Layer       = 抽屉(一组相关菜谱和配置)Recipe(.bb) = 某一道菜的做法(某个软件怎么下载、编译、安装)Image       = 这盒套餐叫什么、默认摆哪些菜(最终整套系统)Machine     = 这锅饭为谁做(虚机 / 真机 PC 等)

再补两个后面会见到的词:

术语
一句话
Distro
全局「口味策略」:默认特性、包格式等(Poky 自带一套)
Class / bbappend
Class = 可复用的公共做法;bbappend = 不改上游、只追加一点点修改

构建时的大致顺序(细节第 7 篇再拆):

打开哪些抽屉(Layer)  → 读清为谁做、加什么菜(Machine / local.conf)  → 按每道菜的做法做菜(Recipe)  → 按套餐装箱(Image)  → 端到出餐口(deploy 目录里的镜像文件)

入门最少记住三句:

  1. Recipe 描述一个软件怎么做进系统;
  2. Machine 描述做给谁用;
  3. Image 描述最终那盘套餐里默认有啥。

有了这张图,下面先分清两个常被混为一谈的名字,再打开 clone 下来的目录。


4. OpenEmbedded-Core 与 Poky

clone 仓库时最常见的误会:

「Poky、Yocto、OpenEmbedded 是不是同一个东西?」

不是。四个名字叠在一起,职责不同:

Yocto Project          = 整个工程与社区(发布、测试、文档、兼容性)OpenEmbedded           = 构建系统这一套工作流与元数据生态OpenEmbedded-Core      = 核心菜谱抽屉(仓库里通常叫 meta/)Poky                   = Yocto 官方入门组合:厨师 + 核心抽屉 + 默认口味 + 参考机型

厨房里可以这样记:

对象
类比
OpenEmbedded-Core
公共基础菜谱:bash、BusyBox、镜像配方、class 等怎么做
Poky
配好灶台的教学厨房:厨师已就位,基础菜谱、默认口味、练手锅都备齐
你 clone 的 poky 仓库
把这间教学厨房整包拎走,开箱就能开火

对照表:

对比项
OpenEmbedded-Core
Poky
是什么
核心元数据层(OE-Core)
Yocto 官方参考发行组合
对应目录
poky 仓库里的 meta/
整个 poky/(含 meta/ 以及其它层)
有没有厨师
不含 BitBake 本体
含 bitbake/
Distro(口味)
不规定「必须用 Poky 这套口味」
有:meta-poky,默认 DISTRO = "poky"
参考机型
一般不含完整 BSP 参考层
有:meta-yocto-bsp(含本系列的 qemux86-64、genericx86-64)
典型用法
厂商/发行版取 OE-Core,再叠自己的 Distro 与 BSP
入门直接 clone,立刻 bitbake
本系列
你会在源码树里看到它叫 meta/;定制时尽量别改这里
动手入口
:本系列 clone 的就是它

关系可以画成:

Poky ├── BitBake              # 厨师 ├── OpenEmbedded-Core    # meta/:核心菜谱 ├── meta-poky            # Distro:Poky 这套口味 ├── meta-yocto-bsp       # 参考机型 └── scripts / 文档       # 开工脚本与说明

记三句即可:

  1. Yocto Project 是工程;Poky 是它提供的入门发行组合。
  2. OpenEmbedded-Core 是核心菜谱,被装进 Poky 的 meta/ 里。
  3. 产品工程常「只要 OE-Core + 自己的 Distro/BSP」,不一定沿用 Poky 这套口味;本系列入门仍从 Poky 开始。

下一节打开目录时,把 meta/ 看成 OE-Core,把 meta-poky/ 看成口味策略,就不会混。


5. 打开源码:clone 之后目录长什么样

入门入口是 Poky:官方参考组合,里面已有 BitBake、OpenEmbedded-Core(meta/),以及可练手的机型配置。

git clone https://git.yoctoproject.org/poky.git -b scarthgap --depth=1cd poky

(分支以官方当前推荐为准;本系列后续示例用 scarthgap。)

5.1 源码树:菜谱库

poky/├── bitbake/           # 厨师程序(BitBake)├── meta/              # OpenEmbedded-Core:核心软件、镜像配方、class├── meta-poky/         # Poky 这套发行策略(Distro 等)├── meta-yocto-bsp/    # 参考机型(含 qemux86-64、genericx86-64)├── meta-skeleton/     # 写自定义层时的骨架示例├── scripts/           # 辅助脚本├── documentation/     # 文档(可选读)└── oe-init-build-env  # 初始化构建环境的入口
路径
对应总图里的谁
bitbake/
厨师
meta/
OE-Core:核心菜谱抽屉
meta-poky/
meta-yocto-bsp/
Distro 口味 + 参考机型
oe-init-build-env
开工前准备灶台的开关
你以后建的 meta-demo/
自己的抽屉
(hello、模板、bbappend 都放这里,尽量别改上游)

5.2 构建目录:施工现场

第一次执行 source oe-init-build-env build-xxx 后,会多出一个不属于 Poky 核心源码的工作目录。本系列约定两个:build-qemux86-64、build-genericx86-64。

build-qemux86-64/          # 示意;真机用 build-genericx86-64├── conf/│   ├── bblayers.conf      # 打开哪些抽屉(Layer 列表)│   ├── local.conf         # 这次为谁做、多加什么、打成什么盒│   └── templateconf.cfg   # (若用模板)记录模板来源├── tmp/                   # 中间产物、rootfs、日志(很大)└── cache/                 # 解析缓存

镜像多在:

build-*/tmp/deploy/images/<MACHINE>/

6. Layer:抽屉里有什么、如何被找到

6.1 一层就是一个约定好的目录

BitBake 只扫描bblayers.conf 里列出的层。没列进去的目录,里面的 .bb 等于不存在。

自定义层最小形态(本系列的 meta-demo 同思路):

meta-demo/├── conf/│   └── layer.conf           # 必有:本层叫什么、去哪找菜谱、优先级├── recipes-example/│   └── hello/│       ├── hello_1.0.bb     # 一道菜│       └── files/hello.c└── conf/templates/          # (本系列)双 MACHINE 的 conf 模板,可选

上游 meta/ 里目录更多,常见只是分类习惯:

目录
典型内容
recipes-core/
 等 recipes-*
各类软件菜谱
classes/.bbclass
 公共逻辑
conf/machine/
某个 MACHINE(如 qemux86-64.conf)
conf/distro/
Distro 策略

真正让 BitBake 找得到菜谱的,是 layer.conf 里的搜索路径,不是目录名字本身。

6.2 layer.conf 在干什么

示意(完整文件一般由 bitbake-layers create-layer 生成):

# conf/layer.conf(示意)BBPATH .= ":${LAYERDIR}"BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \            ${LAYERDIR}/recipes-*/*/*.bbappend"BBFILE_COLLECTIONS += "demo"BBFILE_PATTERN_demo = "^${LAYERDIR}/"BBFILE_PRIORITY_demo = "6"
项
作用
BBFILES
本层 .bb / .bbappend 的查找范围
COLLECTIONS
 / PATTERN
给本层起内部名,并界定归属路径
PRIORITY
多层提供同名菜谱时,谁优先(自己的层通常略高,便于覆盖)

6.3 多层如何叠在一起

meta                 # OE-Core:上游通用软件  + meta-poky        # 发行策略(Poky 口味)  + meta-yocto-bsp   # 机型  + meta-demo        # 你的定制

bblayers.conf 就是「打开哪几只抽屉」的清单。厂商工程(如玄铁)再叠 meta-xxx-bsp,思路相同。


7. Recipe:一道菜怎么写、怎样进最终系统

7.1 一个 .bb 要回答四件事

  1. 源码从哪来(SRC_URI:网址、git、或本地 file://);
  2. 依赖谁(DEPENDS / RDEPENDS 等);
  3. 怎么编、怎么装(手写任务,或 inherit 某个 class);
  4. 最终要不要进镜像(包做出来之后,还靠 Image / IMAGE_INSTALL 选进去)。

文件名惯例:名字_版本.bb,例如 hello_1.0.bb。

7.2 最小示例(本地 C 源码)

与第 8 篇 demo 同思路,先建立「该怎么写」的感觉:

# recipes-example/hello/hello_1.0.bbSUMMARY = "Simple hello world"LICENSE = "MIT"LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"SRC_URI = "file://hello.c"S = "${WORKDIR}"do_compile() {    ${CC} ${CFLAGS} ${LDFLAGS} hello.c -o hello}do_install() {    install -d ${D}${bindir}    install -m 0755 hello ${D}${bindir}/hello}
/* files/hello.c */#include<stdio.h>intmain(void){puts("hello from yocto");return0;}
变量 / 任务
含义
SRC_URI
材料从哪来;本地用 file://
S
源码工作目录
do_compile
编译;${CC} 等由 BitBake 提供
do_install
装进暂存根 ${D};${bindir} 一般是 /usr/bin
LICENSE
 等
许可证声明;缺失常导致解析失败

上游软件更常见的是继承现成流程,而不是手写全部任务:

inherit autotools# 或 inherit cmake / meson / ...

7.3 包做出来了,还要「装进套餐」

core-image-base 也是一种 recipe,但目标不是编一个程序,而是规定:这盒系统默认装哪些包,再打成可启动镜像。

在 local.conf 里写:

IMAGE_INSTALL:append = " hello"

意思是:在选定 Image 的基础上,额外把 hello 包装进 rootfs。

只有 .bb 不够;还要把包装进 Image(或 IMAGE_INSTALL),最终系统里才会有这个命令。

7.4 小改上游:用 bbappend,不要改 meta/ 原文件

换启动图、打小补丁时,在自己的层写 xxx_%.bbappend(% 匹配各版本)。第 9 篇改 psplash / GRUB 时会用到。


8. 串起来:这些文件在构建时各自干什么

执行 bitbake core-image-base 时(流程细节见第 7 篇):

bblayers.conf          → 打开哪些 Layerlayer.conf + 各 .bb    → 收集菜谱、class、machinelocal.conf + Distro + Machine                       → 为谁构建、全局策略、额外装包Image 配方             → 套餐里有哪些包各软件 Recipe          → fetch → unpack → patch → configure                         → compile → install → package组装 rootfs + 出镜像   → build-*/tmp/deploy/images/<MACHINE>/
你维护的文件
构建时作用
典型踩坑
bblayers.conf
启用哪些层
层没启用 → 找不到 hello
local.conf
MACHINE、并行、额外装包、镜像格式
MACHINE 不对 → 产物不能按预期跑
layer.conf
本层如何被发现
搜索路径不对 → 菜谱扫不到
*.bb
某个软件如何变成包
只有 IMAGE_INSTALL、没有 .bb → 仍然没有该软件
*.bbappend
不改上游地修改已有包
—
Image / IMAGE_INSTALL
哪些包装进最终系统
包编出来了但没写进套餐 → 系统里没有

对照第 3 节总图:抽屉、菜谱、套餐、为谁做、厨师——到这里应能对上号。


9. 产业案例与本系列怎么练

平头哥玄铁(了解即可)

国产 RISC-V 生态里,平头哥有面向玄铁的 Yocto 工程(常称 xuantie-yocto-project):在上游之上叠加 BSP 层,提供 machine 与参考镜像。读这类仓库时,优先找 meta-*、conf/machine、README 里的 bblayers / MACHINE——和本篇是同一套语言。

检索:xuantie-yocto-project、平头哥 玄铁 Yocto。

本系列动手约定

对初学者,先在自己的 PC / WSL2 上把「构建 → 启动 → 看到自己的程序」跑通,比同时学新板卡更重要:

项
约定
玄铁工程
对照学习,不是本系列烧写目标
编译宿主
Windows 上的 WSL2 + Ubuntu
目标机
对比 qemux86-64(QEMU)与 genericx86-64(真机 PC)
验证
先 runqemu;再用 U 盘做 Windows 双系统
真机参考
约 16GB 内存、约 1TB 硬盘、已预装 Windows
不做的事
不要求玄铁开发板,不讲板卡串口烧写

本篇小结

  1. Yocto 不是现成发行版,而是「按菜谱做出定制 Linux」的框架。
  2. 先记住总图:BitBake / Layer / Recipe / Image / Machine。
  3. Poky 是入门组合;其中 meta/ 是 OpenEmbedded-Core。build-* 是施工现场;定制放进自己的 Layer。
  4. Recipe 把软件做成包,Image / IMAGE_INSTALL 决定包进不进最终系统。
  5. 玄铁工程用于对照;本系列在 WSL2 构建,用 QEMU + 真机 U 盘验证。

下一篇:真正使用 Yocto 时命令怎么敲、BitBake 如何推进,以及 demo 锁定哪些参数。

系列文章列表:

从零构建 Linux 系统
从零构建 Linux|01 启动流程总览
从零构建 Linux|02 Bootloader
从零构建 Linux|03 内核启动
从零构建 Linux|04 Rootfs、init 与服务
从零构建 Linux|05 包管理

最新文章

随机文章