Yocto project: Create your own Linux with black jack and systemd

7 minute read

Published:

You must known that there are a lot of different Linux distributions. They all are linux but they all are different. You can check the most popular distributives on distrowatch.com. But what is the difference between all these distributives? The main difference between 2 distributions are kernel version and packages that installed. Here is the example of all packages from Debian 10. The list has 59013 packages. In the article we will go quickly how you can add/modify packages and create own distributives.

What is Yocto Project

Yocto project is a tool to customize operating system image. It is commonly used in embedded development and the main purpose is to create the image that can be flashed and the image contains the product that developers create.

Long story short it allows to extend or modify existing linux images to fit to your needs (have pre-instaled dependencies).

Dependencies

What you need to install to get Yocto project running on you host:

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

Setup environment

Let’s get the code:

wget https://downloads.yoctoproject.org/releases/yocto/yocto-3.3.1/poky-hardknott-25.0.1.tar.bz2
tar -xvf poky-hardknott-25.0.1.tar.bz2

Now we are ready to start using the Yocto project.

cd poky-hardknott-25.0.1/
mkdir downloads
mkdir qemu-arm

Before we build it we need to source environment and tell to environment where is the build directory.

. oe-init-build-env qemu-arm

Build base image

Before we can build our first image, we need to adjust configs. Edit conf/local.conf file:

DL_DIR ?= "/home/kurbakov/Git/poky-hardknott-25.0.1/downloads"
MACHINE ?= "qemuarm"

By default, Yocto project provides ready to use images. To see then, just run:

find ./meta -name *-image-*.bb

Ẁe want to build the base image with the lowes number of packages. Keep in mind this command will get sources and build it (around 3K packages will be downloaded and compiled). So it might take a lot of time. Depending on your hardware, it can take from 2 hours to many hours. So grap a cup of tea and be ready to wait.

Let’s build our very first image:

bitbake core-image-minimal

All build artifacts can be found in the folder qemu-arm:

ls -l qemu-arm/tmp/deploy/images/qemuarm/

Run the image

Yocto project provides the tool to run the image from QEMU. We will not cover it in the current article. You just need to know is that QEMU is the tool to run virtual machine. It is a commonly used for development. To start our newly build image, you need to run the following command:

runqemu qemuarm nographic

Use login root to login in qemu. We also use nographic option, because the base image does not have any desktop environment, so we will only have an access to the bash. To stop the QEMU and exit:

Ctrl-A X
quit

Create own custom image

Now we know how to build the base image and how to run the image that we built. The next step would be to add our own package to the image.

Each package belongs to the layer. And the whole image is like a collection of layers. Here is the command to see what layers we currently have in the project:

bitbake-layers show-layers

You should see the ouput that will look like this:

NOTE: Starting bitbake server...
layer                 path                                      priority
==========================================================================
meta                  /home/kurbakov/Git/poky-hardknott-25.0.1/meta  5
meta-poky             /home/kurbakov/Git/poky-hardknott-25.0.1/meta-poky  5
meta-yocto-bsp        /home/kurbakov/Git/poky-hardknott-25.0.1/meta-yocto-bsp  5

So we have a layer name, path where it is stored and the priority. Let’s create the new layer that we will use to store our new package.

bitbake-layers create-layer ../meta-custom
bitbake-layers add-layer ../meta-custom

Now our list of layers will look like this:

NOTE: Starting bitbake server...
layer                 path                                      priority
==========================================================================
meta                  /home/kurbakov/Git/poky-hardknott-25.0.1/meta  5
meta-poky             /home/kurbakov/Git/poky-hardknott-25.0.1/meta-poky  5
meta-yocto-bsp        /home/kurbakov/Git/poky-hardknott-25.0.1/meta-yocto-bsp  5
meta-custom           /home/kurbakov/Git/poky-hardknott-25.0.1/meta-custom  6

And here is the folder structure of the newly created layer:

$ tree ../meta-custom
../meta-custom
├── conf
│   └── layer.conf
├── COPYING.MIT
├── README
└── recipes-example
    └── example
        └── example_0.1.bb

3 directories, 4 files

