All the configuration options in make *config
have a help text
providing details about the option.
The make *config
commands also offer a search tool. Read the help
message in the different frontend menus to know how to use it:
/
;
Ctrl
+ f
.
The result of the search shows the help message of the matching items. In menuconfig, numbers in the left column provide a shortcut to the corresponding entry. Just type this number to directly jump to the entry, or to the containing menu in case the entry is not selectable due to a missing dependency.
Although the menu structure and the help text of the entries should be sufficiently self-explanatory, a number of topics require additional explanation that cannot easily be covered in the help text and are therefore covered in the following sections.
A compilation toolchain is the set of tools that allows you to compile
code for your system. It consists of a compiler (in our case, gcc
),
binary utils like assembler and linker (in our case, binutils
) and a
C standard library (for example
GNU Libc,
uClibc-ng).
The system installed on your development station certainly already has a compilation toolchain that you can use to compile an application that runs on your system. If you’re using a PC, your compilation toolchain runs on an x86 processor and generates code for an x86 processor. Under most Linux systems, the compilation toolchain uses the GNU libc (glibc) as the C standard library. This compilation toolchain is called the "host compilation toolchain". The machine on which it is running, and on which you’re working, is called the "host system" [3].
The compilation toolchain is provided by your distribution, and Buildroot has nothing to do with it (other than using it to build a cross-compilation toolchain and other tools that are run on the development host).
As said above, the compilation toolchain that comes with your system runs on and generates code for the processor in your host system. As your embedded system has a different processor, you need a cross-compilation toolchain - a compilation toolchain that runs on your host system but generates code for your target system (and target processor). For example, if your host system uses x86 and your target system uses ARM, the regular compilation toolchain on your host runs on x86 and generates code for x86, while the cross-compilation toolchain runs on x86 and generates code for ARM.
Buildroot provides two solutions for the cross-compilation toolchain:
Buildroot toolchain
in
the configuration interface.
External toolchain
in
the configuration interface.
The choice between these two solutions is done using the Toolchain
Type
option in the Toolchain
menu. Once one solution has been
chosen, a number of configuration options appear, they are detailed in
the following sections.
The internal toolchain backend is the backend where Buildroot builds by itself a cross-compilation toolchain, before building the userspace applications and libraries for your target embedded system.
This backend supports several C libraries: uClibc-ng, glibc and musl.
Once you have selected this backend, a number of options appear. The most important ones allow to:
.h
files from the kernel), which
define the interface between userspace and the kernel (system
calls, data structures, etc.). Since this interface is backward
compatible, the version of the Linux kernel headers used to build
your toolchain do not need to match exactly the version of the
Linux kernel you intend to run on your embedded system. They only
need to have a version equal or older to the version of the Linux
kernel you intend to run. If you use kernel headers that are more
recent than the Linux kernel you run on your embedded system, then
the C library might be using interfaces that are not provided by
your Linux kernel.
make uclibc-menuconfig
. Note however that
all packages in Buildroot are tested against the default uClibc
configuration bundled in Buildroot: if you deviate from this
configuration by removing features from uClibc, some packages may no
longer build.
It is worth noting that whenever one of those options is modified, then the entire toolchain and system must be rebuilt. See Section 8.2, “Understanding when a full rebuild is necessary”.
Advantages of this backend:
Drawbacks of this backend:
make clean
, which
takes time. If you’re trying to reduce your build time, consider
using the External toolchain backend.
The external toolchain backend allows to use existing pre-built cross-compilation toolchains. Buildroot knows about a number of well-known cross-compilation toolchains (from Linaro for ARM, Sourcery CodeBench for ARM, x86-64, PowerPC, and MIPS, and is capable of downloading them automatically, or it can be pointed to a custom toolchain, either available for download or installed locally.
Then, you have three solutions to use an external toolchain:
Toolchain
from the available ones. This is
definitely the easiest solution.
Toolchain
through the available
ones, unselect Download toolchain automatically
, and fill the
Toolchain path
text entry with the path to your cross-compiling
toolchain.
Custom toolchain
solution in the
Toolchain
list. You need to fill the Toolchain path
, Toolchain
prefix
and External toolchain C library
options. Then, you have
to tell Buildroot what your external toolchain supports. If your
external toolchain uses the glibc library, you only have to tell
whether your toolchain supports C++ or not and whether it has
built-in RPC support. If your external toolchain uses the uClibc
library, then you have to tell Buildroot if it supports RPC,
wide-char, locale, program invocation, threads and C++.
At the beginning of the execution, Buildroot will tell you if
the selected options do not match the toolchain configuration.
Our external toolchain support has been tested with toolchains from CodeSourcery and Linaro, toolchains generated by crosstool-NG, and toolchains generated by Buildroot itself. In general, all toolchains that support the sysroot feature should work. If not, do not hesitate to contact the developers.
We do not support toolchains or SDK generated by OpenEmbedded or Yocto, because these toolchains are not pure toolchains (i.e. just the compiler, binutils, the C and C++ libraries). Instead these toolchains come with a very large set of pre-compiled libraries and programs. Therefore, Buildroot cannot import the sysroot of the toolchain, as it would contain hundreds of megabytes of pre-compiled libraries that are normally built by Buildroot.
We also do not support using the distribution toolchain (i.e. the gcc/binutils/C library installed by your distribution) as the toolchain to build software for the target. This is because your distribution toolchain is not a "pure" toolchain (i.e. only with the C/C++ library), so we cannot import it properly into the Buildroot build environment. So even if you are building a system for a x86 or x86_64 target, you have to generate a cross-compilation toolchain with Buildroot or crosstool-NG.
If you want to generate a custom toolchain for your project, that can be used as an external toolchain in Buildroot, our recommendation is to build it either with Buildroot itself (see Section 6.1.3, “Build an external toolchain with Buildroot”) or with crosstool-NG.
Advantages of this backend:
Drawbacks of this backend:
The Buildroot internal toolchain option can be used to create an external toolchain. Here are a series of steps to build an internal toolchain and package it up for reuse by Buildroot itself (or other projects).
Create a new Buildroot configuration, with the following details:
Then, we can trigger the build, and also ask Buildroot to generate a SDK. This will conveniently generate for us a tarball which contains our toolchain:
make sdk
This produces the SDK tarball in $(O)/images
, with a name similar to
arm-buildroot-linux-uclibcgnueabi_sdk-buildroot.tar.gz
. Save this
tarball, as it is now the toolchain that you can re-use as an external
toolchain in other Buildroot projects.
In those other Buildroot projects, in the Toolchain menu:
file:///path/to/your/sdk/tarball.tar.gz
When using an external toolchain, Buildroot generates a wrapper program,
that transparently passes the appropriate options (according to the
configuration) to the external toolchain programs. In case you need to
debug this wrapper to check exactly what arguments are passed, you can
set the environment variable BR2_DEBUG_WRAPPER
to either one of:
0
, empty or not set: no debug
1
: trace all arguments on a single line
2
: trace one argument per line
On a Linux system, the /dev
directory contains special files, called
device files, that allow userspace applications to access the
hardware devices managed by the Linux kernel. Without these device
files, your userspace applications would not be able to use the
hardware devices, even if they are properly recognized by the Linux
kernel.
Under System configuration
, /dev management
, Buildroot offers four
different solutions to handle the /dev
directory :
system/device_table_dev.txt
in the
Buildroot source code. This file is processed when Buildroot
generates the final root filesystem image, and the device files
are therefore not visible in the output/target
directory. The
BR2_ROOTFS_STATIC_DEVICE_TABLE
option allows to change the
default device table used by Buildroot, or to add an additional
device table, so that additional device files are created by
Buildroot during the build. So, if you use this method, and a
device file is missing in your system, you can for example create
a board/<yourcompany>/<yourproject>/device_table_dev.txt
file
that contains the description of your additional device files,
and then you can set BR2_ROOTFS_STATIC_DEVICE_TABLE
to
system/device_table_dev.txt
board/<yourcompany>/<yourproject>/device_table_dev.txt
. For more
details about the format of the device table file, see
Chapter 25, Makedev syntax documentation.
/dev
, this virtual
filesystem will automatically make device files appear and
disappear as hardware devices are added and removed from the
system. This filesystem is not persistent across reboots: it is
filled dynamically by the kernel. Using devtmpfs requires the
following kernel configuration options to be enabled:
CONFIG_DEVTMPFS
and CONFIG_DEVTMPFS_MOUNT
. When Buildroot is in
charge of building the Linux kernel for your embedded device, it
makes sure that those two options are enabled. However, if you
build your Linux kernel outside of Buildroot, then it is your
responsibility to enable those two options (if you fail to do so,
your Buildroot system will not boot).
CONFIG_DEVTMPFS
and
CONFIG_DEVTMPFS_MOUNT
enabled in the kernel configuration still
apply), but adds the mdev
userspace utility on top of it. mdev
is a program part of BusyBox that the kernel will call every time a
device is added or removed. Thanks to the /etc/mdev.conf
configuration file, mdev
can be configured to for example, set
specific permissions or ownership on a device file, call a script
or application whenever a device appears or disappear,
etc. Basically, it allows userspace to react on device addition
and removal events. mdev
can for example be used to automatically
load kernel modules when devices appear on the system. mdev
is
also important if you have devices that require a firmware, as it
will be responsible for pushing the firmware contents to the
kernel. mdev
is a lightweight implementation (with fewer
features) of udev
. For more details about mdev
and the syntax
of its configuration file, see
http://git.busybox.net/busybox/tree/docs/mdev.txt.
eudev
userspace daemon on top of it. eudev
is a daemon that runs in the background, and gets called by the
kernel when a device gets added or removed from the system. It is a
more heavyweight solution than mdev
, but provides higher
flexibility. eudev
is a standalone version of udev
, the
original userspace daemon used in most desktop Linux distributions,
which is now part of Systemd. For more details, see
http://en.wikipedia.org/wiki/Udev.
The Buildroot developers recommendation is to start with the Dynamic using devtmpfs only solution, until you have the need for userspace to be notified when devices are added/removed, or if firmwares are needed, in which case Dynamic using devtmpfs + mdev is usually a good solution.
Note that if systemd
is chosen as init system, /dev management will
be performed by the udev
program provided by systemd
.
The init program is the first userspace program started by the kernel (it carries the PID number 1), and is responsible for starting the userspace services and programs (for example: web server, graphical applications, other network servers, etc.).
Buildroot allows to use three different types of init systems, which
can be chosen from System configuration
, Init system
:
init
program, which is sufficient
for most embedded systems. Enabling the BR2_INIT_BUSYBOX
will
ensure BusyBox will build and install its init
program. This is
the default solution in Buildroot. The BusyBox init
program will
read the /etc/inittab
file at boot to know what to do. The syntax
of this file can be found in
http://git.busybox.net/busybox/tree/examples/inittab (note that
BusyBox inittab
syntax is special: do not use a random inittab
documentation from the Internet to learn about BusyBox
inittab
). The default inittab
in Buildroot is stored in
package/busybox/inittab
. Apart from mounting a few important
filesystems, the main job the default inittab does is to start the
/etc/init.d/rcS
shell script, and start a getty
program (which
provides a login prompt).
package/sysvinit
. This was the solution used in most desktop
Linux distributions, until they switched to more recent
alternatives such as Upstart or Systemd. sysvinit
also works with
an inittab
file (which has a slightly different syntax than the
one from BusyBox). The default inittab
installed with this init
solution is located in package/sysvinit/inittab
.
systemd
is the new generation
init system for Linux. It does far more than traditional init
programs: aggressive parallelization capabilities, uses socket and
D-Bus activation for starting services, offers on-demand starting
of daemons, keeps track of processes using Linux control groups,
supports snapshotting and restoring of the system state,
etc. systemd
will be useful on relatively complex embedded
systems, for example the ones requiring D-Bus and services
communicating between each other. It is worth noting that systemd
brings a fairly big number of large dependencies: dbus
, udev
and more. For more details about systemd
, see
http://www.freedesktop.org/wiki/Software/systemd.
The solution recommended by Buildroot developers is to use the BusyBox init as it is sufficient for most embedded systems. systemd can be used for more complex situations.
[3] This terminology differs from what is used by GNU configure, where the host is the machine on which the application will run (which is usually the same as target)