Creating flashable mender images for desktop with Yocto

Hey, I was able to create a bootable mender image following this tutorial. But imaging a system like that doesn’t give enough confidence in the long term since, it is hard to reproduce.

So I was trying my hands on using Yocto to produce the images. I was able to stitch together a configuration which successfully prepared a uefiimg. But on introspecting the image, I found the grub config doesn’t have any entries and the rootfs doesn’t have any initramfs. Any ideas what I could be doing wrong.

Here is the grub.cfg.

local.conf

DISTRO ?= "poky"
PACKAGE_CLASSES ?= "package_rpm"
EXTRA_IMAGE_FEATURES ?= "debug-tweaks"
USER_CLASSES ?= "buildstats"
PATCHRESOLVE = "noop"
PACKAGECONFIG:append:pn-qemu-system-native = " sdl"
CONF_VERSION = "2"
MENDER_ARTIFACT_NAME = "release-1"
INHERIT += "mender-full"
MACHINE = "intel-corei7-64"
IMAGE_INSTALL:append = " kernel-image"
INITRD_IMAGE_LIVE="core-image-minimal-initramfs"
MENDER_FEATURES_ENABLE:append = " mender-grub mender-image-uefi"
MENDER_FEATURES_DISABLE:append = " mender-uboot mender-image-sd"

DISTRO_FEATURES:append = " systemd"
VIRTUAL-RUNTIME_init_manager = "systemd"
DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
VIRTUAL-RUNTIME_initscripts = ""

ARTIFACTIMG_FSTYPE = "ext4"
IMAGE_FSTYPES = "uefiimg"

EFI_PROVIDER = "grub-efi"

MENDER_STORAGE_DEVICE = "/dev/nvme0n1p"
MENDER_STORAGE_TOTAL_SIZE_MB="20000"
MENDER_BOOT_PART = "${MENDER_STORAGE_DEVICE_BASE}1"
MENDER_DATA_PART = "${MENDER_STORAGE_DEVICE_BASE}4"
MENDER_ROOTFS_PART_A = "${MENDER_STORAGE_DEVICE_BASE}2"
MENDER_ROOTFS_PART_B = "${MENDER_STORAGE_DEVICE_BASE}3"

bblayers.conf

POKY_BBLAYERS_CONF_VERSION = "2"

BBPATH = "${TOPDIR}"
BBFILES ?= ""

BBLAYERS ?= " \
  /home/hellozee/dev/yocto-stuff/src/poky/meta \
  /home/hellozee/dev/yocto-stuff/src/poky/meta-poky \
  /home/hellozee/dev/yocto-stuff/src/poky/meta-yocto-bsp \
  /home/hellozee/dev/yocto-stuff/src/meta-openembedded/meta-oe \
  /home/hellozee/dev/yocto-stuff/src/meta-openembedded/meta-python \
  /home/hellozee/dev/yocto-stuff/src/meta-openembedded/meta-multimedia \
  /home/hellozee/dev/yocto-stuff/src/meta-openembedded/meta-networking \
  /home/hellozee/dev/yocto-stuff/src/meta-intel \
  /home/hellozee/dev/yocto-stuff/src/meta-mender/meta-mender-core \
  /home/hellozee/dev/yocto-stuff/src/meta-mender/meta-mender-demo \
  "

Don’t have much experience with Yocto and Mender, so most of the config is copied and pasted from all over the internet.

Hi @hellozee,

Thanks for reaching out. The “copied and pasted from all over the internet” is probably the problem here. Looking at the local.conf, I think it will have a number of unintentional effects.

First of all, why do you think you need, respectively try to inject an initramfs? Unless you have a very specific driver or storage combination, it is not needed in a Yocto Project based distro.
→ remove the INITRD_IMAGE_LIVE assignment, and also don’t go looking for it.

Next, the Mender partitions are set with sensible defaults. Unless you have a very specific setup and want/need to modify the partitioning, there is no need to define those.
→ remove the MENDER_BOOT_PART, MENDER_DATA_PART, MENDER_ROOTFS_PART_A and MENDER_ROOTFS_PART_B assignments.

Not exactly important, but still more elegant: use the INIT_MANAGER variable.
→ remove the four lines for enabling systems, and just set

INIT_MANAGER = "systemd"

In a system like that, the Mender defaults should nicely apply
→ remove the MENDER_FEATURES:_ENABLE and MENDER_FEATURES_DISABLE assignments, as well as the IMAGE_FSTYPES and ARTIFACTIMG_FSTYPE ones.

Also, as far as I can tell from the known builds such as this one, the EFI_PROVIDER does not need to be explicitly set.
→ remove the EFI_PROVIDER assignment.

This should give you a build, for example core-image-base or core-image-minimal in .uefiimg form which you can put directly onto the storage and boot, assuming that the MENDER_STORAGE_DEVICE is correct.

If this does not work as expected, please drop the logs here so we can take a look.

Greets,
Josef

1 Like

Excellent, thanks for all the help. It worked as expected. But I have a couple of questions

  • I don’t understand the grub config, the way I read it, it shouldn’t even boot in the first place, without an entry in the grub.cfg and an initrd. How does that work?
  • Can the image be generated with compression? I could add MENDER_COMPRESS_DISK_IMAGE=gzip and MENDER_ARTIFACT_COMPRESSION=zstd_better while using mender-convert but I couldn’t find the equivalent options in the yocto variable list.

Are those mender specific things or Yocto quirks? Which I suspect cause I don’t have much experience with either of the two.

Hi @hellozee,

Great to hear things are working. For your questions:

  • the grub “magic” happens via script. You can find its sources here: GitHub - mendersoftware/grub-mender-grubenv
  • you can pass additional parameters to artefact generation, like compression settings. See the invocation code for more details. You can use the MENDER_ARTIFACT_EXTRA_ARGS variable to hold "--compression zstd_better", which should give the same result as far as I can tell. But remember that the artefact is compressed by default, so you should not need this, the gains will probably neglectible.

This is nothing that I would call a quirk, its just how Yocto builds are done and how Mender is being integrated.

Greets,
Josef