Yocto part I – baseline boot time

The Yocto project provides a set of tools to build custom distribution images from scratch. When using Yocto, the image, and all the tooling used to build the image, is built from recipes. These recipes are parsed using the bitbake command. The recipes have dependencies, just as ordinary packages in a classical distro. By pointing to an image recipe, a dependency tree will be constructed and a large number of packages will be downloaded, built and then assembled into a single image.

In this little series of blog posts, I aim to have a look at what can be done about size and performance for the minimal core image that comes with the system. The target system will be an x86 QEMU machine. So, my starting point is the outcome of the Yocto Project Quick Start. Before I get started, let me also point out the excellent Yocto Project Reference Manual.

My starting point is the core-image-minimal recipe, creating a minimal Linux system. It uses busybox, and provides very little, so it is a good baseline. I’d like to use systemd for booting the image, so before building, I added the following lines to my local.conf file (info source).

DISTRO_FEATURES_append = " systemd"
VIRTUAL-RUNTIME_init_manager = "systemd"
VIRTUAL-RUNTIME_initscripts = ""

I’m also keen on having a look at the boot performance, so I added systemd-analyze to the IMAGE_INSTALL variable. I did this by modifying the¬†meta/recipes-core/images/core-image-minimal.bb file. I know that this is bad practice, I will explain how to do this properly using a custom meta layer and image recipe in a later installment of this series.

Having built and started the system, I get a boot time of 11.3s. Of these, 6.4s are spent to start the kernel, while the remaining 4.9s are spent in userspace. I also got a nice boot graph, as well as a list of systemd units to blame for the time the boot sequence consumed. I used a little netcat trick to get these files of the QEMU system to my host machine. Always nice, to avoid adding cruft to the image.

1.272s systemd-udev-trigger.service
991ms systemd-user-sessions.service
694ms systemd-logind.service
363ms systemd-networkd.service
360ms systemd-remount-fs.service
353ms systemd-sysctl.service
299ms sys-kernel-debug.mount
292ms kmod-static-nodes.service
269ms dev-mqueue.mount
250ms systemd-tmpfiles-setup.service
242ms systemd-journal-flush.service
137ms systemd-update-utmp.service
129ms systemd-tmpfiles-setup-dev.service
102ms systemd-udevd.service
91ms tmp.mount
78ms systemd-random-seed.service
64ms var-volatile.mount


Boot Chart
The boot chart.

Next time, we will have a closer look on the base line image size, before we start looking at what we can do to optimize things.