How the Yocto framework brings Linux to IoT devices

Favorite Recipe

© Lead Image © khunaspix, and

© Lead Image © khunaspix, and

Article from Issue 263/2022
Author(s): , Author(s):

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

Hardware has always been a challenge for the Linux community. Although it is possible to compile the Linux kernel and its surrounding applications for almost any hardware, doing so can be complicated. It actually takes significant effort to adapt an operating system for a hardware platform. Giant companies such as Microsoft and Apple have unlimited resources to work out the details with hardware vendors, but Linux has been left largely to its own resources for most of its history.

Today Linux developers are in close contact with mega chip vendor Intel, and Linux has proven its value on ARM, AMD, MIPS, and several other leading hardware platforms. Debian alone supports 10 major architectures, some in multiple variations.

But what happens if you're starting from scratch on a wholly new hardware system? Or if you're designing a new product and the available OS alternatives for the board you're using don't meet your needs? Is Linux an option?

Some Linux distros are already designed for the embedded space, but if they don't offer the features you need – or if they offer too many features you don't need – they can be difficult to adapt. (See the box entitled "OS Options.") The complications of rolling your own system used to rule out Linux for many embedded projects, but Yocto is working to change that perception.

OS Options

One key decision in the development of any IoT project concerns the choice of operating system. The choice of OS could depend on the nature of the project.

For a bare metal environment, no special operating system is needed. Instead, it is up to the application developer to build capabilities into the application. If developers opt for a bare-metal application, they usually implement a hardware abstraction layer (HAL) that removes the need for the application to have to directly access hardware registers.

Other projects require a real-time operating system (RTOS). Data and event processing is always time-critical in RTOS environments, and you can always expect a limit on processing time. RTOS systems are common in the field of robotics, where the consequences can be catastrophic if certain reaction times are exceeded. Much like bare-metal systems, RTOS environments often integrate the operating system and application.

A third category of IoT projects calls for a more complete operating system such as Linux. Unlike with bare metal or RTOS, the application developer does not need access to the OS source code. Instead, the application uses syscalls or device drivers to access the underlying resources.

Figure 1 shows the resource consumption of the three alternatives. Bare-metal systems have the lowest resource requirements, followed by RTOS. Linux consumes by far the most resources, and it requires a processor that has a Memory Management Unit (MMU). On the other hand, Linux as an operating system allows access to a huge selection of ready-made applications and services that are not available for bare metal and RTOS.

The Yocto project [1] describes itself as "…an open source collaboration project that helps developers create custom Linux-based systems for embedded products, regardless of the hardware architecture. The project provides a flexible set of tools and a space where embedded developers worldwide can share technologies, software stacks, configurations, and best practices that can be used to create tailored Linux images for embedded devices [2]."

Yocto, which has been around since 2010, is supported by the Linux Foundation and evolved through a collaboration with the OpenEmbedded project. The Yocto project "…combines, maintains, and validates three key development elements":

  • a set of integrated tools, such as "tools for automated building and testing, processes for board support and license compliance, and component information for custom Linux-based embedded operating systems"
  • a reference embedded distribution, which they call Pokey
  • the OpenEmbedded build system, which is co-maintained by Yocto and the OpenEmbedded project

The overall goal of Yocto is to provide a complete development environment for adapting Linux to run on embedded or IoT devices. That environment includes templates, tools, methods, and working code. The Pokey reference distribution gives the user an example to follow, with instruction files called recipes that the user can adapt as needed.

One of the most powerful features of Yocto is a modular architecture built around layers. A layer is a collection of files and instructions for the build system. Users can mix and match, customizing individual layers as needed while maintaining the simplicity of the overall system. The layer model makes it easy for the hardware vendor to provide support for the OS developer through a Board Support Package (BSP), a layered collection of files used for building in hardware support.

IoT Components

Every Linux for IoT device consists of five main components (Figure 2). First, is the cross-compiler, which makes it possible to compile source code on the developer's PC that will later be executed on the IoT device. The second component is the bootloader, which is executed by the code in the CPU's ROM as soon as the power is turned on. The ROM knows where it can find the boot loader, for example, on an eMMC or MicroSD card, from the status of certain pins of the CPU.

Figure 2: The Linux image for an IoT device consists of five main components.

The code in ROM then configures the boot medium and searches for the boot loader at a preset address. If the boot loader is found, the ROM transfers the code to RAM, where the CPU processes it. The boot loader is responsible for setting up the environment so that the CPU can load and execute the kernel. This could include downloading the kernel from a TFTP server on the network. The most widely used bootloader for IoT devices is called U-Boot.

The third component is the kernel itself, which is used to run various applications simultaneously on the device and provide them with hardware access. The fourth component is the Device Tree (DTS), a part of the kernel sources that informs the CPU about which peripherals the board has and how they are configured. The fifth and final component consists of the actual applications, which are usually found in the root file system (RFS).

