Yocto Project Tutorial: Baking a Minimal Linux Image from Scratch
Tags: linux, opensource, tutorial, computerscience
Published: 2020-12-27 21:27:34

# **Introduction**
Even though I am still a student, I always wanted to share a little of the knowledge that I have acquired throughout my university studies. This is why I’ve decided to write this, my first blog. In this case, I bring a tool that I learned to use in the Introduction to Embedded Systems course and that I found very interesting. This is a copy and paste of a post that I did in [Medium](https://erickof.medium.com/yocto-project-tutorial-baking-a-minimal-linux-image-from-scratch-625b3e65f768).

{% medium https://erickof.medium.com/yocto-project-tutorial-baking-a-minimal-linux-image-from-scratch-625b3e65f768 %}

# **What is the Yocto Project?**
> The Yocto Project is an open-source collaboration project that helps you to create custom Linux-based systems regardless of the hardware architecture [[1](https://www.yoctoproject.org/)].

As they say on their page, the Yocto Project is not an embedded Linux distribution, instead, it creates a custom one for you.

The Yocto Project has several releases. I’ll mention the last five releases but you can find all in [[2](https://wiki.yoctoproject.org/wiki/Releases)].

|  Codename  | Version | Release Date | Current Version | Poky Version |
|:----------:|:-------:|:------------:|:---------------:|:------------:|
|  Hardknott |   3.3   |  April 2021  |        -        |     25.0     |
| Gatesgarth |   3.2   | October 2020 |        -        |     24.0     |
|   Dunfell  |   3.1   |  April 2020  |      3.1.3      |      23      |
|    Zeus    |   3.0   | October 2019 |      3.0.4      |    22.0.3    |
|   Warrior  |   2.7   |  April 2019  |      2.7.4      |     21.0     |

As you can see, the Hardknott version has yet to be released (at least by the time I wrote this post).

> The Yocto Project through the OpenEmbedded build system provides an open-source development environment targeting the ARM, MIPS, PowerPC and x86 architectures for a variety of platforms including x86–64 and emulated ones. You can use components from the Yocto Project to design, develop, build, debug, simulate, and test the complete software stack using Linux, the X Window System, GTK+ frameworks, and Qt frameworks [[3](https://www.yoctoproject.org/docs/1.8/yocto-project-qs/yocto-project-qs.html)].

<figure>
  <img src="https://miro.medium.com/max/700/0*IaJv6IvY6ybNZGBH.png" alt="The Yocto Project Development Environment" style="width:100%">
  <figcaption>The Yocto Project Development Environment. Taken from [<a href="https://www.yoctoproject.org/docs/1.8/yocto-project-qs/yocto-project-qs.html">3</a>]</figcaption>
</figure>

For this tutorial, we will use *Poky Dunfell* because I have worked with it before and had no problems.

# **Why should I use my own custom Linux image?**
General-purpose operating systems, such as Windows, macOS, or most Linux distributions, have several tasks to run in the background, as well as multiple installed applications that we don’t need or will never use on our embedded systems. All these reasons, together with the limited resources of our systems, make these operating systems inefficient or excessive for our poor hardware. Think that you don’t need a text editor, an office package, or a PDF reader in your embedded system if you will work with an IoT device.

Building our own operating systems allows us to install only the dependencies and software that we need. This makes it easier for us to better control and take advantage of our limited hardware and make our system more efficient by executing only the tasks it needs.

# **Before we start**

## **Environment**

Before starting to work with Yocto, we must make sure that we meet some requirements:

* A supported Linux version (like Fedora, OpenSUSE, CentOS, Debian, or Ubuntu). You can check them in [[4](https://www.yoctoproject.org/docs/1.8/ref-manual/ref-manual.html)].
* The OpenEmbedded build system should be able to run on any modern distribution that has the following versions for Git 1.7.8 or greater, tar 1.24 or greater, and Python 2.7.3 or greater [[4](https://www.yoctoproject.org/docs/1.8/ref-manual/ref-manual.html)].
* At least 50 GB of free disk space for image creation.

## **Installing dependencies**

First, we need to install the necessary packages to run Yocto. Let’s open a terminal and copy and paste the next line:

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

<figure>
  <img src="https://miro.medium.com/max/700/1*JMZqFD0lqxf5a7ZES-meiA.png" alt="Img1" style="width:100%">
</figure>

In my case, I already had all packages installed.

## **Installing QEmu**
This is the easiest part, you only need to run:

```shell
$ sudo apt-get install qemu
```

<figure>
  <img src="https://miro.medium.com/max/700/1*37bzyZwQWBmY2UPoUb3qdA.png" alt="Img2" style="width:100%">
</figure>

## **Downloading Poky Dunfell**
There are two options to download *Poky Dunfell*. The first one is to go on this [link](http://downloads.yoctoproject.org/releases/yocto/yocto-3.1.2/poky-dunfell-23.0.2.tar.bz2) and download the *tar.bz* compressed file or type in a terminal:

```shell
$ wget http://downloads.yoctoproject.org/releases/yocto/yocto-3.1.2/poky-dunfell-23.0.2.tar.bz2
```

I will download it to my user folder. It could take a while depending on your connection speed, so be patient.

<figure>
  <img src="https://miro.medium.com/max/700/1*MtkdVrNdmC8bCDlMqIPCLA.png" alt="Img3" style="width:100%">
</figure>

Now, we need to unzip the downloaded file.

```shell
$ tar -xvf poky-dunfell-23.0.2.tar.bz2
```

This will create a new folder called *poky-dunfell-23.0.2* (you can change the name if you want, but it is not necessary). Now let’s enter the directory and show its content.

<figure>
  <img src="https://miro.medium.com/max/700/1*vphy3-txZig6ouiODgFp2w.png" alt="Img4" style="width:100%">
</figure>

# **Baking our Image**

Now, we will create a couple of directories to work with. The first is a folder where Yocto will download all our packages and dependencies (*downloads* folder), and the second one will be used for our image (*qemu-arm* folder). You can name them as you want.

```shell
$ mkdir downloads
$ mkdir qemu-arm
```

<figure>
  <img src="https://miro.medium.com/max/700/0*YR5YRvRKO0CBx1n7" alt="Img5" style="width:100%">
</figure>

We need to execute the script to configure the environment necessary for variables and commands of the Yocto Project, this is the *oe-init-build-env* file. This will go into the *qemu-arm* folder.

```shell
$ . oe-init-build-env qemu-arm
```

Make sure to run this command every time you need to build or rebuild the image.

<figure>
  <img src="https://miro.medium.com/max/700/1*aDKD98PmPRNUXKxLm4ysaQ.png" alt="Img6" style="width:100%">
</figure>

If we take a glance inside the *conf* folder, we can see some configuration files. For this tutorial, we are only interested in the *local.conf* file where we can set the machine architecture and the download folder path. In this, we need to add the following lines to the end of the file changing `<user>` for your user:

```text
DL_DIR ?= “/home/<user>/poky-dunfell-23.0.2/downloads”
INHERIT += “rm_work”
MACHINE ?= “qemuarm”
```

<figure>
  <img src="https://miro.medium.com/max/700/1*nzKdaw3zUw4QVdaV3uFXnA.png" alt="Img7" style="width:100%">
</figure>

You could use other test architectures that come in the *local.conf* file like:

<figure>
  <img src="https://miro.medium.com/max/700/0*kU2L6DuJDdRtResy" alt="Img8" style="width:100%">
</figure>

Comments are written with *#* at the beginning. Another setting you can do is to use the default directory for downloads.

<figure>
  <img src="https://miro.medium.com/max/700/1*Ci5JseN0ezrGnXsQ5pqf5Q.png" alt="Img9" style="width:100%">
</figure>

Finally, we can build our image. This process can take a while… 2–6 hours… depending on your internet connection and the processing power of your workstation (in this case, your computer). But don’t be overwhelmed, thankfully, every time you make a change or add new recipes (set of instructions for building packages [[5](https://www.yoctoproject.org/docs/1.6/dev-manual/dev-manual.html)]), Yocto will simply rebuild the changes and not the entire project, making this process less time-consuming.

```shell
$ bitbake core-image-minimal
```

<figure>
  <img src="https://miro.medium.com/max/700/0*FdlYFlMZYn43T9W_" alt="Img10" style="width:100%">
</figure>

You can rerun the command to see that it will only take a couple of minutes to build.

<figure>
  <img src="https://miro.medium.com/max/700/0*s5tipmN9lyF1uWKc" alt="Img11" style="width:100%">
</figure>

# **Testing our Image**

Now, let’s test our image. Since our image is not graphic but console, we must specify it so that it does not produce an error.

```shell
$ runqemu qemuarm nographic
```

<figure>
  <img src="https://miro.medium.com/max/700/1*QtTIIU69CaSXXb97xHciKA.png" alt="Img12" style="width:100%">
</figure>

<figure>
  <img src="https://miro.medium.com/max/700/1*mx-o6oyUgu6dV6SCwWeDBg.png" alt="Img13" style="width:100%">
</figure>

Now, type *root*, and we are done.

<figure>
  <img src="https://miro.medium.com/max/700/1*_LVxQjFiOivgtAWrFSjonA.png" alt="Img14" style="width:100%">
</figure>

# **Bibliographic References**

[1] "Yocto Project — It's not an embedded Linux distribution — it creates a custom one for you", Yoctoproject.org. [Online]. Available: https://www.yoctoproject.org/. [Accessed: 23- Oct- 2020].

[2] "Releases — Yocto Project", Wiki.yoctoproject.org. [Online]. Available: https://wiki.yoctoproject.org/wiki/Releases. [Accessed: 23- Oct- 2020].

[3] "Yocto Project Quick Start", Yoctoproject.org. [Online]. Available: https://www.yoctoproject.org/docs/1.8/yocto-project-qs/yocto-project-qs.html. [Accessed: 25- Oct- 2020].

[4] "Yocto Project Reference Manual", Yoctoproject.org. [Online]. Available: https://www.yoctoproject.org/docs/1.8/ref-manual/ref-manual.html. [Accessed: 25- Oct- 2020].

[5] "Yocto Project Development Manual", Yoctoproject.org. [Online]. Available: https://www.yoctoproject.org/docs/1.6/dev-manual/dev-manual.html. [Accessed: 26- Oct- 2020].