The first time I opened meta/recipes-core/images, the collection of tiny .bb files felt almost too simple for something that eventually became a complete bootable system. That is the useful trick: an image recipe describes the software experience, while the machine configuration and BSP layers supply the board-specific pieces. Keeping those responsibilities separate makes a product image far easier to update.

What Poky, an image recipe, and a BSP each provide

  • Yocto Project is the umbrella project and documentation ecosystem for creating custom Linux distributions.

  • OpenEmbedded-Core (OE-Core) supplies the core metadata, classes, and reference image recipes.

  • Poky is the Yocto Project reference distribution and integration repository. It is useful for learning and validation, but it is not the name of every Yocto-based product.

  • An image recipe selects packages, image features, filesystem formats, and image-generation behavior.

  • A BSP layer supplies a board or SoC family’s machine configuration, kernel, bootloader, firmware, and related metadata.

  • BitBake resolves all of that metadata into tasks and executes the dependency graph.

Start with one compatible release across every layer

Choose a maintained Yocto release and check out the matching branch for Poky and every third-party layer. A layer can declare supported releases through LAYERSERIES_COMPAT; mixing arbitrary branches often produces confusing parse errors or silently incompatible metadata.

Initialize and inspect the build configuration

Poky source directorybash
source oe-init-build-env build
bitbake-layers show-layers
bitbake-layers show-recipes 'core-image-*'
layer                 path                                      priority
meta                  .../poky/meta                             5
...
core-image-minimal:   meta
core-image-base:      meta

Why discovery beats a copied recipe list

  • oe-init-build-env changes the current shell environment and enters the chosen Build Directory.

  • show-layers confirms which metadata BitBake will actually parse and reveals layer priority.

  • The quoted glob reaches BitBake unchanged instead of being expanded by the shell.

  • show-recipes reflects the current branches and enabled layers, so it is more reliable than a historical directory listing.

Choose the smallest useful reference image

  • core-image-minimal is a small bootable image and a good bring-up baseline.

  • core-image-base is console-only but includes fuller support for the target hardware.

  • core-image-full-cmdline provides a broader command-line environment.

  • core-image-weston provides a Wayland/Weston graphical environment when the required layers and machine support are present.

  • Use bitbake-layers show-recipes as the authority for your checkout because image availability changes with metadata.

Select the target machine and build

build/conf/local.confconf
MACHINE = "qemux86-64"
 
# Useful during development; put product policy in a distro or image recipe.
EXTRA_IMAGE_FEATURES:append = " ssh-server-openssh"

Two decisions are being made here

  • MACHINE selects the board or emulator configuration and must be provided by an enabled layer.

  • EXTRA_IMAGE_FEATURES is intended for build-local feature experiments; IMAGE_FEATURES belongs in an image recipe.

  • The leading space is required with BitBake’s :append operator.

  • An SSH feature maps to packages and configuration through the image class; it is more expressive than guessing individual daemon packages.

Yocto Build Directorybash
bitbake core-image-minimal
NOTE: Tasks Summary: Attempted ... tasks of which ... did not need to be rerun and all succeeded.

What BitBake does with that target

  • The argument is the image recipe name without its .bb suffix.

  • BitBake parses recipes and configuration, resolves providers, builds packages, creates the root filesystem, and emits the requested image types.

  • A successful task summary means the build graph completed; it does not prove that the image boots on physical hardware.

  • Subsequent builds reuse shared state and previously completed work when their inputs still match.

Find the actual deploy artifacts

Yocto Build Directorybash
bitbake -e core-image-minimal | grep '^DEPLOY_DIR_IMAGE='
ls -lh tmp/deploy/images/${MACHINE}/
DEPLOY_DIR_IMAGE=".../build/tmp/deploy/images/qemux86-64"
... core-image-minimal-qemux86-64.rootfs.wic ...
... core-image-minimal-qemux86-64.rootfs.manifest ...

Treat deploy as the handoff boundary

  • bitbake -e shows the fully expanded value for this recipe and configuration.

  • The deploy directory can contain kernels, bootloaders, filesystem images, manifests, test data, and symlinks to versioned artifacts.

  • Exact extensions depend on IMAGE_FSTYPES, the machine, and BSP integration; .wic, .wic.bz2, .ext4, and tar archives are possibilities, not guarantees.

  • Files inside tmp/work are task workspaces that can be cleaned or rearranged and should not be your release pipeline’s input.

