尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Yocto项目入门——自定义Linux发行版的构建流程

Yocto项目入门——自定义Linux发行版的构建流程
📅 发布时间:2026/7/6 18:09:18

文章目录

      • 每日一句正能量
      • 一、引言:为什么需要Yocto
      • 二、Yocto项目架构全景
        • 2.1 核心组件
        • 2.2 与Buildroot的对比
      • 三、Layer:Yocto的分层架构
        • 3.1 Layer层次结构
        • 3.2 Layer目录结构
      • 四、Recipe:软件包的构建配方
        • 4.1 Recipe结构详解
        • 4.2 任务执行顺序
      • 五、BitBake:任务调度引擎
        • 5.1 依赖解析与调度
        • 5.2 常用BitBake命令
      • 六、自定义Layer创建实战
        • 6.1 从零创建自定义Layer
      • 七、BSP适配:为RK3568添加板级支持
        • 7.1 机器配置
        • 7.2 内核Recipe扩展
      • 八、高级技巧与最佳实践
        • 8.1 镜像定制技巧
        • 8.2 包管理配置
        • 8.3 SDK生成与使用
      • 九、常见问题与排查
      • 十、总结

每日一句正能量

为人处世,既需有宏大视野,也要有躬身入局的担当。
大局观让你不陷于琐碎,能看清方向;但光想不做、袖手旁观,再大的格局也是空中楼阁。真正成熟的人,既能仰望星空,也能撸起袖子解决具体问题。


一、引言:为什么需要Yocto

嵌入式Linux开发面临一个经典困境:厂商提供的SDK往往基于某个特定版本的Linux内核和根文件系统,当需要更换内核版本、添加新驱动、裁剪不需要的软件包、或者为不同硬件平台构建镜像时,开发者常常陷入"手动修改-反复编译-兼容性调试"的泥潭。

Yocto Project 提供了一套完整的解决方案:通过声明式的元数据(Metadata)描述整个Linux系统的构建过程,从源码下载、补丁应用、配置编译到镜像生成,全部自动化、可复现、可定制。

对于 HarmonyOS 生态中的设备(如 RK3568、HiSilicon 等芯片平台),Yocto 是构建底层 Linux 内核和根文件系统的标准工具。掌握 Yocto,意味着掌握从源码到镜像的完整控制权。


二、Yocto项目架构全景

2.1 核心组件

Yocto Project 的核心组件包括:

组件职责类比
BitBake任务调度引擎,解析元数据、构建依赖树、调度执行Makefile 的"超级升级版"
OpenEmbedded (OE)构建系统的核心框架,提供基础类、任务、变量构建系统的"操作系统"
PokyYocto 的参考发行版,包含 OE-Core + meta-poky + meta-yocto-bsp参考实现模板
Layer元数据的集合,按功能/硬件/厂商分层组织代码的"模块化包"
Recipe描述如何构建单个软件包的配方文件软件包的"构建脚本"

构建流程:

源码层 (Linux/U-Boot/应用源码) ↓ BitBake 解析 Recipe → 构建依赖树 → 计算任务哈希 ↓ 检查共享状态缓存 (sstate-cache) ↓ 并行执行构建任务 (fetch → unpack → patch → configure → compile → install → package) ↓ 输出产物 (内核镜像 / 根文件系统 / Bootloader / SDK / 部署镜像)
2.2 与Buildroot的对比

维度手动构建BuildrootYocto Project
灵活性低中极高(Layer可叠加、可覆盖)
可维护性极低中高(元数据版本化管理)
构建速度中快慢(首次),快(增量+sstate)
包管理无基础完善(RPM/DEB/IPK)
可复用性无低高(Layer跨项目共享)
学习曲线低中高

选择建议:

  • 快速原型验证、简单系统 → Buildroot
  • 产品化、多平台、长期维护、需要包管理 → Yocto Project

三、Layer:Yocto的分层架构

3.1 Layer层次结构