Although desktop Linux users are accustomed to downloading an ISO file to a USB flash drive and then using the flash drive to install Linux on their PC, the process works differently for IoT systems. To create all five of the essential components I just described, a framework is required.

The framework is selected by the hardware manufacturer of the System-on-Module (SoM), which contains the CPU and all necessary circuits for power management and signal conditioning. If a company designates a particular SoM for its IoT product, you'll benefit from using the framework provided by the SoM in the form of a BSP.


The BSP consists of different layers, each with its own repository. An SoM provider usually grants third parties access to its BSP in the form of an XML file, which is then called a manifest and lists the appropriate repository for each layer. An example is shown in Figure 3 – this is a BSP from Digi for the System on a Module (SoM) CC6.

Figure 3: The manifest lists the individual repositories for all layers.

The file from Figure 3 uses Android's Repo tool to download all layers. Each layer is created and maintained by a specific organization. For example, in the file, the designations yocto and oe refer to repositories managed by "The Yocto Project." These repos act as the foundation for the entire BSP, providing critical applications such as the BitBake build tool maintained by Yocto and the OpenEmbedded project, as well as reference implementations upon which other layers build.

In Figure 3 you can see that the Meta Freescale layer is also a part of the Yocto layer, although you would actually expect it to be in a repository that manages Freescale/NXP. However, because of the great popularity and frequent use of Freescale CPUs, the Yocto project has adopted this layer. However, there is also a repository provided by NXP, and named NXP, which contains the meta-imx layer. This layer contains configurations, resources, and applications for the iMX series CPUs manufactured by NXP.

You will also find layers managed by Digi, the producer of the SoM, such as meta-digi and meta-digi-dualboot. Finally, you can see that Digi also includes other repositories in the reference BSP, for example, qt5 and swu, which eventually leads to layers named meta-qt5 and meta-swupdate. Digi adds these layers to the BSP to allow it to include frameworks, services, and applications that originate from the organizations that manage these repositories. Figure 4 shows the typical structure of the individual layers.

Figure 4: The structure of a typical layer: In addition to a configuration file, it mainly contains recipes intended for the BitBake build tool.

Each layer contains a configuration directory named conf. This directory in turn contains at least one configuration file that tells the Yocto framework how to handle the recipes brought along by the layer and the Yocto version with which the layer is compatible. In addition, there may be other files that tell the framework how to handle certain configuration options for accessing the hardware.

Each layer includes a set of directories with recipes. A recipe consists of a set of instructions for the make-style build tool BitBake to help it build a particular package. A package can be an application, the Linux kernel, or the whole Linux image. The result is always a single file that can be flashed to the IoT device.

Recipes with similar functionality or ones that address a specific component of the Linux system can be found in the same directory. For example, all recipes that create a kernel module that interacts with custom hardware belong in a recipes-kernel directory. Strict rules for organizing recipes do not exist. Instead, the community and manufacturers follow a set of best practices designed to make finding the right recipe easier.

Figure 4 also shows some files with the .bbappend extension. These files are designed to extend or modify existing recipes. The name of the extension recipe must match the name of the recipe to be extended.

Practical Steps

So far I have described the structure of a BSP based on the Yocto framework. The next steps are to build an image, flash it to an IoT device, customize it, and roll out a small "Hello, World" app. I will used the Digi-CC6N-SBC as the hardware.

The developer's PC needs to meet the requirements for the development computer (see Table 1). In addition, certain software packages must be installed on the machine. You can set up the software using the commands in Listing 1. Additionally, you need the Repo tool from Google (see Listing 2).

Listing 1

Software Installation

$ sudo apt-get install gawk wget git-core diffstat unzip texinfo gcc-multilib \
  g++-multilib build-essential chrpath socat libsdl1.2-dev xterm minicom

Listing 2

Set Up Repo

$ sudo curl -o /usr/local/bin/repo
$ sudo chmod a+x /usr/local/bin/repo

Table 1

Development Computer


64 bit, 8 cores

Operating system

Ubuntu 18.04 LTS



Mass media

250GB free space

Using the Repo tool, you can now move on to the Digi manifest file (Listing 3, first two lines). You then need to configure the BSP for the CC6 (third line). The directory structure now looks like what you can see in Figure 5. You can now create the image with a single call (last line).

Listing 3

Using the Manifest

$ repo init -u -b gatesgarth
$ repo sync -j8 --no-repo-verify
$ source ./ -p ccimx6sbc
$ bitbake dey-image-qt
Figure 5: The subdirectories of a BSP mostly represent the layers the BSP contains.

The image will appear in tmp/deploy/images/ccim6sbc/. You can flash the image to a MicroSD card, which you can then plug into the CC6N board. Then connect the computer to the board via a serial cable and turn on the power. Follow the boot process on the screen (Figure 6).

Figure 6: The screen displays the boot process.

Buy this article as PDF

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

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

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