Book Image

Using Yocto Project with BeagleBone Black

By : Hafiz Muhammad I Sadiq, Irfan Sadiq
Book Image

Using Yocto Project with BeagleBone Black

By: Hafiz Muhammad I Sadiq, Irfan Sadiq

Overview of this book

Table of Contents (17 chapters)
Using Yocto Project with BeagleBone Black
About the Author
About the Reviewers

Let's build for BeagleBone

By examining the contents of the poky directory, you will notice your terminal executables, as in most of the cases while working with new technologies/packages on *nix systems. Here, we have oe-init-build-env. This is the one responsible for creating our build environment. We will source this script and pass to it our build directory as an argument, as follows:

$  source oe-init-build-env build_bbb

The build_bbb argument can be anything you want. I wanted to keep it simply bbb. However, I cannot do this as my Git Aware Prompt keeps complaining about new content. If you inspect .gitignore, you will see that it has build* in it. So, the directory prefixed with build will be ignored. This command will land you in the newly created build directory. Before moving further, we need to examine this directory. Here, we have a subdirectory named conf and two files, bblayers.conf and local.conf. We will look into bblayers.conf in the upcoming chapters. For now, we will go through the contents of local.conf.


First, we will encounter the following two options, which are related to each other. These options are here to tune the level of parallelism used by BitBake, the actual driver behind Yocto Project. The two options are:

  • BB_NUMBER_THREADS ?= "${@oe.utils.cpu_count()}"

  • PARALL EL_MAKE ?= "-j ${@oe.utils.cpu_count()}"

You will find these variables twice in this file: once in the preceding form and once in the following form:

#PARALLEL_MAKE ?= "-j 4"

We are telling BitBake about the maximum number of threads it should use for the job and the maximum of jobs run in parallel. Most of the Yocto Project manuals and blogs say both of these should be equal to the number of cores available on your system. However, my experience has proven that the following formula gives the maximum throughput, that is, the minimum time of execution:

BB_NUMBER_THREADS ?= "1.5 * Number of cores"
PARALLEL_MAKE ?= "-j 2 * Number of cores"

On a 16-core server, we will use the combinations of 24 and 32, whereas on an 8-core machine we will use 12 and 16. For a 4-core machine, we will use 6 and 8 as follows:



While setting these variables, do not forget the difference of -j n for PARALLE_MAKE. Otherwise, you will encounter errors. Also, note that BitBake requires even numbers to be enclosed in "".

Next, we need to select the machine. Here, we will set BeagleBone, which is already available to us. So, we will uncomment it and comment out the default selection, which is the qemux86 selection. Commenting out an existing selection is not strictly necessary since it is assigned using the ?? operator, which we will discuss in the upcoming chapters.

MACHINE ?= "beaglebone"
#MACHINE ??= "qemux86"

Next, we will set our downloads directory. This directory will be used to download sources for packages. The available configuration variable to set this configuration is DL_DIR. If we don't set this, its default value would be used as our build directory. So, we will have this directory created under the build directory. We usually don't care much in case of Board Support Packages (BSPs) running rm-rf on our build directory to start a fresh build. In such cases, not caring about this variable can cause regrets, as it will download all the sources again and again, causing longer build times. We set it up in the top-level directory, which contains the poky directory itself, so that we don't ever accidentally delete it with other expendable stuff.

DL_DIR ?= "${TOPDIR}/../../downloads"

Next, we have SSTATE_DIR, TMPDIR, and DISTRO, which we will leave unchanged for now. SSTATE_DIR is related to the shared state feature of Yocto Project. Yocto Project has a mechanism to check whether some package is already built and available, it uses the existing package and doesn't build it. TMPDIR is the directory that contains a lot of build stuff. We will go through its contents in the upcoming chapters. Then, we have PACKAGE_CLASSES, as follow:

PACKAGE_CLASSES ?= "package_ipk"

We will leave the remaining variables unchanged.

We can use a lot other options in this file as well. We will learn about some of these options in the upcoming chapters.


While setting values for a variable, always remember to leave spaces on both sides of an operator in order to avoid any surprises.


As the name suggests, bblayers.conf is there to provide us with a mechanism to configure our Yocto Project layers. This file has configurations related to layers. We can add extra layers to this file to use the metadata available in these layers. This file further classifies layers into removable and non-removable ones, as you can see in the following code snippet:

  /home/irfan/yocto/poky/meta \
  /home/irfan/yocto/poky/meta-yocto \
  /home/irfan/yocto/poky/meta-yocto-bsp \
  /home/irfan/yocto/poky/meta \
  /home/irfan/yocto/poky/meta-yocto \

Since we are not using any extra layers, we will leave this file unchanged.


This file is optional. You won't find it created by the build environment creation script. We mostly use system-wide or other configurations common across different builds and targets are put in this file. For example, we would use the toolchain path if we were using an external toolchain. Another option could be specifying mirror sites, we case it for this purpose. If we have this file created, BitBake looks for it and uses common configurations from this file. We override any configuration that we want modified in conf/local.conf.


This is an optional file. Just like the previous file, you won't find it created by the build environment creation script. We can use this file to set our custom options so that we don't have to modify local.conf manually. In most of the cases, this file is used by build systems such as Jenkins. For example, if we don't want our build directory size to explode due to space constraints, we could use the following code file in the local.conf or auto.conf file:

INHERIT += "rm_work"

For now, we don't need to set this. I am just mentioning it here to elaborate the preceding point. Since we will analyze the contents of the tmp/work directory in the upcoming chapters, I would suggest that you do not use this option for the time being.

Trigger build

Now that we have set all the configurations, let's start our build. You can choose any of the images to build. I will prefer core-image-sato:

$  bitbake core-image-sato

Building images for our desired target may take some time, depending on network speed and processing power. After the build is complete, you will have your images ready at tmp/deploy/images/beaglebone/ under your build directory, as shown in the following screenshot. This contains first-level bootloader MLO, second-level bootloader u-boot, kernel image, device tree blobs, a root filesystem archive, and a modules archive.

Here, you will notice that we have symbolic links as well as full names of the files, with time stamp information in most of the cases. Symbolic links always point to the latest file created. We should always try to use a symbolic link for copying to avoid any confusion.

Now that we have our images created by Yocto Project, we are ready to verify these images on our BeagleBone board:

Images directory contents

In case of other images, such as core-image-minimal, core-image-base, and core-image-sdk, the content shown in this screenshot will contain files related to those images instead of core-image-sato.