Layer 是 Yocto 最核心的设计概念。它将构建元数据按功能、硬件、厂商分层组织,高优先级的 Layer 可以覆盖低优先级 Layer 中的配置。

标准Layer层次(从底到顶):

层级典型Layer作用
OE-CoremetaOpenEmbedded核心,提供基础类、通用Recipe
Poky参考meta-pokyYocto参考发行版配置
BSP层meta-ti,meta-freescale,meta-rockchip板级支持包,特定芯片的Kernel/Bootloader配置
中间件层meta-qt,meta-python,meta-networking特定功能域的软件包集合
用户自定义meta-custom,meta-<product>产品-specific配置、自定义Recipe、镜像定义

优先级规则:

  • bblayers.conf中后出现的 Layer 优先级更高
  • 高优先级 Layer 的 Recipe 可以覆盖低优先级同名 Recipe
  • BBFILE_PRIORITY变量显式控制优先级
# bblayers.conf - Layer注册与优先级配置 BBLAYERS ?= " \ /home/yocto/poky/meta \ /home/yocto/poky/meta-poky \ /home/yocto/poky/meta-yocto-bsp \ /home/yocto/meta-openembedded/meta-oe \ /home/yocto/meta-openembedded/meta-python \ /home/yocto/meta-rockchip \ /home/yocto/meta-harmonyos \ /home/yocto/meta-custom \ "
3.2 Layer目录结构
meta-custom/# Layer根目录├── conf/# 配置目录│ ├── layer.conf# Layer配置文件(必需)│ ├── distro/# 发行版配置│ │ └── custom-distro.conf │ └── machine/# 机器配置(BSP)│ └── custom-machine.conf ├── recipes-core/# 核心软件包│ ├── base-files/ │ │ └── base-files_%.bbappend │ └── images/ │ └── custom-image.bb ├── recipes-example/# 示例Recipe│ └── hello/ │ ├── hello_1.0.bb │ └── files/ │ ├── main.c │ └── Makefile ├── recipes-kernel/# 内核相关│ └── linux/ │ └── linux-yocto_%.bbappend ├── recipes-bsp/# BSP相关│ └── u-boot/ │ └── u-boot_%.bbappend ├── classes/# 自定义BitBake类│ └── custom-image.bbclass └── README# 说明文档

四、Recipe:软件包的构建配方

4.1 Recipe结构详解

Recipe 是 Yocto 中最基础的构建单元,以.bb(BitBake)为后缀。一个完整的 Recipe 描述了如何从源码构建一个软件包。

# hello_1.0.bb - 示例Recipe # ============================================================ # 元数据头 # ============================================================ SUMMARY = "Hello World Example Application" DESCRIPTION = "A simple hello world program demonstrating Yocto recipe creation" HOMEPAGE = "https://example.com/hello" LICENSE = "MIT" LIC_FILES_CHKSUM = "file://COPYING;md5=bb5c5b6b7c5b5c5b5c5b5c5b5c5b5c5b" # ============================================================ # 源码获取 # ============================================================ SRC_URI = "git://github.com/example/hello.git;protocol=https;branch=main" SRCREV = "v1.0.0" # 或从本地文件 # SRC_URI = "file://${TOPDIR}/../sources/hello-1.0.tar.gz" # 源码解压后的工作目录 S = "${WORKDIR}/git" # ============================================================ # 依赖声明 # ============================================================ # 构建时依赖(编译时需要) DEPENDS = "zlib openssl" # 运行时依赖(安装时需要) RDEPENDS:${PN} = "libc6" # 可选功能配置 PACKAGECONFIG[ssl] = "--with-ssl,--without-ssl,openssl" PACKAGECONFIG[zlib] = "--with-zlib,--without-zlib,zlib" # ============================================================ # 构建任务 # ============================================================ # 配置任务(继承自autotools类时通常不需要重写) do_configure() { # 自定义配置 ./configure --prefix=${prefix} \ --sysconfdir=${sysconfdir} \ --localstatedir=${localstatedir} \ ${@bb.utils.contains('PACKAGECONFIG', 'ssl', '--with-ssl', '--without-ssl', d)} } # 编译任务 do_compile() { oe_runmake -j${BB_NUMBER_THREADS} } # 安装任务 do_install() { # 安装到临时目录${D},后续打包 install -d ${D}${bindir} install -m 0755 ${B}/hello ${D}${bindir}/ # 安装配置文件 install -d ${D}${sysconfdir} install -m 0644 ${S}/hello.conf ${D}${sysconfdir}/ # 安装systemd服务 install -d ${D}${systemd_system_unitdir} install -m 0644 ${S}/hello.service ${D}${systemd_system_unitdir}/ } # ============================================================ # 包分割 # ============================================================ # 将构建产物分割为多个二进制包 PACKAGES =+ "${PN}-config ${PN}-systemd" FILES:${PN}-config = "${sysconfdir}/hello.conf" FILES:${PN}-systemd = "${systemd_system_unitdir}/hello.service" # ============================================================ # 系统服务配置 # ============================================================ inherit systemd SYSTEMD_SERVICE:${PN} = "hello.service" SYSTEMD_AUTO_ENABLE = "enable" # 开机自启
4.2 任务执行顺序

