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