Genimage ❲Top-Rated ◆❳

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.

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.

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

For modern UEFI systems, you can set precise partition attributes:

partition boot 
    partition-type-uuid = "c12a7328-f81f-11d2-ba4b-00a0c93ec93b"  # ESP
    attributes = 0x8000000000000000  # GPT attribute: Required partition

Here’s a quick comparison of doing it manually vs. using GenImage:

Manual (bash) – ~15 lines:

dd if=/dev/zero of=image.ext4 bs=1M count=64
mkfs.ext4 -b 4096 -N 8192 image.ext4
mkdir -p /mnt/img
sudo mount -o loop image.ext4 /mnt/img
sudo cp -r rootfs/* /mnt/img/
sudo umount /mnt/img

GenImage – 7 lines in a config file:

image image.ext4 
  size = 64M
  filesystem = ext4
  block_size = 4096
  inodes = 8192
  contents = "rootfs"

The GenImage version is not only shorter but also:

The core interaction with genimage is via a configuration file, typically written in simple, human-readable text (not XML or JSON, thankfully). Under the hood, Genimage isn't magic; it is

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.

When populating filesystems directly from a directory, you can exclude files: Here’s a quick comparison of doing it manually vs

image rootfs.ext4 
    ext4 
        rootpath = "build/target_root"
        exclude = [
            "usr/src/.*",       # regex
            "run/*",            # glob
            ".git"
        ]