Chapter 11. Creating Custom Layers
Beyond using existing layers from the community or from vendors, we learn why we create layers for our own products in this chapter. In addition, we discover how to create a machine definition and a distribution, and profit from them to better organize our source code.
Before creating our own layer, it's always a good idea to check whether there is a similar one already available at the following website: http://layers.openembedded.org. If we cannot find a suitable layer for our needs, the next step is to create the directory. Usually, the layer name starts with meta-
, but this is not a technical restriction.
The layer configuration file is required in every layer, and is placed in <layer>/conf/layer.conf
; we can create it manually using any text editor, or populate it with a script provided in Poky, as shown in the following command:
$ ./poky/scripts/yocto-layer create newlayer
The output is shown in the following screenshot:
With the script, we are asked to enter the value for layer priority and answer other questions regarding the sample content that can be generated for the layer. We can use the default values, or enter a custom one. An example of a generated layer is shown in the following figure:
Important variables that may need...
Adding metadata to the layer
The purpose behind the use of layers is to add extra metadata to BitBake's database, or change it.
The most commonly added features are project related, such as applications, libraries, or a service server.
On the other hand, instead of adding new features, it is much more common to accommodate existing feature configurations to our needs, for example, the initial network values for a SSH server, or the custom boot splash image.
It means that we can include several types of metadata files on a new layer— recipes, images, and bbappend
files—to change existing features. The script used to create the new layer can also create two example files: the first one, example_0.1.bb
, is a recipe example; the second one, example_0.1.bbappend
, is a bbappend
example used to modify the feature included in example_0.1.bb
. There are several other examples of bbappend
files on meta-yocto-bsp
and meta-yocto
, and we explore some of their common uses in the next chapter.
Image files can be seen as a set of packages grouped for a purpose and configured in a controlled way. We can either create a new image, including an existing image, adding the needed packages, or overriding configurations, or we can create the image from scratch.
When an image mostly fits our needs and we need to make only minor adjustments to it, it is very convenient to reuse its code. This makes code maintenance easier, and highlights the functional differences. For example, if we want to include an application and remove an image feature from core-image-sato
, we can create an image at recipes-mine/images/my-image-sato.bb
with the following lines of code:
require recipes-sato/image/core-image-sato.bb
IMAGE_FEATURES_remove = "splash"
CORE_IMAGE_EXTRA_INSTALL += "myapp"
On the other hand, we sometimes want to create our image from scratch; we can facilitate our work using the core-image
class, as it provides a set of image features that can be used very easily, for example...
A package recipe is how we can instruct BitBake to fetch, unpack, compile, and install our application, kernel module, or any software provided by a project. Poky includes several classes that abstract the process for the most common development tools as projects based on Autotools, CMake, and QMake. A list of classes included in Poky can be seen in the following reference manual: http://www.yoctoproject.org/docs/2.4/ref-manual/ref-manual.html.
One simple recipe that executes the compile and install tasks explicitly is provided as follows:
DESCRIPTION = "Simple helloworld application"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0b
cf8506ecda2f7b4f302"
SRC_URI = "file://helloworld.c"
S = "${WORKDIR}"
do_compile() {
${CC} helloworld.c -o helloworld
}
do_install() {
install -d ${D}${bindir}
install -m 0755 helloworld ${D}${bindir}
}
The do_compile
and do_install
code blocks provide the Shell Scripting...
Adding support to a new machine definition
Creating a new machine to be used by Poky is a straightforward task. It essentially provides the information needed for a machine to work. The bootloader, kernel, and hardware support drivers must be checked before starting to integrate the board into the BSP layer.
The Yocto Project supports x86-32, x86-64, ARM32, ARM64, MIPS, MIPS64, and PowerPC, representing the most currently-used embedded architectures.
The prevailing set of variables used in a machine definition is as follows:
TARGET_ARCH
: This sets the machine architecture, for example, ARM and i586PREFERRED_PROVIDER_virtual/kernel
: This overrides the default kernel (linux-yocto
) in case you need to use a specific oneSERIAL_CONSOLES
: This defines serial consoles and their speedsMACHINE_FEATURES
: This describes hardware features, so the software stack needed is included in the images by defaultKERNEL_IMAGETYPE
: This is used to choose the kernel image type, for example, zImage
and uImage
IMAGE_FSTYPES...
Using a custom distribution
The creation of a distribution is a mix of simplicity and complexity. The process of creating the distribution file is very easy; however, the distribution configuration has a high impact in the way Poky behaves, and may cause a binary incompatibility with previously built binaries, depending on the options we use.
The distribution is where we define global options, such as the toolchain version, graphical backends, support for OpenGL, and so on. We should make a distribution only in case the default settings provided by Poky do not fulfil our requirements.
Usually, we intend to change a small set of options from Poky. For example, we remove the X11 support to use a framebuffer instead. We can easily accomplish this by reusing Poky distribution and overriding the variables we need. For example, the sample distribution represented by the file <layer>/conf/distro/mydistro.conf
is as follows:
require conf/distro/poky.conf
DISTRO = "mydistro"
DISTRO_NAME = "mydistro...
MACHINE_FEATURES versus DISTRO_FEATURES
Both DISTRO_FEATURES
and MACHINE_FEATURES
work together to provide feasible support on the final system.
When a machine supports a feature, this does not imply that it is being supported by the final system because the distribution used must provide the underlying base for it.
If a machine supports Wi-Fi but the distribution does not, the applications used by the operating system will be built with Wi-Fi support disabled, so that the outcome will be a system without Wi-Fi support.
On the other hand, if the distribution provides Wi-Fi support and a machine does not, the modules and applications needed for the Wi-Fi will not be installed in images built for this machine, though the operating system and its modules have support for Wi-Fi enabled.
Understanding the variables scope
The BitBake metadata has thousands of variables, but the scope where these variables are available depends on where it is defined. Basically, there are two kinds of variables as follows:
- Variables defined in configuration files are global to every recipe. The parsing order of the main configuration files is shown as follows:
build/conf/local.conf
<layer>/conf/machines/<machine>.conf
<layer>/conf/distro/<distro>.conf
- Variables defined within recipe files are local to the specific recipe only during the execution of its tasks
In this chapter, we learned the reasons that motivate us to create a new layer and metadata. We saw a description of how to create machine configuration, a distribution definition, and recipes files. We learned how we can create images and how to include our application in an image.
In the next chapter, we will access some examples of the most common customization cases used by an additional layer, such as modifying existing packages, adding extra options to autoconf
, applying a new patch, and including a new file to a package. We will see how to configure BusyBox and linux-yocto
, two packages commonly customized when making an embedded system.