Buildroot is an open-source build system that automates the process of building a complete embedded Linux system — toolchain, bootloader, kernel, and root filesystem — from source. It was started in 2001 with a focus on simplicity, and that philosophy has made it one of the most approachable tools for embedded Linux development.
What is Buildroot?
Buildroot is a collection of Linux packages with build instructions for both host and target. It manages:
- Downloading source tarballs and Git repositories
- Applying cross-compilation patches
- Configuring and building each package
- Assembling the root filesystem
- Creating deployable image files
Buildroot Build Flow:
Configuration (make menuconfig)
|
v
Download sources (upstream tarballs)
|
v
Apply patches (cross-compilation fixes)
|
v
Build toolchain, bootloader, kernel, packages
|
v
Assemble root filesystem
|
v
Create image files (output/images/)
Buildroot Philosophy
Buildroot is designed around simplicity:
- A single Makefile-based build system
- Text-based configuration via
menuconfig - No package management on the target (no
apt, norpm) - No incremental package updates — a configuration change typically triggers a full rebuild
Best for:
- Learning embedded Linux concepts
- Simple, single-purpose devices
- Projects where a minimal, controlled image is the priority
Getting Started with Buildroot
Step 1: Install Prerequisites
Before using Buildroot, install the mandatory host packages (on Ubuntu/Debian):
sudo apt install build-essential libncurses-dev \
git wget unzip bc python3
Refer to the Buildroot User Manual for the complete list of prerequisites for your distribution.
Step 2: Clone Buildroot
git clone git://git.buildroot.net/buildroot
cd buildroot
Step 3: Explore Supported Configurations
Buildroot ships with default configurations (defconfig files) for hundreds of supported boards:
ls configs/
This lists all the boards that Buildroot supports out of the box, including Raspberry Pi variants, BeagleBone, STM32, and many more.
Configuring a Build
Load a Board Default Configuration
For example, to configure for an STM32MP157A Discovery board:
make stm32mp157a_dk1_defconfig
This creates a .config file with sensible defaults for that hardware platform.
Customise the Configuration
Open the menu-based configuration interface:
make menuconfig
**Note:** `ncurses` or `ncurses-dev` must be installed to use the menuconfig UI.
In menuconfig you can customise:
- Target architecture and CPU variant
- Toolchain — internal or external, glibc/musl/uClibc
- Bootloader — U-Boot version and configuration
- Linux kernel — version and defconfig
- System configuration — hostname, init system, getty
- Target packages — BusyBox, networking utilities, Python, etc.
Building the Image
Once satisfied with the configuration, start the build:
make
Buildroot will:
- Download all required source archives
- Build the toolchain (if using internal toolchain)
- Build the bootloader, kernel, and all packages
- Assemble the root filesystem
- Create output images
Build time depends on the configuration and host speed — expect anywhere from 30 minutes to several hours on the first build.
Build Output
When the build completes, output files appear in output/images/:
output/images/
├── rootfs.ext2 (root filesystem image)
├── sdcard.img (complete SD card image)
├── stm32mp157a-dk1.dtb (device tree blob)
├── u-boot.stm32 (bootloader binary)
└── zImage (Linux kernel image)
| File | Description |
|---|---|
rootfs.ext2 | Root filesystem as an ext2 image |
sdcard.img | Complete image for direct SD card writing |
*.dtb | Device tree blob for the target board |
u-boot.* | Bootloader binary |
zImage / Image | Linux kernel binary |
Flashing to Hardware
Use the dd command to write the SD card image directly to the storage device:
sudo dd if=output/images/sdcard.img of=/dev/mmcblk2 bs=1M
Parameters:
if=— input file (the Buildroot image)of=— output file (your SD card or eMMC device node)bs=1M— block size of 1 MB for efficient transfer
After flashing, eject the card, insert it into the target board, and power on.
Rebuilding After Changes
A key characteristic of Buildroot is that most configuration changes require a full rebuild. This is by design — it guarantees a consistent, reproducible image.
# Full clean rebuild
make clean
make
For minor changes (editing a package without changing configuration), you can rebuild just that package:
make <package-name>
make <package-name>-rebuild
Buildroot vs Yocto
| Aspect | Buildroot | Yocto |
|---|---|---|
| Learning curve | Low | High |
| Build speed | Fast | Slower initially |
| Customisation | Limited | Extensive |
| Incremental builds | Limited | Full incremental |
| Target package management | None | Optional (rpm/deb/ipk) |
| Best for | Simple projects, learning | Complex products |
Final Thoughts
Buildroot is an excellent starting point for embedded Linux development. Its simplicity means you can have a working image for a target board within hours of starting, without needing to understand the full depth of a system like Yocto.
Buildroot Quick Start:
git clone buildroot
|
v
make <board>_defconfig
|
v
make menuconfig (customise)
|
v
make (build everything)
|
v
dd to SD card (deploy)
|
v
Boot on hardware
Once you have mastered Buildroot and understand how the four embedded Linux elements (toolchain, bootloader, kernel, root filesystem) are built and assembled, you will have the foundation needed to move to more complex build systems like Yocto.