Building Embedded Linux with Yocto and Buildroot

Most of the work in Linux system development revolves around the root filesystem, as uboot and kernel are generally provided by the manufacturer, and drivers for peripherals are also provided by the official sources. The main development work is not extensive. The most challenging aspect of building the root filesystem is ensuring that the versions are compatible and complete. This is because the root filesystem involves many requirements, libraries, source files, etc., and there are also version requirements, making it quite difficult.

The most troublesome libraries to build the root filesystem include opengl, java, qt, tslib, openvg, Python, sqlite, and so on. Below, I will introduce several different building methods, explaining the materials and tools, processes, and outputs involved.

Yocto is a common tool for building the root filesystem. Of course, uboot and kernel can also be built, but most people only need the root filesystem. Many SOC manufacturers, such as NXP, have joined the Yocto project to produce Yocto versions of SDKs, which is not necessarily a good thing. SOC users prefer a separate SDK for each chip that they can configure and compile individually. Building with Yocto requires a computer with high memory, clock speed, and disk performance, as well as an Ubuntu environment and repo/git setup, along with a Yocto package provided by the SOC manufacturer. The process involves downloading, configuring the build, and compiling, which can take several hours depending on the computer’s performance. The output includes a cross-compilation toolchain, binary uboot and kernel, and most importantly, the root filesystem containing various required libraries.

Buildroot is also a common method used by SOC manufacturers to provide SDKs, such as for Rockchip and STM32MP. The configuration and compilation process of Buildroot is relatively simple and not complicated; it resembles the configuration and compilation process of the kernel, and the compilation speed is also relatively fast. After obtaining the SDK from the manufacturer, compiling it is not difficult.

Busybox is only used to build the root filesystem, but it only includes some basic utilities such as shell, telnet, etc. The compilation process is similar to compiling the kernel, starting with make menuconfig, then configuring and finally compiling.

When building the root filesystem, I believe it is better to have more than less. Many people think that flash resources are limited and are not suitable for including so many libraries. However, if you choose to use Linux, you should not approach it with an MCU mindset. If resources are truly limited, you should consider using RTOS instead of Linux. Because missing one or two libraries can cause the application to fail, and rebuilding the root filesystem can be very painful.

Additionally, porting Android is not as difficult as many imagine. Generally, SOCs capable of running Android will have an official public SDK released. The difficulty with Android lies in deep customization and application development; the porting itself is easier than with Linux.

