I have been experimenting with Yocto on my Raspberry Pi for a while, and I thought it would be worth writing a brief introduction on how to do it...
1. Introduction
What is Yocto?
The Yocto Project is a set templates, scripts, tools, and methods that enable us to create custom Linux-based distributions for embedded systems regardless of the hardware architecture.
In other words, Yocto provides recipes to create your own Linux distribution to be executed on a specific hardware.
2. Motivation
Why Raspberry Pi?
- It is a good value for your money. It is not as cheap as other boards, such as Arduino UNO, but it offers far more resources;
- It is highly available;
- It is quite popular among hobbyists and students.
- It provides all the resources available in a Linux desktop: the same applications, libraries, and services. If the software we need to use on your platform is not provided by Yocto, then it is probably provided by OpenEmbedded;
- It enables us to select the pieces of software included in the system. This way we can save resources by adding only what is needed, which is always an advantage when developing embedded systems;
- It enables cross-compiling, which is faster and easier than developing your software on the target platform;
- It is open-source (you can find the source code here).
3. Environment setup
- Create a working folder:$ mkdir ~/my_distro
$ cd ~/my_distro - Get the build system:
$ git clone -b jethro git://git.yoctoproject.org/poky
'jethro' is the nave of the current Yocto release. - Get the BSP overlay for the hardware we are going to use, in this case Raspberry Pi:
$ git clone -b jethro git://git.yoctoproject.org/meta-raspberrypi - Set the environment variables required to build the image. You may specify the folder where the built artifacts will be stored. The folder will be created in case it does not exist. The minimal configuration files will be created as well.
$ cd poky
$ . oe-init-build-env ../build
- Add the Raspberry Pi overlay to the the file conf/bblayers.conf:
$ vi conf/bblayers
After editing the file, it will be like this:
# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
LCONF_VERSION = "6"
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS ?= " \
/home/adriano/my_distro/poky/meta \
/home/adriano/my_distro/poky/meta-yocto \
/home/adriano/my_distro/poky/meta-yocto-bsp \
/home/adriano/my_distro/meta-raspberrypi \
"
BBLAYERS_NON_REMOVABLE ?= " \
/home/adriano/my_distro/poky/meta \
/home/adriano/my_distro/poky/meta-yocto \
" - Select the machine to target the build with:
$ vi conf/local.conf
... and replace the line:MACHINE ?= "qemux86"
... with:
MACHINE ?= "raspberrypi"
4. Building a very basic image
The most basic image available is rpi-hwup-image. To build it, type:
$ bitbake rpi-hwup-image
$ bitbake rpi-hwup-image
This will take a long time to complete in the first time you do it - remember it will download all the required source files and build the entire operating system from scratch! Once it is finished, the built image will be stored in: build/tmp/deploy/images/raspberrypi/rpi-hwup-image.rpi-sdimg
5. Writing the image to the SD card
It is very easy to write the image to the SD disk, but it is also very easy to do something wrong in the process. That is because we need to use dd as root. So be careful to not write the image into the wrong device (into the hard disk, for example). One thing I always do is verifying the connected devices using lsblk:
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 931.5G 0 disk
|-sda1 8:1 0 512M 0 part /boot/efi
|-sda2 8:2 0 923.1G 0 part /
`-sda3 8:3 0 7.9G 0 part [SWAP]
sdb 8:16 1 3.7G 0 disk
|-sdb1 8:17 1 40M 0 part
`-sdb2 8:18 1 3.6G 0 part
sr0 11:0 1 1024M 0 rom
This will show you the block devices connected to the computer. If you are not sure about which device is your SD card, then run lsblk, connect the SD card to the computer, and then run lsblk again. That will show the name of the device name of the connected SD card.
Once you have done that, type:
$ sudo dd if=tmp/deploy/images/raspberrypi/rpi-hwup-image.rpi-sdimg of=/dev/sdX bs=1M
... where /dev/sdX is the device name of the connected SD card.
This will create three partitions in the SD card:
- /dev/sdX1: A fat32 partition containing some configuration files specific to Raspberry Pi;
- /dev/sdX2: An ext4 partition to be mounted as root directory in the target hardware;
- /dev/sdX3: A linux-swap partition.
This should be enough to boot the new operating system, but there is a detail to be solved: the created ext4 partition is exactly the same size as the built image - and it is full. So we need to resize it using a partition editor such as Gparted.
6. Conclusion
The procedure I described creates a minimal operating system for a Raspberry Pi. That operating system is based on an existing recipe and it is just enough to boot the hardware and provide a minimal command prompt.
I hope I have time to describe how to customize this minimal operating system and make it more useful though still saving resources.