Genimage

The core interaction with genimage is via a configuration file, typically written in simple, human-readable text (not XML or JSON, thankfully).

What works well: The syntax is hierarchical and intuitive. You define image blocks. Inside those, you define partition blocks. The beauty lies in its abstraction. You don't need to remember the arcane flags to align an ext4 partition precisely 1MB after the boot sector. You simply write:

image boot.vfat 
  vfat 
    files =  "zImage", "board.dtb"
image sdcard.img 
  hdimage
partition boot 
    partition-type = 0xC
    image = "boot.vfat"
partition root 
    partition-type = 0x83
    image = "rootfs.ext4"

This declarative approach means your build process becomes deterministic. If you commit this config file, anyone on your team can generate the exact same binary layout without reading a 20-page wiki on partition offsets. genimage

While not part of core Yocto, the meta-genimage layer adds a genimage class, allowing recipes to generate images during the build.

Genimage calls host tools. Install dosfstools (provides mkfs.vfat) and mtools on your build machine. The core interaction with genimage is via a

sudo dnf install genimage

Under the hood, Genimage isn't magic; it is ruthlessly mechanical. It creates a sparse file, attaches it to a loop device (a virtual block device in Linux), parses your config, runs fdisk, mkfs, and dd in the right order, and then detaches the loop. This declarative approach means your build process becomes

If a command fails, Genimage cleans up its mess. It doesn't leave a dangling loop device behind. It is the polite guest in your build system.

But the really interesting feature? Variaion support.

One of GenImage’s killer features is creating a complete block image with a partition table, bootloader, kernel, and rootfs. Here’s a config for a typical ARM board:

image sdcard.img 
  # Create an MBR partition table
  hdimage 
    align = 1M
    gpt = false

The Embedded Engineer’s "Swiss Army Knife" for Filesystem Creation