Home » Yocto Development Environment With Docker

Yocto Development Environment With Docker

  • by
yocto

Introduction

In this blog post, we will present the usage of docker containers as a development environment for an Embedded Linux BSP development project based on yocto and open embedded.

Nowadays Docker and containers, in general, are virtually everywhere, due to their versatility when it comes to solving application dependencies and packaging problems. At DigitalGate we are using Docker for many tasks from CI pipelines up to scalable IoT devices that need to provide a generic interface for integration of third-party applications. As an IDE we will be using Visual Studio Code, due to its excellent remote development capabilities. Visual Studio Code is an excellent IDE when it comes to development inside Docker Containers.

One advantage of doing Embedded Linux development inside Docker containers is the platform independence of the development environment. All dependencies of the build system are packaged inside the docker containers. Developers only need  to have docker installed, such setups are ideal for corporate environments where for e.g. Windows is the de-facto platform for development machines

Host Environment Setup

As a first step in setting up our development environment, we will need to install Docker on our machine. For the purpose of this article, we will be using a Windows 10 machine with Docker version 19.03.13 installed. You can find the steps to install docker at the following link: https://docs.docker.com/desktop/windows/install/. Once Docker is installed, we will proceed to implement our docker-compose files. The files will describe our development environment and the tools that we need to install on it. The packages that we need to install are specified in the Yocto user manual https://www.yoctoproject.org/docs/1.8/yocto-project-qs/yocto-project-qs.html

The steps for setting up the environment and installing the required dependencies for Yocto will be done in our Dockerfile that defines the base image that we will be using.

Docker-compose script

The following docker compose file implements our development platform, it describes the following:

  • OS that we will be emulating inside the docker container, in this case, Ubuntu 18.04;
  • The various volumes that we will be using to map the project files from the host PC into the docker container;
  • Network interfaces that we will share with the host. In this particular case, we will run in bridged mode so the container has access directly to the network interfaces of the host machine.
docker services
				
					version: "2"
services:
  yocoto-dev-enviroment:
    build: .
    networ_mode: bridge
    volumes:
      - ../:/yocoto-dev-enviroment/
    working_dir: /yocoto-dev-enviroment
    command: sleep infinity
    environment:
      - DEBIAN_FRONTEND=noninteractive


				
			

Development Environment Image

The docker image that we will be using for the development docker container is based on Ubuntu 18.04. Inside the docker file, we can specify all the packages that we need to install such that all packages required by Yocto are installed while the container is built.

				
					RUN apt-get install -y \
    bc \
    build-essential \
    chrpath \
    cpio \
    debianutils \
    diffstat \
    dos2unix \
    fop \
    g++-multilib \
    gawk \
    gcc-multilib \
    git-core \
    git-lfs \
    iputils-ping \
    libegl1-mesa \
    libncurses5-dev \
    libsdl1.2-dev \
    pylint3 \
    python3 \
    python3-dev \
    python3-git \
    python3-jinja2 \
    python3-pexpect \
    python3-pip \
    socat \
    texinfo \
    tmux \
    unzip \
    vim \
    wget \
    xsltproc \
    xterm \
    openssl \
    tree \
    xz-utils

				
			

Once all required packages are installed we can proceed to configure the locales and permissions for the various directories on the container filesys such that the build directories and artifacts can be shared with the host pc and with the board bootloader which boots the Linux image via Ethernet.

				
					RUN apt-get update && apt-get install -y \
    apt-utils locales sudo && \
    dpkg-reconfigure locales && \
    locale-gen en_US.UTF-8 && \
    update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*
ENV LANG en_US.utf8

				
			

An additional step is the configuration of a non-root user, by default the container has only the root user but bitbake cannot run under the root user. We need to create a user and add it to the sudoers group such it can run commands as root.

				
					ARG host_uid=1001
ARG host_gid=1001
RUN groupadd -g $host_gid $USER_NAME && \
    useradd -g $host_gid -m -s /bin/bash -p $(openssl passwd -crypt $PASS) -u       $host_uid $USER_NAME && \
    echo "build ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers

				
			

One handy configuration is to switch to the non-root user at the end of the Dockerfile since anyways all commands that we will execute inside the docker container are required to run under a non-root user.

				
					USER $USER_NAME
				
			

Once the script is done we can run it using Visual Studio remote containers extension. This will trigger the docker daemon to build our image and open the Yocto workspace inside the newly created container.

From now on we can proceed with setting up the bitbake environment for building our images. In this particular example, we will build a custom image for the sama5d2 xplained board.

In order to automate the initialization of the built environment for bitbake, we will use a small shell script. It performs the following actions.

Clones all required layers for the build:
  • Poky;
  • Openembedded;
  • meta-atmel;
  • meta-aws;
  • meta-qt.

Sources the bitbake init script which will set up our build environment inside which the various bitbake commands for layer, recipe creation, machine configuration, etc. can be run.

Adds the required layers to the build configuration using the bitbake-layers add-layer comman

				
					#!/bin/bash -xe

#layers on which our image depends
POKY_REPO=git://git.yoctoproject.org/poky.git
OPENEMBEDDED_REPO=git://git.openembedded.org/meta-openembedded.git

# Setup all source directories
if [ ! -d /opt/build ] ; then
   git clone "$POKY_REPO" -b dunfell  /opt/build/poky
   git clone "$OPENEMBEDDED_REPO" -b dunfell /opt/build/meta-openembedded
fi

# initialize build directory
source /opt/build/poky/oe-init-build-env /opt/build

# add all required layers to the build
bitbake-layers add-layer meta-openembedded/meta*/
bitbake-layers add-layer /yocoto-dev-enviroment/layers/meta-atmel/
bitbake-layers add-layer /yocoto-dev-enviroment/layers/meta-aws/
bitbake-layers add-layer /yocoto-dev-enviroment/layers/meta-custom-app/

				
			

Once this is done the directory will be changed to the bitbake directory. Here we can start the build of an imag. For example, micro-chip-graphics-image, which includes support for the graphics interfaces on the board.

Conclusion

In conclusion, using a fully dockerized development environment for embedded Linux development is an efficient way to ensure reproducible builds and setups across an entire team. At the same time, it allows us to work in parallel on multiple projects with various setup requirements on the same machine. A dockerized development environment also enables us to keep a clean development machine that is not polluted with project-specific packages.

See other articles:

Software testing

The investigation of artifacts and the behavior of the software under test is known as software testing. It also determines whether the actual results match

Read More »
services

Component placement  

Component placement is one of the most critical parts of PCB design. First, you must understand the fundamental criteria for arranging components on a printed

Read More »

Linux System Programming

This article focuses on Linux system calls and other low-level operations, such as the C library’s functions. System programming is the process of creating system software, which is

Read More »
emc

EMC Testing

When an electrical product is tested for electromagnetic compatibility (EMC), it is determined whether or not it will perform satisfactorily in the electromagnetic environment in

Read More »
Hardware

BSP Development Process

Every board comes with a base BSP (Board Support Package) from the manufacturers. However, in most of the cases, different levels of customization are required

Read More »

BSP Development Costs

The Board Support Package (BSP) represents the software link layer that allows, traditionally a real-time operating system (RTOS), to run on a particular hardware environment.

Read More »

Leave a Reply

Your email address will not be published.