BitBake 将 Recipe 中的指令分解为一系列任务,按依赖顺序执行:

do_fetch → 下载源码(支持git/http/ftp/local) do_unpack → 解压源码到WORKDIR do_patch → 应用补丁(.patch/.diff文件) do_configure → 运行配置脚本(./configure/cmake/meson) do_compile → 编译源码 do_install → 安装到临时目录${D} do_package → 将安装内容分割为二进制包 do_package_write → 生成RPM/DEB/IPK包 do_populate_sysroot → 将头文件/库导出到sysroot供其他Recipe使用 do_build → 默认任务,触发上述所有任务

关键变量:

  • ${WORKDIR}:Recipe的工作目录(如/home/yocto/build/tmp/work/cortexa53-poky-linux/hello/1.0-r0)
  • ${S}:源码目录(解压后的位置)
  • ${B}:构建目录(可能与${S}分离,支持out-of-tree构建)
  • ${D}:安装目标目录(临时根文件系统)
  • ${PN}:包名(Recipe文件名去掉版本号)
  • ${PV}:包版本号
  • ${PR}:包修订号

五、BitBake:任务调度引擎

5.1 依赖解析与调度

BitBake 的核心能力在于依赖解析和并行调度:

1. 解析阶段:

  • 读取bblayers.conf获取所有 Layer
  • 遍历所有.bb和.bbappend文件
  • 解析变量、继承类、任务定义
  • 构建全局依赖图

2. 依赖树构建:

# 查看包的依赖树$ bitbake-gcore-image-minimal# 生成pn-buildlist和task-depends.dot# 查看特定Recipe的依赖$ bitbake-ehello|grep^DEPENDS=$ bitbake-ehello|grep^RDEPENDS=

3. 任务哈希与共享缓存:
BitBake 使用sstate-cache(Shared State Cache)避免重复构建:

  • 每个任务计算输入哈希(源码、配置、依赖)
  • 如果哈希匹配缓存,直接复用上次构建结果
  • 首次构建慢,增量构建极快
# 配置共享缓存(团队共享)SSTATE_DIR ?="/mnt/sstate-cache"DL_DIR ?="/mnt/downloads"# 使用本地镜像加速下载SOURCE_MIRROR_URL ?="http://internal-mirror.company.com/yocto/"INHERIT+="own-mirrors"

4. 并行构建:

# local.conf - 并行配置BB_NUMBER_THREADS="16"# BitBake任务并行数(建议CPU核心数)PARALLEL_MAKE="-j 16"# make编译并行数BB_NUMBER_PARSE_THREADS="8"# 解析阶段并行数
5.2 常用BitBake命令
# 初始化构建环境(每次新终端执行)$sourcepoky/oe-init-build-env build-rk3568# 构建完整镜像$ bitbake core-image-minimal $ bitbake core-image-sato# 带图形界面$ bitbake custom-image# 构建单个包$ bitbake hello $ bitbake-cclean hello# 清理构建$ bitbake-crebuild hello# 强制重新构建# 查看可用镜像$ bitbake-layers show-images# 查看Layer信息$ bitbake-layers show-layers $ bitbake-layers show-recipes $ bitbake-layers show-appends# 查看包依赖$ bitbake-ghello $ dot-Tpngtask-depends.dot-odepends.png# 生成SDK$ bitbake custom-image-cpopulate_sdk# 进入开发shell(用于调试)$ bitbake-cdevshell hello

六、自定义Layer创建实战

6.1 从零创建自定义Layer

步骤1:创建Layer目录结构

# 进入Yocto项目目录cd~/yocto/poky# 使用脚本创建Layer骨架bitbake-layers create-layer meta-harmonyos-rk3568# 或手动创建mkdir-pmeta-harmonyos-rk3568/{conf,recipes-example,recipes-core,recipes-kernel,recipes-bsp}

步骤2:编写Layer配置文件

# meta-harmonyos-rk3568/conf/layer.conf # 必须包含的基本配置 # Layer路径加入BBPATH BBPATH .= ":${LAYERDIR}" # Recipe文件搜索路径 BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ ${LAYERDIR}/recipes-*/*/*.bbappend" # Layer集合名称 BBFILE_COLLECTIONS += "harmonyos-rk3568" # 文件匹配模式(用于确定哪些Recipe属于本Layer) BBFILE_PATTERN_harmonyos-rk3568 = "^${LAYERDIR}/" # Layer优先级(数值越大优先级越高) BBFILE_PRIORITY_harmonyos-rk3568 = "10" # Layer依赖(本Layer依赖的其他Layer) LAYERDEPENDS_harmonyos-rk3568 = "core rockchip" # 兼容的Yocto版本 LAYERSERIES_COMPAT_harmonyos-rk3568 = "scarthgap" # Layer版本 LAYER_VERSION_harmonyos-rk3568 = "1"

步骤3:编写自定义Recipe

# meta-harmonyos-rk3568/recipes-core/images/harmonyos-image.bb # 自定义镜像Recipe SUMMARY = "HarmonyOS Device Image for RK3568" DESCRIPTION = "Custom Linux image for HarmonyOS ecosystem devices based on RK3568" LICENSE = "MIT" # 继承core-image类 inherit core-image # 镜像特性 IMAGE_FEATURES += " \ ssh-server-openssh \ package-management \ hwclock \ splash \ " # 安装到镜像的软件包 IMAGE_INSTALL += " \ kernel-modules \ linux-firmware \ usbutils \ pciutils \ i2c-tools \ spi-tools \ ethtool \ iproute2 \ iw \ wpa-supplicant \ bluez5 \ alsa-utils \ v4l-utils \ libdrm \ mesa \ harmonyos-distributed-service \ harmonyos-softbus \ " # 根文件系统大小(MB) IMAGE_ROOTFS_SIZE ?= "8192" # 额外分区配置 IMAGE_FSTYPES += " wic wic.bmap ext4" # 预装配置文件 ROOTFS_POSTPROCESS_COMMAND += "harmonyos_postprocess;" harmonyos_postprocess() { # 设置主机名 echo "harmonyos-device" > ${IMAGE_ROOTFS}/etc/hostname # 配置网络 install -d ${IMAGE_ROOTFS}/etc/systemd/network cat > ${IMAGE_ROOTFS}/etc/systemd/network/20-wired.network <<EOF [Match] Name=eth0 [Network] DHCP=yes EOF # 创建HarmonyOS数据目录 install -d ${IMAGE_ROOTFS}/data/harmonyos install -d ${IMAGE_ROOTFS}/data/harmonyos/logs install -d ${IMAGE_ROOTFS}/data/harmonyos/config }