Create a product image in your own layer

Yocto Build Directorybash
bitbake-layers create-layer ../meta-company
bitbake-layers add-layer ../meta-company
NOTE: Starting bitbake server...
Add your new layer with "bitbake-layers add-layer ../meta-company"

What the layer commands change

  • create-layer generates the conventional layer skeleton and configuration.

  • add-layer records the layer in conf/bblayers.conf for this Build Directory.

  • A product layer keeps custom policy out of Poky and third-party BSP repositories.

  • Commit the layer and reproducible configuration to version control; do not commit the generated tmp directory.

meta-company/recipes-core/images/company-console-image.bbbitbake
SUMMARY = "Company maintenance console image"
LICENSE = "MIT"
 
inherit core-image
 
IMAGE_FEATURES += "ssh-server-openssh"
IMAGE_INSTALL:append = " strace ethtool"

A small recipe with clear ownership

  • inherit core-image supplies the standard root-filesystem and image-generation behavior.

  • IMAGE_FEATURES expresses supported capabilities; IMAGE_INSTALL names concrete OpenEmbedded packages.

  • Package names are OpenEmbedded output package names, which may differ from Debian or RPM distribution names.

  • IMAGE_INSTALL:append needs a leading space and avoids the ordering surprises that can occur with weaker assignment choices.

  • For a large product, move related packages into a custom package-group recipe instead of growing one long line.

Yocto Build Directorybash
bitbake company-console-image
grep -E '^(strace|ethtool) ' tmp/deploy/images/${MACHINE}/company-console-image-${MACHINE}.rootfs.manifest
strace ...
ethtool ...

Verification should inspect the image, not your intention

  • Build the custom recipe by its filename stem.

  • The generated manifest records installed packages and versions for the root filesystem.

  • A successful package build does not imply that package was installed into the final image; the manifest settles that question.

  • Artifact naming can be customized, so list the deploy directory if the illustrative manifest path differs in your BSP.

Choose filesystem and disk-image formats deliberately

IMAGE_FSTYPES requests output formats, while Wic creates partitioned disk images from a kickstart-style .wks description. Many BSPs already select sensible formats and a Wic layout. Review that machine policy before appending another format, because every extra format costs build time and storage.

Where BSP work stops and image work begins

  • Put kernel providers, device trees, bootloader integration, firmware, and machine tuning in the BSP layer.

  • Put the user-space package set and product-facing capabilities in image recipes and package groups.

  • Put organization-wide defaults that apply across images in a custom distribution configuration.

  • Use local.conf for developer-local choices and experiments, not as the only record of product policy.

Common failures and the shortest useful check

  • Nothing PROVIDES the machine: enable the correct BSP layer and use one of its exact machine names.

  • Layer is not compatible: align all layer branches with the chosen Yocto release; do not suppress compatibility checks blindly.

  • Nothing RPROVIDES a package: confirm the output package name with oe-pkgdata-util or recipe packaging metadata.

  • Image is unexpectedly large: inspect the manifest and image features, then move optional tools out of the production package group.

  • Expected `.sdimg` or `.wic` is missing: inspect IMAGE_FSTYPES and the BSP documentation instead of renaming another artifact.

  • A copied `tmp/work` root filesystem disappears: consume files from tmp/deploy/images, because cleaning a recipe legitimately removes work directories.

  • Build succeeds but board does not boot: verify machine/BSP selection, boot media instructions, bootloader, device tree, and serial boot logs.

A release-ready image needs more than a successful build

  • Boot-test the exact deploy artifact on the target board or a supported QEMU machine.

  • Archive the package manifest, build configuration, source revisions, and licensing output with the released image.

  • Pin compatible layer revisions and make the build reproducible outside one developer’s workstation.

  • Remove development-only features, default credentials, and unnecessary network services.

  • Follow the BSP vendor’s writing or flashing instructions; media-device commands are destructive and board-specific.

Authoritative Yocto references