Yocto + Raspberry Pi: A quick run through

September 20, 2023

My experience working with Yocto, this comes as part of a series of working with embedded Linux OS for Raspberry PIs or similar devices.

Quick links to my other posts: Ubuntu Core and Raspberry Pi , Updatable Linux OS


This blog post explores my experience with building a custom OS with Yocto and deploying it on the Raspberry Pi. I’ll share some pain points I had and overall feelings I had when experimenting with this setup.

The Raspberry PI is an amazing embedded developer tool and has opened the world of small embedded linux computers to many developers, makers, and hobbyists. It is also being used in real world applications directly or with their different variants like the CM3/4.

While the default Raspbian OS works wonderfully I wanted to explore other Linux OS options that may be better suited for real-world IoT applications where 1000s of devices need to be deployed, managed, and updated

The Yocto Project (YP) is an open source collaboration project that helps developers create custom Linux-based systems regardless of the hardware architecture - https://www.yoctoproject.org/

What that really means is it enables you to build a custom Linux OS for your board (Raspberry Pi) or something custom with only the packages and tools you need installed. Through the process you will automatically build from source every part of the OS and have a neat little .img to install on a SD card at the end.

In the embedded Linux world Yocto and OpenEmbedded/BitBake (part or tangential to Yocto) are fairly ubiquitous because the tool offers so much configurability. I used Yocto many years ago from 2009 - 2013 to build images for Gumstix boards for Intellistreets which embedded Linux computers in street lights to play music wirelessly and connect sensors for public municipalities. It does have drawbacks; the learning curve is steep especially for non software developers but online guides are usually pretty good to get you going.

Getting Started

I needed to set up another Linux development machine. Ideally Ubuntu or Debian which is the best supported for Yocto. Mac OSX is a bit tricky and I didn’t want my laptop to have to do the hard work for such a long time and not be able to use it. I first used GCP and spun up a fairly large instance but that got costly so I dedicated my old gaming desktop to a Ubuntu Server.

I found this wonderful blog post by Michael Seidel: Build your own Linux Image for the Raspberry Pi

Some dependencies:

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

Setting up your configuration:

Yocto and OpenEmbedded use “layers” which provide recipes to build software packages or provide specific board support. To get going you need a few provided by Yocto and OpenEmbedded that provide the basic build for the base OS and you will also need the meta-raspberrypi to provide the board support for it. You can find some layers and recipes here .

mkdir ~/yocto
cd ~/yocto
mkdir sources

Checkout the Layers

cd ~/yocto/sources

git clone git://git.yoctoproject.org/poky -b kirkstone
git clone https://git.openembedded.org/meta-openembedded -b kirkstone

# And the raspberry pi bsp layer
git clone git://git.yoctoproject.org/meta-raspberrypi -b kirkstone

Initialize the build environment with the script that Yocto provides.

cd ~/yocto/
. sources/poky/oe-init-build-env

Add the layers to the layer config.

bitbake-layers add-layer ../sources/meta-openembedded/meta-oe
bitbake-layers add-layer ../sources/meta-openembedded/meta-python
bitbake-layers add-layer ../sources/meta-openembedded/meta-networking
bitbake-layers add-layer ../sources/meta-raspberrypi

The final output of conf/bblayers.conf should look like:

# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
POKY_BBLAYERS_CONF_VERSION = "2"

BBPATH = "${TOPDIR}"
BBFILES ?= ""

BBLAYERS ?= " \
  /home/adam/yocto/sources/poky/meta \
  /home/adam/yocto/sources/poky/meta-poky \
  /home/adam/yocto/sources/poky/meta-yocto-bsp \
  /home/adam/yocto/sources/meta-openembedded/meta-oe \
  /home/adam/yocto/sources/meta-openembedded/meta-python \
  /home/adam/yocto/sources/meta-openembedded/meta-networking \
  /home/adam/yocto/sources/meta-raspberrypi \
  "

Building

Now build your image. Go take a break and grab some coffee and lunch because it will take a while the first time. It took a few hours for me.

MACHINE=raspberrypi4-64 bitbake core-image-base

This will build a 64bit based image for the raspberry pi4. The name of the image in bitbake is `core-image-base`, it’s a very minimal image. You can read up on them here . `core-image-full-cmdline` is another good choice if you want the standard tools you expect in most linux distros.

The Image

Once finished look in `~/yocto/build/tmp/deploy/images/raspberrypi4-64/` for `core-image-base-raspberrypi4-64-20231016121807.sdimg.bz2` which can be written to a micrsd card with Etcher or similar.

Note: for Etcher I had to change the extension from .sdimg -> .img.

Booting

If done correctly and using the correct board it should boot and if plugged into a hdmi screen you should see a login prompt. Login with `root` with no password. You can also use a FTDI cable and its serial port to avoid having a monitor/keyboard. Follow these instructions from Adafruit.

Conclusion

Yocto and OpenEmbedded are quite powerful but come with a steep learning curve once you go past the basic image build. For example building a golang program is quite a process past a simple hello world. Also see my blog post on Raspberry Pi with Yocto and Tailscale ..

The biggest draw for me thinking about a production system is having a well supported (with longevity) and having a generally reproducible build of the entire image. Less important these days for me is the considerable reduction in image size nand is getting cheaper and is not unheard of to have a few gigs to work with.

Yocto has wide industry support and integrates well with Mender to allow for OTA upgrades of the entire rootfs using an A/B partition.

My next goal is playing with a pre-built Linux Distros eg. Debian using Debos to make modifications for the specific packages I need. Ultimately for use case this may be a good middle ground from Ubuntu Core and Yocto.