Blog

Using build information from Yocto to deploy software updates (part 2)

In our previous post, we discussed the need to check compatibility for software and devices when designing a solution to deploy software updates. We also saw that this entails discovering the hardware device type and the supported device type by the software update.

In this post we will look at how Yocto and OpenEmbedded can be used to obtain this information for builds relying on them.

Importing variables into the device with buildinfo

There is a little known image feature in Yocto called buildinfo that will help us get the required information. Buildinfo is available in Yocto 1.8 and later versions. This image feature will write a set of OpenEmbedded variables to a file /etc/build in the image, which in turn gets written to the target device.

To enable buildinfo, use the following steps.

  1. Go to the build directory, e.g. with source oe-init-build-env.
  2. Open conf/local.conf and append INHERIT += "image-buildinfo".
  3. Build the desired image, e.g. with bitbake -k core-image-minimal.
  4. Run the image, e.g. with runqemu qemuarm, and look at the file generated in /etc/build.

A sample resulting /etc/build file is shown below.

-----------------------
Build Configuration:  |
-----------------------
DISTRO = poky
DISTRO_VERSION = 1.8
-----------------------
Layer Revisions:      |
-----------------------
meta              = fido:cd2c9acdbd75c83790e8144d2a834f5b5de35df0 -- modified
meta-yocto        = fido:cd2c9acdbd75c83790e8144d2a834f5b5de35df0 -- modified
meta-yocto-bsp    = fido:cd2c9acdbd75c83790e8144d2a834f5b5de35df0 -- modified

So now we have a way to get build-time information into our devices!

Device type and the MACHINE variable definitions

One of the first things a Yocto user is exposed to is the MACHINE variable, which is found in conf/local.conf in the build directory. This variable determines the target machine and architecture of the build. Examples include beaglebone, genericx86 and edgerouter.

Clearly the MACHINE variable is an important configuration for the hardware compatibility of the build. However, it is not exactly the same as the Device Type as discussed earlier because there might be differences in peripherals, like network modules which still make the builds incompatible across several devices with the same MACHINE.

The device type should be derived from the MACHINE variable, but allow for an optional extension to flag incompatibility across different MACHINEs. One approach to achieve this is to define another variable that would flag incompatibilities between same MACHINE, e.g. DEVICE_MODEL, and combine the two to set DEVICE_TYPE.

The following variables from conf/local.conf demonstrates this approach.

 DEVICE_MODEL="wifi"
 DEVICE_TYPE="${MACHINE}-${DEVICE_MODEL}"

Using buildinfo to include DEVICE_TYPE

Combining the buildinfo image feature and the variables, we can now write our device compatibility variables to the device.

We already defined the variables in conf/local.conf, so what remains is to tell buildinfo to include them by overriding the IMAGE_BUILDINFO_VARS variable. This can be achieved with the following steps.

  1. Go to the build directory, e.g. with source oe-init-build-env.
  2. Open conf/local.conf and append IMAGE_BUILDINFO_VARS = "DISTRO DISTRO_VERSION MACHINE DEVICE_MODEL DEVICE_TYPE".
  3. Build the desired image, e.g. with bitbake -k core-image-minimal.
  4. Run the image, e.g. with runqemu qemuarm, and look at the file generated in /etc/build.

Inside the running machine, you should see something like the following.

-----------------------
Build Configuration:  |
-----------------------
DISTRO = poky
DISTRO_VERSION = 1.8
MACHINE = qemuarm
DEVICE_MODEL = wifi
DEVICE_TYPE = qemuarm-wifi
-----------------------
Layer Revisions:      |
-----------------------
meta              = fido:cd2c9acdbd75c83790e8144d2a834f5b5de35df0 -- modified
meta-yocto        = fido:cd2c9acdbd75c83790e8144d2a834f5b5de35df0 -- modified
meta-yocto-bsp    = fido:cd2c9acdbd75c83790e8144d2a834f5b5de35df0 -- modified

Including other variables

Now that we know how to define and include variables, we can add more that are relevant. For software updates in particular, the version of the software or image is relevant to determine if an update needs to be deployed or not. This could be done by simply defining SOFTWARE_ID in conf/local.conf to the desired version or revision and including it in /etc/build as well.

This should get us going on the basic information for deploying updates!