[WIP] Buildroot Project Characterization
Purpose
We want to create a slimmed-down Linux OS for use on a Raspberry Pi (cm5) as the Controls Display system.
Today, two solutions are emerging as the most popular ones
• Yocto/OpenEmbedded : Builds a complete Linux distribution with binary packages. Powerful, but somewhat complex and quite steep learning curve.
• Buildroot: Builds a root filesystem image, no binary packages. Much simpler to use, understand
and modify.
Metrics
The major metrics being evaluated are:
Boot Time
Memory Footprint
Memory Footprint Under Load
Power Draw
How it Works
Buildroot is a tool that simplifies and automates the process of building a complete Linux system for embedded devices. Think of it as a “Linux distribution builder.” It takes source code for the kernel, boot-loader, libraries, and applications, then compiles everything into a working system image you can flash onto hardware. Buildroot’s power comes from its simplicity; it’s just Makefiles and shell scripts orchestrating standard tools.
General Tips
1. The Buildroot Source Tree
When you download Buildroot, you get a directory structure like this:
buildroot/
├── arch/ # Architecture-specific configurations
├── board/ # Board-specific files (scripts, configs, overlays)
├── boot/ # Bootloader packages (U-Boot, GRUB, etc.)
├── configs/ # Pre-made defconfig files for various boards
├── package/ # All available software packages
├── system/ # System configuration files (init, device tables)
├── toolchain/ # Toolchain configuration and build
├── linux/ # Linux kernel build infrastructure
└── fs/ # Filesystem image generators
2. Configuration System
Buildroot uses the same Kconfig system as the Linux kernel. You configure your build using:
make menuconfig # Interactive menu-based configuration
make nconfig # Newer ncurses interface
make xconfig # Graphical Qt-based interface
This creates a .config file that defines:
Target architecture (ARM, x86, MIPS, etc.)
Which packages to include
Kernel version and configuration
Bootloader settings
Filesystem type (ext4, squashfs, initramfs, etc.)
Toolchain options
3. The Toolchain
The toolchain is the set of tools needed to compile code for your target
Compiler: GCC or LLVM/Clang that generates code for your target CPU
C Library: uClibc, glibc, or musl
Binutils: Assembler, linker, and binary utilities
Debugger: GDB for debugging
Buildroot can either:
Build its own toolchain (internal toolchain) - takes longer but is fully controlled
Use an external toolchain - faster, useful if you already have one, ex: Bootlin
4. The Build Process
When you run make, Buildroot follows this sequence:
Build/download toolchain
↓Build host utilities (needed for building)
↓Build target packages (in dependency order)
↓Build Linux kernel
↓Build bootloader
↓Create root filesystem
↓Generate final images
Everything Buildroot builds goes into the output/ directory:
output/
├── build/ # Extracted and built package sources
├── host/ # Tools that run on your build machine
├── staging/ # Sysroot with headers/libraries for compiling
├── target/ # The actual root filesystem for your device
└── images/ # Final bootable images (kernel, rootfs, etc.)
5. Dependency Management
Buildroot automatically handles dependencies. When you select a package that depends on others, Buildroot:
Enables required dependencies automatically
Builds them in the correct order
Ensures the dependency's headers/libraries are available
6. Filesystem Overlays
You can customize the root filesystem using overlays - directories that get copied over the generated filesystem:
bash
BR2_ROOTFS_OVERLAY="board/mycompany/myboard/rootfs_overlay"This lets you add custom files like:
Configuration files (
/etc/network/interfaces)Custom scripts
Additional binaries
Device-specific data
Typical Workflow
1. Initial Setup
bash
# Clone Buildroot
git clone https://github.com/buildroot/buildroot.git
cd buildroot
# Start with a defconfig if your board is supported
make raspberrypi4_64_defconfig
# Or create a custom configuration
make menuconfig2. Configuration
In menuconfig, you'll configure:
Target Options:
Architecture (ARM, x86_64, MIPS, etc.)
CPU variant (Cortex-A53, etc.)
Floating point support
Build Options:
Number of parallel jobs
Download directory (to cache sources)
Compiler optimizations
Toolchain:
C library choice
GCC version
Kernel headers version
System Configuration:
Hostname
Root password
Init system (BusyBox init, systemd, etc.)
Network configuration
Kernel:
Kernel version
Custom kernel config
Device tree files
Target Packages:
Select all the software you need
Libraries, utilities, GUI applications, etc.
Filesystem Images:
ext4, squashfs, tar, cpio, etc.
Size limits
Compression
Bootloaders:
U-Boot, GRUB, etc.
3. Building
bash
# Build everything
make
# Build with multiple cores
make -j$(nproc)
# Rebuild a single package
make <package>-rebuild
# Clean a single package
make <package>-dirclean4. Output
After the build completes (typically 30 minutes to 2 hours), check output/images/:
output/images/
├── rootfs.ext4 # Root filesystem image
├── zImage # Kernel image
├── bcm2711-rpi-4-b.dtb # Device tree blob
└── sdcard.img # Complete SD card image (if configured)5. Flashing and Testing
# Flash to SD card
sudo dd if=output/images/sdcard.img of=/dev/sdX bs=1M status=progress
Notes
There are several options for cross-compiling a full Linux system; Yocto, OpenWRT, and Buildroot are the three most common. These systems are generally hosted on a standard desktop Linux distribution and will cross-build a Linux system for your chosen target device.
References
https://buildroot.org/downloads/manual/manual.html#_getting_started
https://buildroot.org/docs.html