In this article by Pierre-Jean TEXIER, the author of the book Yocto for Raspberry Pi, covers basic concepts of the Poky workflow. Using the Linux command line, we will proceed to different steps, download, configure, and prepare the Poky Raspberry Pi environment and generate an image that can be used by the target.
(For more resources related to this topic, see here.)
The steps necessary for the configuration of the host system depend on the Linux distribution used. It is advisable to use one of the Linux distributions maintained and supported by Poky. This is to avoid wasting time and energy in setting up the host system. Currently, the Yocto project is supported on the following distributions:
Even if your distribution is not listed here, it does not mean that Poky will not work, but the outcome cannot be guaranteed. If you want more information about Linux distributions, you can visitthis link:
http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html
The following list shows required packages by function, given a supported Ubuntu or Debian Linux distribution. The dependencies for a compatible environment include:
Here is the command to type on a headless system:
$ sudo apt-get install gawk wget git-core diffstat unzip texinfo gcc-multilib build-essential chrpath
If you want to use Fedora, you just have to type this command:
$ sudo yum install gawk make wget tar bzip2 gzip python unzip perl patch diffutils diffstat git cpp gcc gcc-c++ glibc-devel texinfo chrpath ccache perl-Data-Dumper perl-Text-ParseWords perl-Thread-Queue socat
After having installed all the necessary packages, it is time to download the sources from Poky. This is done through the git tool, as follows:
$ git clone git://git.yoctoproject.org/poky (branch master)
Another method is to download tar.bz2 file directly from this repository:
https://www.yoctoproject.org/downloads
To avoid all hazardous and problematic manipulations, it is strongly recommended to create and switch to a specific local branch. Use these commands:
$ cd poky
$ git checkout daisy –b work_branch
At this stage, we only have the base of the reference system (Poky), and we have no support for the Broadcom BCM SoC. Basically, the BSP proposed by Poky only offers the following targets:
$ ls meta/conf/machine/*.conf
beaglebone.conf
edgerouter.conf
genericx86-64.conf
genericx86.conf
mpc8315e-rdb.conf
This is in addition to those provided by OE-Core:
$ ls meta/conf/machine/*.conf
qemuarm64.conf
qemuarm.conf
qemumips64.conf
qemumips.conf
qemuppc.conf
qemux86-64.conf
qemux86.conf
In order to generate a compatible system for our target, download the specific layer (the BSP Layer) for the Raspberry Pi:
$ git clone git://git.yoctoproject.org/meta-raspberrypi
If you want to learn more about git scm, you can visit the official website:
http://git-scm.com/
Now we can verify whether we have the configuration metadata for our platform (the rasberrypi.conf file):
$ ls meta-raspberrypi/conf/machine/*.conf
raspberrypi.conf
This screenshot shows the meta-raspberrypi folder:
The examples and code presented in this article use Yocto Project version 1.7 and Poky version 12.0. For reference,the codename is Dizzy.
Now that we have our environment freshly downloaded, we can proceed with its initialization and the configuration of our image through various configurations files.
As can be seen in the screenshot, the Poky directory contains a script named oe-init-build-env. This is a script for the configuration/initialization of the build environment. It is not intended to be executed but must be "sourced". Its work, among others, is to initialize a certain number of environment variables and place yourself in the build directory's designated argument. The script must be run as shown here:
$ source oe-init-build-env [build-directory]
Here, build-directory is an optional parameter for the name of the directory where the environment is set (for example, we can use several build directories in a single Poky source tree); in case it is not given, it defaults to build. The build-directory folder is the place where we perform the builds. But, in order to standardize the steps, we will use the following command throughout to initialize our environment:
$ source oe-init-build-env rpi-build
### Shell environment set up for builds. ###
You can now run 'bitbake <target>'
Common targets are:
core-image-minimal
core-image-sato
meta-toolchain
adt-installer
meta-ide-support
You can also run generated qemu images with a command like 'runqemu
qemux86'
When we initialize a build environment, it creates a directory (the conf directory) inside rpi-build. This folder contain two important files:
The local.conf file under rpi-build/conf/ is a file that can configure every aspect of the build process. It is through this file that we can choose the target machine (the MACHINE variable), the distribution (the DISTRO variable), the type of package (the PACKAGE_CLASSES variable), and the host configuration (PARALLEL_MAKE, for example). The minimal set of variables we have to change from the default is the following:
BB_NUMBER_THREADS ?= "${@oe.utils.cpu_count()}"
PARALLEL_MAKE ?= "-j ${@oe.utils.cpu_count()}"
MACHINE ?= raspberrypi MACHINE ?= "raspberrypi"
The BB_NUMBER_THREADS variable determines the number of tasks that BitBake will perform in parallel (tasks under Yocto; we're not necessarily talking about compilation). By default, in build/conf/local.conf, this variable is initialized with ${@oe.utils.cpu_count()},corresponding to the number of cores detected on the host system (/proc/cpuinfo).
The PARALLEL_MAKE variable corresponds to the -j of the make option to specify the number of processes that GNU Make can run in parallel on a compilation task. Again, it is the number of cores present that defines the default value used.
The MACHINE variable is where we determine the target machine we wish to build for the Raspberry Pi (define in the .conf file; in our case, it is raspberrypi.conf).
Now, we still have to add the specific layer to our target. This will have the effect of making recipes from this layer available to our build. Therefore, we should edit the build/conf/bblayers.conf file:
# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
LCONF_VERSION = "6"
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS ?= "
/home/packt/RASPBERRYPI/poky/meta
/home/packt/RASPBERRYPI/poky/meta-yocto
/home/packt/RASPBERRYPI/poky/meta-yocto-bsp "
BBLAYERS_NON_REMOVABLE ?= "
/home/packt/RASPBERRYPI/poky/meta
/home/packt/RASPBERRYPI/poky/meta-yocto
"
Add the following line:
# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
LCONF_VERSION = "6"
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS ?= "
/home/packt/RASPBERRYPI/poky/meta
/home/packt/RASPBERRYPI/poky/meta-yocto
/home/packt/RASPBERRYPI/poky/meta-yocto-bsp
/home/packt/RASPBERRYPI/poky/meta-raspberrypi "
BBLAYERS_NON_REMOVABLE ?= "
/home/packt/RASPBERRYPI/poky/meta
/home/packt/RASPBERRYPI/poky/meta-yocto
"
Naturally, you have to adapt the absolute path (/home/packt/RASPBERRYPI here) depending on your own installation.
At this stage, we will have to look at the available images as to whether they are compatible with our platform (.bb files).
Poky provides several predesigned image recipes that we can use to build our own binary image. We can check the list of available images by running the following command from the poky directory:
$ ls meta*/recipes*/images/*.bb
All the recipes provide images which are, in essence, a set of unpacked and configured packages, generating a filesystem that we can use on actual hardware (for further information about different images, you can visit http://www.yoctoproject.org/docs/latest/mega-manual/mega-manual.html#ref-images).
Here is a small representation of the available images:
We can add the layers proposed by meta-raspberrypi to all of these layers:
$ ls meta-raspberrypi/recipes-core/images/*.bb
rpi-basic-image.bb
rpi-hwup-image.bb
rpi-test-image.bb
Here is an explanation of the images:
We will take one of these three recipes for the rest of this article. Note that these files (.bb) describe recipes, like all the others. These are organized logically, and here, we have the ones for creating an image for the Raspberry Pi.
At this point, what remains for us is to start the build engine Bitbake, which will parse all the recipes that contain the image you pass as a parameter (as an initial example, we can take rpi-basic-image):
$ bitbake rpi-basic-image
Loading cache: 100% |########################################################################################################################################################################| ETA: 00:00:00
Loaded 1352 entries from dependency cache.
NOTE: Resolving any missing task queue dependencies
Build Configuration:
BB_VERSION = "1.25.0"
BUILD_SYS = "x86_64-linux"
NATIVELSBSTRING = "Ubuntu-14.04"
TARGET_SYS = "arm-poky-linux-gnueabi"
MACHINE = "raspberrypi"
DISTRO = "poky"
DISTRO_VERSION = "1.7"
TUNE_FEATURES = "arm armv6 vfp"
TARGET_FPU = "vfp"
meta
meta-yocto
meta-yocto-bsp = "master:08d3f44d784e06f461b7d83ae9262566f1cf09e4"
meta-raspberrypi = "master:6c6f44136f7e1c97bc45be118a48bd9b1fef1072"
NOTE: Preparing RunQueue
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
Once launched, BitBake begins by browsing all the (.bb and .bbclass)files that the environment provides access to and stores the information in a cache.
Because the parser of BitBake is parallelized, the first execution will always be longer because it has to build the cache (only about a few seconds longer). However, subsequent executions will be almost instantaneous, because BitBake will load the cache. As we can see from the previous command, before executing the task list, BitBake displays a trace that details the versions used (target, version, OS, and so on). Finally, BitBake starts the execution of tasks and shows us the progress.
Depending on your setup, you can go drink some coffee or even eat some pizza. Usually after this, , if all goes well, you will be pleased to see that the tmp/subdirectory's directory construction (rpi-build) is generally populated. The build directory (rpi-build) contains about20 GB after the creation of the image.
After a few hours of baking, we can rejoice with the result and the creation of the system image for our target:
$ ls rpi-build/tmp/deploy/images/raspberrypi/*sdimg
rpi-basic-image-raspberrypi.rpi-sdimg
This is this file that we will use to create our bootable SD card.
Now that our environment is complete, you can create a bootable SD card with the following command (remember to change /dev/sdX to the proper device name and be careful not to kill your hard disk by selecting the wrong device name):
$ sudo dd if=rpi-basic-image-raspberrypi.rpi-sdimg of=/dev/sdX
bs=1M
Once the copying is complete, you can check whether the operation was successful using the following command (look at mmcblk0):
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
mmcblk0 179:0 0 3,7G 0 disk
├─mmcblk0p1 179:1 0 20M 0 part /media/packt/raspberrypi
└─mmcblk0p2 179:2 0 108M 0 part /media/packt/f075d6df-d8b8-4e85-a2e4-36f3d4035c3c
You can also look at the left-hand side of your interface:
This is surely the most anticipated moment of this article—the moment where we boot our Raspberry Pi with a fresh Poky image.
You just have to insert your SD card in a slot, connect the HDMI cable to your monitor, and connect the power supply (it is also recommended to use a mouse and a keyboard to shut down the device, unless you plan on just pulling the plug and possibly corrupting the boot partition).
After connectingthe power supply, you could see the Raspberry Pi splash screen:
The login for the Yocto/Poky distribution is root.
In this article, we learned the steps needed to set up Poky and get our first image built. We ran that image on the Raspberry Pi, which gave us a good overview of the available capabilities.
Further resources on this subject: