{"id":587,"date":"2014-06-21T00:11:30","date_gmt":"2014-06-20T22:11:30","guid":{"rendered":"http:\/\/www.thelins.se\/johan\/blog\/?p=587"},"modified":"2014-06-21T22:53:42","modified_gmt":"2014-06-21T20:53:42","slug":"yocto-part-i-baseline-boot-time","status":"publish","type":"post","link":"https:\/\/www.thelins.se\/johan\/blog\/2014\/06\/yocto-part-i-baseline-boot-time\/","title":{"rendered":"Yocto part I &#8211; baseline boot time"},"content":{"rendered":"<p>The <a href=\"https:\/\/www.yoctoproject.org\/\">Yocto project<\/a> 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 <a href=\"http:\/\/en.wikipedia.org\/wiki\/BitBake\">bitbake<\/a> 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.<\/p>\n<p>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 <a href=\"http:\/\/www.yoctoproject.org\/docs\/current\/yocto-project-qs\/yocto-project-qs.html\">Yocto Project\u00a0Quick Start<\/a>. Before I get started, let me also point out the excellent <a href=\"http:\/\/www.yoctoproject.org\/docs\/current\/ref-manual\/ref-manual.html\">Yocto Project Reference Manual<\/a>.<\/p>\n<p>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&#8217;d like to use <a href=\"http:\/\/en.wikipedia.org\/wiki\/Systemd\">systemd<\/a> for booting the image, so before building, I added the following lines to my local.conf file (<a href=\"http:\/\/www.yoctoproject.org\/docs\/1.6\/dev-manual\/dev-manual.html#selecting-an-initialization-manager\">info source<\/a>).<\/p>\n<p><code><br \/>\nDISTRO_FEATURES_append = \" systemd\"<br \/>\nVIRTUAL-RUNTIME_init_manager = \"systemd\"<br \/>\nDISTRO_FEATURES_BACKFILL_CONSIDERED = \"sysvinit\"<br \/>\nVIRTUAL-RUNTIME_initscripts = \"\"<br \/>\n<\/code><\/p>\n<p>I&#8217;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\u00a0meta\/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.<\/p>\n<p>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 <a href=\"http:\/\/www.microhowto.info\/howto\/copy_a_file_from_one_machine_to_another_using_netcat.html\">netcat trick<\/a> to get these files of the QEMU system to my host machine. Always nice, to avoid adding cruft to the image.<\/p>\n<p><code><br \/>\n1.272s systemd-udev-trigger.service<br \/>\n991ms systemd-user-sessions.service<br \/>\n694ms systemd-logind.service<br \/>\n363ms systemd-networkd.service<br \/>\n360ms systemd-remount-fs.service<br \/>\n353ms systemd-sysctl.service<br \/>\n299ms sys-kernel-debug.mount<br \/>\n292ms kmod-static-nodes.service<br \/>\n269ms dev-mqueue.mount<br \/>\n250ms systemd-tmpfiles-setup.service<br \/>\n242ms systemd-journal-flush.service<br \/>\n137ms systemd-update-utmp.service<br \/>\n129ms systemd-tmpfiles-setup-dev.service<br \/>\n102ms systemd-udevd.service<br \/>\n91ms tmp.mount<br \/>\n78ms systemd-random-seed.service<br \/>\n64ms var-volatile.mount<br \/>\n<\/code><\/p>\n<p>&nbsp;<\/p>\n<figure id=\"attachment_589\" aria-describedby=\"caption-attachment-589\" style=\"width: 540px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.thelins.se\/johan\/blog\/wp-content\/uploads\/2014\/06\/boot.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-large wp-image-589\" src=\"https:\/\/www.thelins.se\/johan\/blog\/wp-content\/uploads\/2014\/06\/boot-707x1024.png\" alt=\"Boot Chart\" width=\"540\" height=\"782\" srcset=\"https:\/\/www.thelins.se\/johan\/blog\/wp-content\/uploads\/2014\/06\/boot-707x1024.png 707w, https:\/\/www.thelins.se\/johan\/blog\/wp-content\/uploads\/2014\/06\/boot-207x300.png 207w, https:\/\/www.thelins.se\/johan\/blog\/wp-content\/uploads\/2014\/06\/boot.png 1168w\" sizes=\"auto, (max-width: 540px) 100vw, 540px\" \/><\/a><figcaption id=\"caption-attachment-589\" class=\"wp-caption-text\">The boot chart.<\/figcaption><\/figure>\n<p>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.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 &hellip; <a href=\"https:\/\/www.thelins.se\/johan\/blog\/2014\/06\/yocto-part-i-baseline-boot-time\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Yocto part I &#8211; baseline boot time<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"class_list":["post-587","post","type-post","status-publish","format-standard","hentry","category-yocto"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/posts\/587","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/comments?post=587"}],"version-history":[{"count":3,"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/posts\/587\/revisions"}],"predecessor-version":[{"id":601,"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/posts\/587\/revisions\/601"}],"wp:attachment":[{"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/media?parent=587"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/categories?post=587"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.thelins.se\/johan\/blog\/wp-json\/wp\/v2\/tags?post=587"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}