Xilinx Zynq - change mender to have rootfs inside fit image

Hi there,

I am continuing some Xilinx Zynq work that Bryan was working on here:

We have a branch for Mender 2.0 that is working with “thud” for Xilinx petalinux 2019.1.

What we want to do is have the roofs.cpio.gz put inside the u-boot FIT image. We are using initramfs, and the whole fit image (including kernel, device tree, and rootfs) should be around 20-30MB. Our app is configured to use the /data partition for persistent storage. So my questions are:

  1. How do I get the initramfs-rootfs to be included inside the mender U-boot FIT image? Currently only the kernel and device tree are included. There is a similar question here, although we have a eMMC, so the MTD raw flash stuff doesn’t apply:
    Read only compressed rootfs in raw flash?

  2. Our rootfs currently includes the device tree plus extra kernel images (all of uImage, vmlinuz, zImage). When booting from a single file FIT image, we don’t need those inside the image, so how do we take them out? Basically, we just want to have /boot/fitImage, where the rootfs when uncompressed doesn’t contain the device tree or kernel images. At that point, they just add a lot of unnecessary size.

  3. I think we should be able to create a fitImageReplace artifact, which would allow us to just replace the single FIT file instead of re-flashing the whole partition (including zero’s). Does that sound right?

Thanks,
Kory

I took a similar approach in using a FIT image to boot from and use as my update artifact. A few notes that might be helpful:

  • The bitbake support in yocto/oe isn’t great and (from memory) the kernel-fitimage.bbclass class doesn’t let you bundle in an initramfs/squashfs image rootfs. I ended up making my own custom-fitimage.bbclass to get around this. The xilinx-fitimage is a decent starting point for this. I now generate a FIT image with a kernel, device tree blob and squashfs blob.
  • If you’re including a kernel binary (uImage or zImage) in the FIT image, I don’t think there’s any reason to also install them into the rootfs. I had to patch the Mender recipes to not install these (the line responsible is MACHINE_ESSENTIAL_EXTRA_RDEPENDS_append_mender-image_arm = " kernel-image kernel-devicetree"). I’m not familiar with Petalinux but there might be some other recipes that cause kernel images to be installed to /boot/ on the rootfs - I’d just grep through the recipe files and see if you can modify the recipe or avoid invoking it all.
  • You will need to patch the Mender uboot patches to work with FIT images. Some of the stuff the Mender uboot functions try to do by default, like loading the kernel from disk and changing the cmdline parameters to boot with a rootfs directly on a disk partition, obviously needs to be different.
  • You might also need to patch the Mender daemon code so that it can successfully recognise the correct partition to flash if you’re going to run with an initramfs out of RAM. See this thread for some more details.

I’d like to eventually contribute some of this work back upstream, but unfortunately it’s time consuming to structure it in a generic way that doesn’t interfere with other use cases.

Thanks for the tips, that really helped.

The petalinux Xilinx Zynq build calls the yocto tools, but essentially it builds yocto recipe “petalinux-user-image”. I was able to remove the devicetree and kernels from the rootfs.cpio.gz by adding the following to the .conf file

MACHINE_ESSENTIAL_EXTRA_RDEPENDS_remove_petalinux-user-image = " kernel-image kernel-devicetree"
MACHINE_ESSENTIAL_EXTRA_RDEPENDS_remove_mender-image_arm = " kernel-image kernel-devicetree"

The other tips I haven’t looked into yet, but they have me heading in the right direction.

I don’t think a custom fitimage.bbclass is needed. I found you could use the standard one, provided your local .conf has something like this:

# Add FIT image dependency
KERNEL_CLASSES = "kernel-fitimage"
KERNEL_IMAGETYPES = "fitImage"
# Specify FIT image variables
# Kernel entrypoint and load address is mandatory for FIT image creation
# Load address for DTB and RootFS is optional
UBOOT_ENTRYPOINT  = "0x80000"
UBOOT_LOADADDRESS = "0x80000"
INITRAMFS_IMAGE_BUNDLE = "1"
INITRAMFS_IMAGE = "petalinux-user-image"
INITRAMFS_MAXSIZE = "16777216"

Hopefully that helps someone else as well.

1 Like