Yocto 产品化

一、产品化要素

二、Layer 架构

poky/
├── meta               # 核心(OE)
├── meta-poky          # Distro 配置
├── meta-yocto-bsp     # 通用 BSP
├── meta-<vendor>      # 厂商 BSP(meta-fsl-arm, meta-ti, meta-st-stm32mp)
├── meta-<distro>      # Distro 扩展
├── meta-<product>     # 产品层(自建)
└── meta-qt6           # Qt6 层

三、Layer 自定义

bitbake-layers create-layer meta-mycompany
cd meta-mycompany
mkdir -p conf/recipes-* recipes-*/myapp recipes-core/images

四、核心配置文件

1. conf/layer.conf

BBPATH .= ":${LAYERDIR}"
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb ${LAYERDIR}/recipes-*/*/*.bbappend"
BBFILE_COLLECTIONS += "mycompany"
BBFILE_PATTERN_mycompany = "^${LAYERDIR}/recipes"
BBFILE_PATTERN_IGNORE_EMPTY_mycompany = "1"
LAYERVERSION_mycompany = "1"
LAYERSERIES_COMPAT_mycompany = "kirkstone langdale mickledore"

2. conf/distro/my-distro.conf

require conf/distro/poky.conf

DISTRO = "my-distro"
DISTRO_NAME = "My Distribution"
DISTRO_VERSION = "1.0"

# C library
TCLIBC = "glibc"

# Init system
DISTRO_FEATURES:append = " systemd wayland x11"
DISTRO_FEATURES:remove = "x11"

# 优化
DISTRO_FEATURES:append = " largefile opengl egl"

3. conf/machine/myboard.conf

#@TYPE: Machine
#@NAME: MyBoard
#@DESCRIPTION: My custom board

require conf/machine/include/imx-base.inc

MACHINE_NAME = "myboard"
MACHINE_GUI_CLASS = "smallscreen"

KERNEL_DEVICETREE = " \
    myboard.dtb \
    myboard-mipi.dtb \
"

SERIAL_CONSOLE = "115200 ttymxc0"

# Image 类型
IMAGE_FSTYPES = "ext4 tar.gz wic wic.bmap"
WKS_FILE = "myboard.wks.in"

五、Image 配方

# my-custom-image.bb
SUMMARY = "My Custom Image"

require recipes-core/images/core-image-minimal.bb

IMAGE_INSTALL:append = " \
    packagegroup-mycompany-core \
    myapp \
    myapp-tools \
    openssh \
    dropbear \
    python3 \
    opencv \
    qtbase \
"

IMAGE_FEATURES:append = " \
    ssh-server-dropbear \
    package-management \
    debug-tweaks \
"

# 关不必要的(基于 core-image-minimal)
IMAGE_INSTALL:remove = "busybox-syslog"

# 自定义 rootfs 后处理
ROOTFS_POSTPROCESS_COMMAND += "my_custom_function; "

my_custom_function() {
    install -d ${IMAGE_ROOTFS}/opt/myapp
    install -m 0755 ${THISDIR}/files/startup.sh ${IMAGE_ROOTFS}/etc/init.d/myapp
}

六、WIC(磁盘镜像)

# myboard.wks.in
part --source bootimg-partition --ondisk mmcblk --fstype=vfat --label boot --active --align 4096 --size 64
part / --source rootfs --ondisk mmcblk --fstype=ext4 --label root --align 4096

bootloader --source rawcopy --sourceparams="file=u-boot.imx" --ondisk mmcblk --offset 1KiB

七、Bbappend 扩展

1. 修改已有包的选项

# recipes-core/busybox/busybox_%.bbappend
# 添加补丁
SRC_URI += "file://0001-busybox-fix.patch"

# 改配置
EXTRA_OECONF:append = " --with-my-option"

# 增加依赖
DEPENDS += "libfoo"

2. 修改内核

# recipes-kernel/linux/linux-yocto_%.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI += "file://myboard.cfg \
            file://0001-my-driver.patch"

八、SDK

# 生成
bitbake -c populate_sdk my-custom-image

# 输出
tmp/deploy/sdk/poky-glibc-x86_64-my-custom-image-armv7at2hf-neon-vfpv4-toolchain-3.1.20.sh

# 安装
./tmp/deploy/sdk/...sh
source /opt/poky/.../environment-setup-armv7at2hf-neon-vfpv4

九、镜像签名与发布

# 烧录镜像
wic create myboard.wks -e my-custom-image
# tmp/deploy/images/myboard/*.wic

# bmap 增量
bmaptool create myboard.wic > myboard.wic.bmap
bmaptool copy myboard.wic /dev/sdX

十、CI 集成

# .gitlab-ci.yml
build:
  image: crops/yocto-build:ubuntu-22.04
  script:
    - source oe-init-build-env build
    - bitbake my-custom-image
    - cp tmp/deploy/images/myboard/*.wic .
  artifacts:
    paths:
      - "*.wic"

十一、版本管理

长期产品用 LTS(Kirkstone)。每 2-3 年升级。

十二、安全

十三、嵌入式常见问题

问题 解决
编译慢 sstate-cache 共享、远端构建
跨团队 明确 layer 划分
长期维护 锁内核版本
BSP 更新 用 BSP layer
大产品 meta- 层组织