Build a custom Linux for your Rasp Pi with Yocto

Tailor-Made

© Lead Image © Author, 123RF.com

© Lead Image © Author, 123RF.com

Article from Issue 229/2019
Author(s):

Yocto is a tool for creating custom Linux images for embedded devices. We'll show you how to create a customized Linux for your Rasp Pi.

Yocto [1] is a distribution builder. The tool helps users create customized images. A custom image is particularly tempting in the embedded environment, where hardware resources are limited.

In the Beginning

Yocto builds images based on recipes. The user can modify the recipe to determine how the system should be structured – you can even specify which compiler will be used for compiling the source code.

Yocto comes with a reference distribution called Poky, which includes many ready-made recipes and is based on OpenEmbedded [2]. A tool called bitbake lets you combine the Poky layer with a hardware-specific board support layer.

One of Yocto's strengths is the many layers available from the start, including layers from most board manufacturers and also from numerous open source projects. Figure 1 shows the extensive and searchable OpenEmbedded Layer Index [3]. Yocto also has an excellent manual [4] that explains all aspects in detail.

Figure 1: The OpenEmbedded Layer Index.

The easiest way to get started with your own image is by downloading poky and meta-raspberrypi and cloning the Git repositories (Listing 1). The convention is to place all layers below poky. It is important to always clone the same branch name of each layer, e.g. Warrior. Warrior is the name of the current Poky version. The layer names usually start with meta-. In fact, Poky contains a large number of meta-* directories, because it consists of several layers.

Listing 1

Cloning Repositories

 

After cloning, you need to create a suitable environment by running the following command:

source oe-init-build-env

This command also updates the PATH variable so that the Yocto tools can be called from anywhere. The command creates a build directory with a conf subdirectory. conf contains two interesting files: bblayers.conf, a list of the layers used, and local.conf, instructions for Yocto on how to build the image.

In the bblayers.conf file, edit the line with meta-yocto-bsp and enter the location of the cloned meta-raspberrypi layer. In local.conf, add the following line:

MACHINE ?= "raspberrypi3"

This line tells Yocto which hardware model the build will be for. Look online for a list of the models supported by the Raspberry Pi layer [5].

Initially Minimal

To check if everything is set up correctly, build a core-image-minimal with the following call from the build directory:

bitbake core-image-minimal

Do not be put off by the time and space required for this action. Yocto builds an image that contains a small Linux system, as well as all the tools needed to build the distribution, such as a compiler. The next build call then works incrementally; in other words, later steps do not need to rebuild the tools created in a previous step.

When the build process is done, examine the build directory. You will find four new subdirectories: cache, downloads, sstate-cache, and tmp. The most interesting of these subdirectories is tmp, in which the resulting image takes its place. Below downloads are downloaded files, and sstate-cache and cache serve the build process as cache storage. In more complex scenarios, several computers can share sstate-cache.

The tmp directory has a number of subdirectories, one of which is called deploy. The deploy directory contains all packages used for the platform and their licenses, as well as the generated image. The core-image-minimal-raspberrypi3.rpi-sdimg file in the tmp/deploy/images/raspberrypi3/ directory is a link to the last successful build.

With the help of the dd command, you can easily transfer the image to an SD card. Be very careful with dd, which overwrites the copy target. Make doubly sure that the correct output device is specified so that you don't accidentally overwrite the operating system.

After plugging in the SD card, search the dmesg output for messages from the last device added; the name of the device appears in the output. You can then specify the device name in the dd command using the of= option:

sudo dd if=core-image-minimal-raspberrypi3.rpi-sdimg of=/dev/mmcblk0 bs=1MB

The if= option refers to the input file, and bs= is the block size.

Once the microSD card is ready, you can insert it into a Raspberry Pi, connect the keyboard and monitor, and boot. Afterwards, you can log in as root without a password.

Customizing the Image

Once the basic image is created, you can customize and extend it. This is a three-step process: First, a new layer is created, then you create a recipe for a new application you wish to integrate, and then a new image recipe.

For the first step, the new layer, run the following command in the poky subdirectory:

bitbake-layers create-layer meta-lm

This command creates the new layer with a sample recipe. Then add this layer to the list in bblayers.conf, which can either be done manually or with the bitbake-layers command:

cd <I>Path/to/Build<I>
bitbake-layers add-layer ../meta-lm

The new layer doesn't do anything until you add a recipe. In the present case, the recipe is a simple small C program in "Hello World" style: lm-hello.c (Listing 2).

Listing 2

lm-hello.c

 

Create a lm-hello directory below recipes-lm and remove the sample recipe. In the new lm-hello directory, you need a lm-hello_1.0.bb file with the contents of Listing 3. The file extension bb stands for BitBake Recipe; the underscore in the filename must be followed by a version number, which will be used later when bitbake builds a package based on the recipe.

Listing 3

lm-hello_1.0.bb

 

The file itself consists of variable declarations and functions. The variables SUMMARY and SECTION act as metadata describing the content. LIC_FILES_CHKSUM contains an MD5 checksum of the license file to ensure that the content has not changed since the recipe was written.

A reference to the source code follows, here in the form of a URI (SRC_URI) and a specific revision (SRCREV) of a Git repository. In this way, different versions of a recipe can exist, each referring to a different revision. The version number of the package is specified by PV; in this case, the number comes from the version identifier in the filename.

The following lines apply to settings for the build process. The lm-hello project is based on a makefile. Yocto can use a variety of build systems, including CMake, Autotools, and custom files. To support them, the file exports the variables EXTRA_OEMAKE and TARGET_CC_ARCH. These variables ensure that the right compiler with the right flags is used.

Whenever bitbake processes a recipe, it goes through a series of steps. This recipe can use default values for most of these steps, except for the installation step. It needs a custom function that first creates a bin directory (${bindir}) below the stage area (${D}), where it then installs the binary of lm-hello.

As soon as the recipe is prepared, you can test it outside an image with bitbake:

cd Path/to/Build
bitbake lm-hello

The result is a package instead of an image. This package can be found at build/tmp/deploy/rpm.

Two things are particularly noteworthy. First, even the simplest recipe always produces three packages at once: An installation package without an appendix in the filename, a development package with dev in the name, and a debug package identifiable by dbg in the name.

Second, the packages are always located in a CPU-specific subdirectory of build/tmp/deploy/rpm (in the example, this is cortexa7t2hf_neon_vfpv4) and not in a subdirectory named after the board. This means that the package can be used on all computers with the same CPU. The bitbake -g option will help you find dependencies associated with the package. (See the box entitled "Finding Dependencies.")

Finding Dependencies

A manifest file attached to a Yocto image contains a list of all included packages, along with their version numbers and architecture details.

For example, the core-image-minimal-raspberrypi3.rpi-sdimg image has a core-image-minimal-raspberrypi3.manifest file. The file contains a line for the lm-hello package, and it says:

lm-hello cortexa7t2hf_neon_vfpv4 1.0+git0 +6c2970ab52

To find the dependencies for the package, use the bitbake command with the -g option:

bitbake -g lm-hello

This command creates two files, task-depends.dot and recipe-depends.dot. The first file describes the order in which Yocto executes the bitbake tasks, and the second describes the dependencies between the recipes. The .dot files can be rendered to PNGs but are not quickly readable. For the lm-hello package, there are more than 400 dependencies. If you repeat the exercise for lm-image-minimal, you get more than 6,000 dependencies.

You can search the .dot files for information. If, for example, you filter out all rows starting with lm-hello, you see a result like the one in Listing 4. From this information, you can deduce that lm-hello depends on the packages listed on the right. The remaining lines include headers that are not deployed, as well as the C library and other run-time dependencies of the C program.

Listing 4

Filtered Files

 

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Professor Knopper's Lab – Yocto Knoppix

    The professor sets the stage for Knoppix on an SD card that runs on the Raspberry Pi.

  • Yocto

    The Yocto project gives you all the tools you'll need to build a custom Linux for IoT device.

  • Baking Bits
  • Yocto Project and OpenEmbedded Community Join Forces

    “This kind of massive collaboration is exactly what makes Linux the driving force behind today’s new technology innovations.” said Jim Zemlin, executive director at The Linux Foundation.

  • Gnublin

    Embedded Linux doesn’t have to be rocket science, which the Gnublin board clearly shows. If you want to learn how to read sensors, flip switches, and switch LEDs on ARM Linux, this tiny machine is perfect for your research.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More

News