步骤4:注册Layer

# 编辑build/conf/bblayers.conf,添加新LayerBBLAYERS ?=" \${TOPDIR}/../poky/meta \${TOPDIR}/../poky/meta-poky \${TOPDIR}/../poky/meta-yocto-bsp \${TOPDIR}/../meta-openembedded/meta-oe \${TOPDIR}/../meta-openembedded/meta-python \${TOPDIR}/../meta-openembedded/meta-networking \${TOPDIR}/../meta-rockchip \${TOPDIR}/../meta-harmonyos-rk3568 \ "# 或使用命令行添加$ bitbake-layers add-layer../meta-harmonyos-rk3568

步骤5:构建验证

# 构建自定义镜像$ bitbake harmonyos-image# 构建输出目录# build/tmp/deploy/images/rk3568-evb/# ├── harmonyos-image-rk3568-evb.wic # 可直接烧录的镜像# ├── harmonyos-image-rk3568-evb.ext4 # 根文件系统# ├── zImage # 内核镜像# ├── rk3568-evb.dtb # 设备树# └── u-boot.itb # Bootloader# 烧录到SD卡$sudoddif=harmonyos-image-rk3568-evb.wicof=/dev/sdXbs=4Mstatus=progress

七、BSP适配:为RK3568添加板级支持

7.1 机器配置
# meta-harmonyos-rk3568/conf/machine/harmonyos-rk3568.conf # RK3568机器配置 # 继承Rockchip基础配置 require conf/machine/include/rk3568.inc # 机器名称 MACHINE = "harmonyos-rk3568" # 内核配置 PREFERRED_PROVIDER_virtual/kernel = "linux-rockchip" KCONFIG_MODE = "--alldefconfig" KBUILD_DEFCONFIG = "rockchip_defconfig" # 设备树 KERNEL_DEVICETREE = "rockchip/rk3568-evb.dtb" # Bootloader PREFERRED_PROVIDER_virtual/bootloader = "u-boot-rockchip" UBOOT_MACHINE = "rk3568_defconfig" # 串口配置 SERIAL_CONSOLES = "1500000;ttyS2" # 分区配置 IMAGE_BOOT_FILES = "zImage rk3568-evb.dtb" WKS_FILE = "harmonyos-rk3568.wks" # GPU/显示配置 MACHINE_FEATURES += " gpu mali-g52" MACHINE_FEATURES += " display hdmi lvds"
7.2 内核Recipe扩展
# meta-harmonyos-rk3568/recipes-kernel/linux/linux-rockchip_%.bbappend # 扩展Rockchip内核,添加HarmonyOS分布式支持 FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" # 添加HarmonyOS分布式补丁 SRC_URI += " \ file://0001-harmonyos-add-distributed-softbus.patch \ file://0002-harmonyos-enable-binder-ipc.patch \ file://0003-harmonyos-optimize-scheduler-for-iot.patch \ file://harmonyos.config \ " # 合并内核配置 do_configure:append() { ${S}/scripts/kconfig/merge_config.sh \ ${B}/.config \ ${WORKDIR}/harmonyos.config } # 添加内核模块 KERNEL_MODULE_AUTOLOAD += " \ harmonyos_softbus \ harmonyos_distributed_sched \ "

八、高级技巧与最佳实践

