Buildroot Getting Started Guide
Published on December 8, 2015
This post intends to gather all the information you need to start a project based on Buildroot. It relies on the 2015.11 release but applies to other versions. This post is largely inspired from Free Electrons Buildroot training, with a focus towards our platforms and Freescale-specific packages.
Introduction
When choosing a build system for an embedded Linux project, many options are available such as: Yocto/OpenEmbedded, PTXdist, Buildroot, LTIB, OpenBricks, OpenWRT, etc...
However nowadays the two most popular ones are:
- Yocto/OpenEmbedded
- Builds a complete Linux distribution with binary packages.
- Most powerful option but also the most complex.
- Officially supported by Freescale.
- Buildroot
- Builds a root filesystem image, no binary packages.
- Much simpler to use, understand and modify.
Although Freescale is only supporting Yocto, Buildroot offers the same level of support in most instances in regards to the Freescale-specific packages. For instance, the Buildroot 2015.11 release is using the exact same Freescale packages as the Fido release of Yocto.
Here are the key features of Buildroot:
- Can build a toolchain, a rootfs, a kernel, a bootloader
- Fast: builds a simple root filesystem in a few minutes
- Small root filesystem, starting at 2 MB
- Easy to understand: written in make, extensive documentation
- Based on well-known technologies: make and kconfig
- 1600+ packages for user space libraries/apps available
- Including X.org, Kodi (formerly XBMC), Gstreamer1.0, Qt5.5 etc...
- Active community, regular releases
For the impatients
We've prepared images with the following content:
- U-Boot 2015.07
- Kernel 3.14.28_1.0.0-GA
- All the Freescale packages (GPU, VPU, firmwares)
- Gstreamer1 + Gstreamer-imx plugin
- Qt5.5 + Cinematic demo
You can download them from here:
- buildroot-2015.11-nitrogen6x-20151201.img.gz for Nitrogen6X, SABRE Lite, Nitrogen6_Lite and Nitrogen6_Max
- buildroot-2015.11-nitrogen6sx-20151201.img.gz for Nit6_SoloX
As usual, you'll need to register on our site and agree to the EULA because it contains Freescale content. The image is a 4GB SD card image that can be restored using zcat and dd under Linux.
~$ zcat buildroot-2015.11-nitrogen*.img.gz | sudo dd of=/dev/sdX bs=1M
For Windows users, please use Alex Page's USB Image Tool.
Build & flashing instructions
In order to retrieve Buildroot source code, you can either download the latest available archive (2015.11 as of this writing):
~$ curl https://buildroot.uclibc.org/downloads/buildroot-2015.11.tar.gz | tar xz
~$ cd buildroot-2015.11
Another option to get Buildroot source is to clone the git repository:
~$ git clone https://git.buildroot.net/buildroot
The configurations available in the Buildroot work fine but only contain very minimalistic system packages.
~/buildroot-2015.11$ make nitrogen6x_defconfig
For this blog post and the image associated to it, we've prepared a Qt5.5 + Gstreamer1.0 configuration for Nitrogen6x:
~/buildroot-2015.11$ curl https://storage.googleapis.com/boundarydevices.com/20151201-buildroot-nitrogen6x.config > .config
If you wish to build for Nitrogen6sx instead:
~/buildroot-2015.11$ curl https://storage.googleapis.com/boundarydevices.com/20151201-buildroot-nitrogen6sx.config > .config
Finally the build process is very easy:
~/buildroot-2015.11$ make
The output image will be located in output/images/rootfs.ext2.gz
and can be flashed as follows:
~/buildroot-2015.11$ sudo parted /dev/sdc mklabel msdos
~/buildroot-2015.11$ sudo parted -a optimal /dev/sdc mkpart primary 0% 100%
~/buildroot-2015.11$ zcat output/images/rootfs.ext2.gz | sudo dd of=/dev/sdc1 bs=1M
That's it! As simple as that. Once the image booted, you can start playing with the applications available on the image
# wget https://media.xiph.org/mango/tears_of_steel_1080p.webm -P /root/
# gst-launch-1.0 playbin uri=file:///root/tears_of_steel_1080p.webm
# gst-launch-1.0 imxv4l2videosrc device=/dev/video1 ! imxeglvivsink
# /usr/share/Qt5/CinematicExperience/Qt5_CinematicExperience
Next sections will give an overview of Buildroot features, how you can modify and/or extend it for your needs
Customization
Configuration
As Buildroot on Kconfig, its configuration is going to be just like the Linux kernel
~/buildroot-2015.11$ make menuconfig
From there you can browse the Target Packages available and select the ones you want.
Quick tip, you can look for a component by typing "/", then you can go straight to it by entering the number associated to it.
In the example above, a search for "imx" has been issued. Then typing "2" would bring you directly to the "Freescale i.MX libraries" package selection.
Create a new package
A package in Buildroot-speak is the set of meta-information needed to automate the build process of a certain component of a system. It can be used for open-source, third party proprietary components, or in-house components.
Adding a package consists of creating the following:
- A directory:
package/foo
- A
Config.in
file, written in kconfig language, describing the configuration options for the package. - A
.mk
file, written in make, describing where to fetch the source, how to build and install it, etc... - An optional
.hash
file, providing hashes to check the integrity of the downloaded tarballs. - Optionally,
.patch
files, that are applied on the package source code before building. - Optionally, any additional file that might be useful for the package: init script, example configuration file, etc...
Here are the steps Buildroot goes through when building a package:
- Download the package (to the
dl
directory) - Extract the package (inside the
output/build
directory) - Patch the source code
- Configure the package
- Build the package
- Install the package (to
output/target
directory)
Each software component to be built by Buildroot comes with its own build system. Buildroot does not re-invent the build system of each component, it simply uses it, whether it is hand-written Makefiles or shell scripts, autotools, CMake and also some specific to languages: Python, Perl, Lua, Erlang, etc. In order to avoid duplicating code, Buildroot has package infrastructures for well-known build systems.
Below are some simple examples of existing packages, based on different infrastructures. This should give a good starting point for making your own package.
- generic package: fbgrab
FBGRAB_VERSION = 1.2
FBGRAB_SITE = https://fbgrab.monells.se
FBGRAB_DEPENDENCIES = libpng
FBGRAB_LICENSE = GPLv2
FBGRAB_LICENSE_FILES = COPYING
define FBGRAB_BUILD_CMDS
$(TARGET_CONFIGURE_OPTS) $(MAKE) -C $(@D)
endef
define FBGRAB_INSTALL_TARGET_CMDS
$(INSTALL) -m 0755 -D $(@D)/fbgrab $(TARGET_DIR)/usr/bin/fbgrab
endef
$(eval $(generic-package))
- autotools package: e2tools
E2TOOLS_VERSION = 3158ef18a903ca4a98b8fa220c9fc5c133d8bdf6
E2TOOLS_SITE = $(call github,ndim,e2tools,$(E2TOOLS_VERSION))
# Source coming from GitHub, no configure included.
E2TOOLS_AUTORECONF = YES
E2TOOLS_LICENSE = GPLv2
E2TOOLS_LICENSE_FILES = COPYING
E2TOOLS_DEPENDENCIES = e2fsprogs
E2TOOLS_CONF_ENV = LIBS="-lpthread"
$(eval $(autotools-package))
- python package: python-serial
PYTHON_SERIAL_VERSION = 2.6
PYTHON_SERIAL_SOURCE = pyserial-$(PYTHON_SERIAL_VERSION).tar.gz
PYTHON_SERIAL_SITE = https://pypi.python.org/packages/source/p/pyserial
PYTHON_SERIAL_LICENSE = Python Software Foundation License
PYTHON_SERIAL_LICENSE_FILES = LICENSE.txt
PYTHON_SERIAL_SETUP_TYPE = distutils
$(eval $(python-package))
Use BR2_EXTERNAL
The instructions above show the simplest solution for building and customizing Buildroot. But storing your custom packages, custom configuration files and custom defconfigs inside the Buildroot tree may not be the most practical solution:
- Doesn't cleanly separate open-source parts from proprietary parts
- Makes it harder to upgrade Buildroot
The BR2_EXTERNAL
mechanism allows to store your own package recipes, defconfigs and other artefacts outside of the Buildroot source tree. Thus allowing to have a project structure as:
project/
buildroot/
- The Buildroot source code, cloned from Git, or extracted from a release tarball.
external/
- Your external tree, with your own custom packages and defconfigs
output-build1/
output-build2/
- Several output directories, to build various configurations
custom-app/
custom-lib/
- The source code of your custom applications and libraries.
Here is an example of what the external
folder can contain.
external/
board//
- folder containing board specific post-install/image scripts or overlays
configs/
- custom configuration for your project
packages/
- custom packages (proprietary?) for your project
Config.in
- Configuration options for the BR2_EXTERNAL packages
source "$BR2_EXTERNAL/package/package1/Config.in"
source "$BR2_EXTERNAL/package/package2/Config.in"
-
external.mk
- Can include custom make logic, use to include the package .mk files
include $(sort $(wildcard $(BR2_EXTERNAL)/package/*/*.mk))
Once your external folder is properly configured, using the same folder structure as before, starting a new build would be:
~/project$ make BR2_EXTERNAL=$PWD/external -C $PWD/buildroot
O=$PWD/output-build3 myownconf_defconfig
~/project$ make -C $PWD/output-build3
Going further
This post just gives an overview of what you can achieve with Buildroot. This is what we think is sufficient to get you started. But if you wish to go further, here are a few links.
First, the project documentation is very thorough and well-written:
Once again we highly recommend to look at the Free Electrons training:
As usual all the slides, labs and solutions are open-source (Creative Commons Attribution - Share Alike 3.0).
Finally, the Buildroot community is very friendly and appreciates any contribution/feedback you can provide:
- mailing list: https://lists.buildroot.org/mailman/listinfo/buildroot
- IRC channel: #buildroot (hosted on Freenode)
Let us know your experience with Buildroot, good or bad, so we can update this post with more information if needed.