In embedded system development, building a usable Linux system image is never an easy task. Buildroot, as a lightweight and highly integrated build system, has become one of the preferred solutions for many embedded projects.
This article will quickly introduce you to the core features, advantages, and disadvantages of Buildroot, and in conjunction with engineering practices, explain how to customize the integration of third-party applications, the building method of BusyBox, the choice of init systems, and the importance of rootfs.
๐ง What is Buildroot?
Buildroot is an open-source, Make-based build tool designed to generate a complete cross-compilation toolchain, root filesystem (rootfs), Linux kernel image, bootloader, and user-space applications for embedded Linux systems.
It uses a Kconfig configuration system similar to the Linux kernel, which can be configured through <span>menuconfig</span> or <span>xconfig</span>. Buildroot does not rely on package managers but delivers the system by building a complete image in one go.
Core features include:
- Generating a cross-compilation toolchain (GCC + binutils + libc)
- Building Linux kernel images
- Integrating Bootloader (such as U-Boot)
- Building BusyBox, system tools, and third-party applications
- Building rootfs (supporting various formats such as ext4, cpio, ubi, etc.)
- Optional init systems (BusyBox init or systemd)
๐ What is rootfs? Why is it important?
<span>rootfs</span> (root filesystem) refers to the filesystem mounted as <span>/</span> after the system boots, which is the foundation for the operation of the Linux system. It typically contains:
<span>/bin</span>,<span>/sbin</span>: System executables (such as busybox, sh)<span>/lib</span>,<span>/lib64</span>: Shared library files<span>/etc</span>: Configuration files (such as inittab, fstab)<span>/dev</span>,<span>/proc</span>,<span>/sys</span>: Device and kernel interfaces<span>/usr</span>,<span>/home</span>,<span>/tmp</span>,<span>/var</span>, etc.
The role of rootfs:
- Providing a user-space runtime environment (Shell, scripts, configurations)
- Supporting the system boot process (such as the init process)
- Hosting business applications (such as Qt applications, network services, etc.)
In Buildroot, rootfs is an important component of the final image, usually output in the form of <span>rootfs.ext4</span>, <span>rootfs.cpio</span>, or <span>rootfs.tar</span>.
๐งฐ BusyBox: The Core of Minimal rootfs
BusyBox is known as the “Swiss Army Knife of Embedded Systems”; it packages commonly used Unix tools into a single executable file, which is small in size and full of functionality, making it the preferred shell toolset for embedded systems.
BusyBox’s Dual Role:
-
Core of Minimal rootfs Construction:
- A rootfs containing BusyBox and a few configuration files can boot a complete Linux system (suitable for initramfs)
- Basic commands such as Shell, ls, cp, init, ifconfig can be implemented with just a few hundred KB
Default init System:
- Buildroot uses the
<span>init</span>program provided by BusyBox by default - The configuration file is usually
<span>/etc/inittab</span>, which can define run levels and startup behaviors
Building and Configuration Methods:
In Buildroot:
- Enable it through
<span>menuconfig โ Target packages โ BusyBox</span> - Use
<span>make busybox-menuconfig</span>to configure enabled tool commands - You can choose whether to enable BusyBox’s init functionality
๐ช Init System: BusyBox vs. systemd
In Buildroot, there are two mainstream choices for the init system:
| Option | Features |
|---|---|
| BusyBox init | Small size, suitable for minimal embedded systems, simple configuration, based on <span>/etc/inittab</span> |
| systemd | Modern service management, supports dependencies, logging, socket activation, suitable for complex systems |
You can switch options in <span>menuconfig โ System configuration โ Init system</span>:
[*] /etc/inittab support (BusyBox init)
[ ] systemd
Selection Recommendations:
- If you are building a resource-constrained, fast-booting device, choose BusyBox init for a lighter option.
- If the project requires more complex service management and state tracking, it is recommended to use systemd.
โ Advantages of Buildroot
| Advantages | Description |
|---|---|
| ๐งฉ Integrated | Build system, toolchain, kernel, and user space are integrated together |
| ๐ง Flexible Configuration | Project customization through menuconfig, defconfig |
| ๐ฆ Rich Software Packages | Built-in a large number of mainstream open-source components (Python, Qt, network tools, etc.) |
| ๐ Clear Output | Output structure is standardized, suitable for flash burning and product release |
โ Disadvantages of Buildroot
| Disadvantages | Description |
|---|---|
| ๐ Full Build Each Time | For frequent debugging of user-space programs, build efficiency is not high |
| โ No Runtime Package Manager | Does not support <span>apt</span>, <span>opkg</span>, updating dependencies requires rebuilding |
| ๐งช Complex Patch Management | Not as easy to integrate large third-party components as Yocto |
| ๐ฑ High Customization Requires Experience | Custom package structure and patch management require understanding of internal mechanisms |
๐ ๏ธ Basic Usage Process of Buildroot
-
Obtain the source code:
git clone https://git.busybox.net/buildroot cd buildroot -
Select board configuration or customize:
make qemu_x86_defconfig -
Customize system configuration:
make menuconfig -
Start building:
make -
Output includes:
<span>output/images/</span>: Contains kernel, bootloader, rootfs images<span>output/target/</span>: Complete rootfs unpacked directory<span>output/staging/</span>: Cross-toolchain sysroot
๐ฆ How to Add Custom Third-Party Projects?
You can integrate your own C/C++ projects into Buildroot in the following ways:
Method 1: Add External Package
- Create a directory in
<span>package/yourapp</span> - Add
<span>Config.in</span>and<span>yourapp.mk</span>files - Modify
<span>package/Config.in</span>to include references
Example of yourapp.mk:
YOURAPP_VERSION = 1.0
YOURAPP_SITE = $(TOPDIR)/../yourapp
YOURAPP_SITE_METHOD = local
define YOURAPP_BUILD_CMDS
$(MAKE) -C $(@D)
endef
define YOURAPP_INSTALL_TARGET_CMDS
$(INSTALL) -m 0755 $(@D)/yourapp $(TARGET_DIR)/usr/bin
endef
$(eval $(generic-package))
Method 2: Use <span>BR2_EXTERNAL</span>
By using the <span>BR2_EXTERNAL</span> mechanism, you can centralize third-party packages in an external directory, making it easier to maintain a shared package repository for multiple projects.
- Advantages: Avoid direct modification of Buildroot source code, facilitating upgrades and reuse
๐ Alternatives and Extensions to Buildroot: Why Focus on Yocto?
Although Buildroot is very effective for the “overall build system”, it is not ideal for user-space program development, incremental compilation, and multi-version management.
This leads to another more comprehensive build system – Yocto.
Yocto is more suitable for embedded projects that require long-term maintenance, complex dependencies, and modular component management, and is the basis for many commercial Linux distributions.
In the next article, we will detail:
- Comparison of design philosophies between Yocto and Buildroot
- Yocto’s metadata-driven build system
- How to build highly configurable rootfs and SDK
๐ Summary
Buildroot is the “standard path” for building embedded Linux systems, especially suitable for prototype development, customized devices, and lightweight scenarios. By integrating BusyBox, the kernel, and the toolchain, it quickly produces a complete rootfs image.
Whether choosing BusyBox init or systemd, Buildroot can meet the construction needs from minimal to medium-sized systems.
However, as project scale increases or long-term maintenance is required, Yocto offers more flexible package management and build control capabilities.
๐ Next Article Preview: Deep Dive into Yocto – Building an Enterprise-Level Embedded Linux Build Platform!
Author: Ling Zao Ge Focused on Linux, embedded, and robotic system development, feel free to follow my public account to explore the beauty of low-level builds together.