8.1 镜像定制技巧
# 通过bbappend修改现有Recipe # meta-harmonyos-rk3568/recipes-core/busybox/busybox_%.bbappend # 添加自定义busybox配置 FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" SRC_URI += "file://harmonyos-busybox.cfg" # 启用特定功能 CONFIG_FEATURES:append = " \ CONFIG_FEATURE_FANCY_ECHO=y \ CONFIG_FEATURE_EDITING=y \ CONFIG_FEATURE_TAB_COMPLETION=y \ "
8.2 包管理配置
# local.conf - 包管理配置 # 包格式选择(RPM/DEB/IPK) PACKAGE_CLASSES ?= "package_rpm" # 生成包feed(用于OTA更新) PACKAGE_FEED_URIS = "http://update.harmonyos.com/rpm" PACKAGE_FEED_BASE_PATHS = "rpm" PACKAGE_FEED_ARCHS = "cortexa53" # 生成SBOM(软件物料清单) INHERIT += "create-spdx" SPDX_INCLUDE_SOURCES = "1"
8.3 SDK生成与使用
# 生成SDK(包含交叉编译器、sysroot、环境脚本)$ bitbake harmonyos-image-cpopulate_sdk# 输出# build/tmp/deploy/sdk/poky-glibc-x86_64-harmonyos-image-cortexa53-rk3568-toolchain-5.0.sh# 安装SDK$ ./poky-glibc-x86_64-harmonyos-image-cortexa53-rk3568-toolchain-5.0.sh-d/opt/harmonyos-sdk# 使用SDK$source/opt/harmonyos-sdk/environment-setup-cortexa53-poky-linux $$CChello.c-ohello# 使用交叉编译器$$STRIPhello# 使用strip工具

九、常见问题与排查

问题原因解决方案
构建失败:checksum mismatch源码下载不完整或被修改删除DL_DIR中的文件,重新下载
任务被跳过(setscene)sstate-cache命中使用bitbake -c cleansstate <recipe>清除
找不到RecipeLayer未注册或路径错误检查bblayers.conf和BBFILES
依赖循环Recipe间循环依赖使用bitbake -g查看依赖图,打破循环
磁盘空间不足tmp目录过大清理tmp/或配置TMPDIR到大容量分区
编译器错误交叉编译环境配置错误检查CC/LD/CFLAGS等环境变量

十、总结

Yocto Project 是构建自定义嵌入式Linux发行版的工业标准工具。通过本文的学习,我们掌握了:

  1. Layer分层架构:从OE-Core到用户自定义Layer的优先级叠加机制
  2. Recipe编写:从元数据头到构建任务的完整配方
  3. BitBake调度:依赖解析、任务哈希、共享缓存、并行构建
  4. BSP适配:为RK3568等芯片平台添加板级支持
  5. 镜像定制:从core-image继承,添加HarmonyOS分布式服务
  6. SDK生成:为应用开发提供标准化交叉编译环境

在 HarmonyOS 生态中,Yocto 是构建底层 Linux 基础设施的基石。掌握 Yocto,意味着从"使用厂商SDK"跃升到"掌控整个系统栈",这是每一位嵌入式Linux工程师的必修课。


转载自:https://blog.csdn.net/u014727709/article/details/162639719
欢迎 👍点赞✍评论⭐收藏,欢迎指正

相关新闻

  • React-redux-toastr 终极指南:如何快速集成Redux通知系统到React应用
  • nix-alien技术原理:揭秘ELF二进制依赖解析的魔法
  • Python RESTful API终极实战指南:5个关键步骤解决接口混乱难题

最新新闻

  • 基于TPAFE0808与PIC32的多通道实时信号采集系统设计
  • FocalNet vs Swin Transformer:如何选择最适合你的视觉Transformer模型?终极性能对比指南
  • CRDs-catalog支持的500+ CRD分类指南:快速找到所需资源定义
  • 猫抓Cat-Catch:浏览器资源嗅探扩展的完整使用指南与性能优化
  • ICM-42605与PIC18LF45K22的6DOF运动追踪系统设计
  • SDF项目完全解析:如何快速掌握射线步进技术与距离函数

日新闻

  • AI智能体安全防护框架AgentGuard:从原理到实战部署指南
  • KMX63与PIC18F26K40硬件组合及低功耗设计实践
  • 基于YOLO13改进的门体检测模型:C3k2模块与PoolingFormer技术解析

周新闻

  • 基于YOLOv12的番茄成熟度智能检测系统开发
  • 终极RimWorld模组管理指南:用RimSort告别模组冲突烦恼
  • AI Agent框架开发:从理论到实践的完整指南

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号