Comparison of Buildroot and YoctoComparison Points: (1) Embedded Build System The goal is to build a complete and customized embedded Linux system including root filesystem, toolchain, kernel, bootloader (2) Start from source code (3) Use cross-compilation toolchain (4) Very active maintenance and development (5) Widely used in industry (6) Documentation and training courses available (7) Free software General Principles of Buildroot (1) Focus on simplification (2) Easy to use, easy to understand, easy to extend (3) Handle special cases through extension scripts rather than Buildroot itself (4) Use existing technologies/languages: kconfig, make. (Worth investing time to learn) (5) Default to small (6) Purpose-agnostic (7) Open community, no vendor or bureaucratic/company management General Principles of Yocto (1) Support for major CPU architectures OpenEmbedded: only qemu Yocto Project: adds support for a small number of machines (2) Only provides core methods; uses layers to support more packages and machines (3) Customer modifications should be in a separate layer (4) Multi-purpose build system: as flexible as possible to handle more use cases (5) Open community, but the project is overseen by the Yocto Project Advisory Board initiated by corporate sponsors (6) OpenEmbedded is an independent community-driven project. Buildroot Output (1) Mainly root filesystem images also includes: toolchain, kernel image, bootloader, etc. (2) Supports multiple formats: ext2/3/4, ubifs, iso9600, etc. (3) No binary packages, no package management system Some refer to it as a firmware generator Updates via packages are not possible Updates require a complete system update, like Android Partial updates are considered harmful Yocto Output (1) Builds distributions, with the main output being a package feed Package management system is optional Loading and updating parts of the system is possible (2) Can also produce root filesystem images by installing some packages. Supports ext2/3/4, ubifs, iso9600, etc., and also supports VM images: vmdk, vdi, qcow2 (3) Finally, image classes or tools, wic can be used to build disk images (4) When generating images, SDK can also be generated, allowing application developers to compile and test their applications (without integrating into the build). However, the SDK must match the image. Buildroot Configuration (1) Uses kconfig like the Linux kernel (2) Simple {menu, x, n, g} configuration interface (3) The entire configuration is saved in a file .config/defconfig (4) Defines various aspects of the system: architecture, kernel version/kernel configuration, bootloader, user space packages, etc. (5) make menuconfig, make (6) Builds a generic system for different machines: handle separately A tool can build a defconfig from fragments Feasible, but not super simple Each machine builds completely independently Yocto Configuration (1) Configuration is divided into several parts: Distribution configuration (package configuration, toolchain and libc selection…) Machine Configuration (defines architecture, CPU features, BSP) Image recipe (what packages to install for target) Local configuration (Distribution and default machine selection, number of threads used during compilation, whether to delete build artifacts) (2) It is necessary to collect the layers that will be used and declare them. (3) Allows building the same image for different machines, or building different distributions or images for the same machine. Buildroot Layers (1) No concept of layers (2) All packages are maintained in the official repository (3) Adding BR2_EXTERNAL Allows storage of package definitions, configurations, and other manual files A BR2_EXTERNAL Typically used for proprietary/custom packages and configurations Only adds packages, does not override packages in Buildroot Yocto Layers (1) The layer mechanism allows for modifications and additions of new packages or images (2) Clear separation between core build system, BSP, and custom modifications (3) Third parties provide BSPs for their layers, or a method for handling specialized applications (4) Layers need to be compatible and use the same OE branch base (5) Beware of layer quality, checks are not systemic (6) OpenEmbedded Metadata Index lists available layers, recipes, machines: http://layers.openembedded.org/layerindex/ (7) Additionally, there is a powerful override mechanism that can adjust recipe variables based on machine or distribution Buildroot/Yocto Toolchain Same functionality: (1) Build their own toolchain based on gcc, C libraries (glibc, uClibc, musl) (2) Use external toolchain, simpler for Buildroot since this feature is built-in, while for Yocto, it is only fully supported in additional vendor layers. Buildroot New Package Involves three files Config.in xxx.mk xxx.hash Yocto New Package Involves one file ×××.bb Buildroot: Complexity (1) Designed for simplicity of use (2) For core, each suggested feature is analyzed for usefulness/complexity ratio (3) Core logic is entirely written in make, with less than 1000 lines of code including 230 lines of comments: indeed easy to understand what, why, how; almost as simple as a shell script that downloads, extracts, builds, and installs software in sequence. (4) Documentation is comprehensive, with many resources available (5) An hour’s talk is enough to describe all internal implementations (ELCE 2014) (6) Typical feedback on IRC: from Yocto, very surprised at how easy it is to use. This was the first thing that challenged me. Yocto Project: Complexity (1) A bit of a steep learning curve (2) The core is bitbake, a separate project written in python (60k lines of code) (3) A set of class definitions for common tasks (4) Recipes use a bitbake specific language, mixing python and shell (5) Logs and debugging help understand what each task does specifically (6) Detailed documentation, but there are many different configuration variables (7) Not always easy to understand best practices (for example, Poky cannot be used in production, distro/image modifications should not be made in local.conf, deleting tmp/) (8) People still find some terms confusing (Yocto Project, Poky, OpenEmbedded, bitbake) Buildroot Packages (1) 1800+ packages (2) Graphics: X.org, Wayland, Qt4/Qt5, Gtk2/Gtk3, EFL (3) Multimedia: Gstreamer 0.10/1.x, ffmpeg, Kodi, OpenGL (4) Languages: Python2/3, PHP, Lua, Perl, Erlang, Mono, Ruby, Node.js (5) Networking: Apache, Samba, Dovecot, Exim, CUPS, lots of servers/tools (6) Init systems: Busybox(default), initsysv, systemd (7) No support for a toolchain on the target Yocto Project Packages (1) Thousands of recipes: for oe-core, meta-openembedded, meta-qt5 about 2200. More than 8400 can be found through the Metadata Index (2) Most are similar to Buildroot (3) More languages: Java, Go, Rust, Smalltalk (4) There is still a working layer for Qt3 (5) meta-virtualization (Docker, KVM, LXC, Xen) and meta-openstack layers Buildroot Dependency Method (1) Minimal dependencies, if a feature can be disabled, it is disabled by default (2) Many automatic dependencies, for example, if you enable OpenSSL, it will automatically obtain SSL support from other enabled packages that can provide SSL support (3) Default to effortlessly obtaining a small root filesystem Yocto Project Dependency Method (1) Package configuration at the distribution level Enabling OpenSSL will enable it for all packages, but some packages can be disabled, conversely, some selected packages can be enabled for certain features. (2) Modifications can be made at the machine level, but this should be avoided (3) Each recipe can define its own default feature set, providing a robust default configuration. Buildroot Updates/Security (1) Releases every three months, two months of development, one month of stabilization (2) Releases include package version updates: security updates and major updates (3) The core architecture may also undergo potential changes (4) No LTS version, users need to handle it themselves (5) A script is being provided to assess unresolved CVEs (Common Vulnerabilities & Exposures) in a given Buildroot configuration Yocto Project Updates/Security (1) Releases every six months, once in April, once in October (2) Planning and roadmap can be found through the wiki: https://wiki.yoctoproject.org/wiki/Yocto_Project_v2.1_Status (3) Contains four milestones within three months between M1 and the final release (4) At least previous and current release versions have designated maintainers who receive security and important fixes, but no recipe updates (5) Old versions are maintained by the community Buildroot Configuration Change Detection (1) Buildroot is not very intelligent (2) It does not attempt to detect what needs to be rebuilt when configurations are modified (3) Once a package is built, Buildroot will not rebuild it unless forced (4) Major configuration changes require a full rebuild (5) Minor configuration changes may not require a full rebuild (6) One configuration, one build, cannot share configurations between builds Yocto Project Configuration Change Detection (1) Bitbake maintains a shared State Cache allowing incremental builds (2) It detects task input modifications by creating checksums of inputs (3) The cache can be shared across all builds, making builds faster for similar machines (4) This cache can be shared across hosts, such as a nightly server and a development machine, greatly speeding up full builds Buildroot: Architecture Support (1) Supports many architectures (2) ARM (64), MIPS, PowerPC (64), x86/x86-64 (3) Also supports many more specialized architectures: Xtensa, Blackfin, ARC, m68k, SPARC, Microblaze, NIOSII; ARM noMMU, especially ARMv7-M (4) Architecture vendors provide assistance: MIPS from Imagination Technologies, PowerPC64 from IBM, ARC from Synopsys, Blackfin from Analog Devices Yocto Project: Architecture Support (1) In core, ARM, MIPS, PowerPC, X86, and their 64-bit series (2) Separate layers: Microblaze, NIOSII (3) Typically, chip manufacturers maintain their own BSP layers: meta-intell, meta-altera (ARM & NIOSII), meta-atmel, meta-fsl, meta-ti, meta-xilinx … (4) Community provides: meta-rockchip, meta-sunxi Buildroot: Minimal Build The minimal build takes 15 minutes and 25 seconds, with an image size of 2.2MB Yocto Project: Minimal Build The minimal build takes 50 minutes and 47 seconds, with an image size of 4.9MB. If there is an existing sstate-cache, it takes 1 minute and 21 seconds License (1) Both can create a list of licenses used (2) Both can detect license changes (3) The Yocto project can exclude GPLv3 Buildroot & Yocto SelectionBuildroot (1) Very specialized CPU architectures (2) Very small rootfs < 8M (3) Not very demanding on engineers (4) Does not support various machines or similar systems (5) No need for package/system updates (6) Small systems Yocto (1) Not very specialized CPU architectures, not very small rootfs, requires experienced engineers. (2) Not very specialized CPU architectures, not very small rootfs, requires experienced engineers. Supports several similar systems (3) Not very specialized CPU architectures, not very small rootfs, requires experienced engineers. Needs package and system updates (4) Not very specialized CPU architectures, not very small rootfs, requires experienced engineers. Very large systems

Regularly share embedded knowledge in an easy-to-understand manner, follow our public account, star it, and improve a little every day.

Disclaimer:

All articles, images, etc. that are original or reprinted by this account are copyrighted by the original authors. If there is any infringement, please contact us for removal.

Building Embedded Linux with Yocto and BuildrootFollow, like, view, share, support quality content!Building Embedded Linux with Yocto and Buildroot

Leave a Comment