As we can see it has a dedicated folder for recipes. A Yocto recipe is the file that explains where to get the package, how to build it and what dependencies it has. So as you might already understood, add a package to the image means writing a new recipe.

Yocto has multiple ways to create recipies:

  1. Command recipetool create <arguments>
  2. Command devtool add <arguments>
  3. Write manually, because a recipe is just a text file, so you can write it by yourself.

We will use recipetool create <arguments> just as an example. I encourage you to check also other alternatives.

mkdir ../meta-custom/recipes-example/gnuhello
recipetool create https://ftp.gnu.org/gnu/hello/hello-2.10.tar.gz -o ../meta-custom/recipes-example/gnuhello/

Above mentioned commands will create the recipe. It is a hello world recipe. Will just print a hello world string. Nothis special. The file hello_2_10.bb means hello package and revision 2.10. bb is the resolution of the file for BitBake.

This is how the BitBake recipe looks like:

$ cat ../meta-custom/recipes-example/gnuhello/hello_2.10.bb 

# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# (Feel free to remove these comments when editing.)

# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is
# your responsibility to verify that the values are complete and correct.
LICENSE = "GPLv3"
LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504"

SRC_URI = "https://ftp.gnu.org/gnu/hello/hello-${PV}.tar.gz"
SRC_URI[md5sum] = "6cd0ffea3884a4e79330338dcc2987d6"
SRC_URI[sha1sum] = "f7bebf6f9c62a2295e889f66e05ce9bfaed9ace3"
SRC_URI[sha256sum] = "31e066137a962676e89f69d1b65382de95a7ef7d914b8cb956f41ea72e0f516b"
SRC_URI[sha384sum] = "3ba72897cfb76d572423afca9f689e1503c4656bb04a670d3b9a950e88df71551b46917bbe71fc3271970157eeb02bcb"
SRC_URI[sha512sum] = "e301d785135c52575a8b4c35994c0316f8d366451f604eb5e74c1f907077502aebd5a1a32cd1e26cd7ca32c22f4de5623a335f8ae7e735ac977420df664f01de"

# NOTE: if this software is not capable of being built in a separate build directory
# from the source, you should replace autotools with autotools-brokensep in the
# inherit line
inherit gettext autotools

# Specify any options you want to pass to the configure script using EXTRA_OECONF:
EXTRA_OECONF = ""

The name should be unique in the project. If we want to build the recipe, just run:

bitbake hello

If you get error: /bin/bash: line 30: lib/configmake.h-t: No such file or directory, run the command mentioned line above in the error message manually. In my case the command was:

/home/kurbakov/Git/poky-hardknott-25.0.1/qemu-arm/tmp/hosttools/mkdir -p lib/sys

Now you are good to go to the last step, add the custom package to your image.

Extend the image with new recipe

Extending the image requires us just to add one line to the file: conf/local.conf that is inside your build directory.

$cat >> conf/local.conf <<EOF
> IMAGE_INSTALL_append = " hello "
> EOF

It will tell that for the image we want to build we need to add the package hello. So lets build one more time our image:

bitbake core-image-minimal

Nowrun the image:

runqemu qemuarm nographic

Use root as your login. And now in the image just run the following commands, to check that hello was added to the image:

root@qemuarm:~# ls -l /usr/bin/hello 
-rwxr-xr-x    1 root     root         22024 Mar  9  2018 /usr/bin/hello
root@qemuarm:~# /usr/bin/hello
Hello, world!

As we can see, the binary is a part of the image.

What to take out from this article

  1. Yocot Project can allow you to create your own Linux image
  2. The image consis of Layers, each layer has recipies (reciepe is an instruction how to build a package)
  3. Build time is terible. To build an image it might take hours
  4. Yocto Project provides you cross compilation out of the box, it is awesome!

Used resources

  1. Customizing Yocto Based Linux Distribution for Production
  2. Custom-meta layers recipes images in yocto project
  3. Yocto project tutorial baking a minimal linux image from scratch
  4. BitBake guide
  5. Yocto quick start
  6. Yocto kernel development
  7. Yocto quick build tutorial
  8. Yocto Project Documentation
  9. Custom image tutorial
  10. Image from scratch
  11. Meta folder structire