Raspberrypi and Buildroot - johnosbb/Automation GitHub Wiki
Buildroot Configuration
Buildroot is an invaluable open-source tool for embedded Linux development, streamlining the creation of highly customized and minimal Linux systems, perfect for resource-constrained devices like the Raspberry Pi. It achieves this by automating the entire build process, from fetching source code to compiling the cross-compilation toolchain, bootloader, Linux kernel, and ultimately generating a root filesystem image. For Raspberry Pi users, Buildroot offers "defconfigs" (default configurations) tailored for various models, such as raspberrypi_defconfig (for older models), raspberrypi3_defconfig, and raspberrypi5_defconfig. These defconfigs provide an excellent starting point, pre-selecting the necessary components and settings to get a functional Linux image for your specific Raspberry Pi hardware, which you can then further customize using make menuconfig to include desired applications and features.
Downloading Buildroot
You can download buildroot from here. Or, you can download stable releases as compressed tarballs from the official Buildroot website's download page: buildroot downloads
Configuring for a specific Pi Model
Raspberry Pi models from the original Pi 1 through to the latest Pi 5 are well-supported, allowing you create highly optimized and compact embedded systems for a wide range of applications.
To configure for the Raspberry Pi 3 model we would run:
make raspberrypi3_defconfig
Customizing the Configuration
In Buildroot, an overlay is a mechanism that allows you to customize your build without directly modifying the Buildroot source code. Think of it as a transparent layer placed on top of the standard Buildroot directories. When Buildroot goes to look for a file (like a package definition, a board configuration, or a root filesystem file), it first checks your overlay directories. If the file exists there, Buildroot uses the version from your overlay; otherwise, it falls back to its own internal files. This "lookup" order is crucial.
The simplist form of overlay is the Root Filesystem Overlay (BR2_ROOTFS_OVERLAY). This is a simpler type of overlay specifically for the root filesystem. The directory specified by BR2_ROOTFS_OVERLAY (or multiple directories separated by spaces) contains files and directories that will be copied directly on top of the generated root filesystem.
For example, if you have:
my_rootfs_overlay/
├── etc/
│ └── my_custom_file.conf
└── usr/
└── bin/
└── my_script.sh
These files will end up in /etc/my_custom_file.conf
and /usr/bin/my_script.sh
on your target device, potentially overwriting existing files in the root filesystem if they have the same path.
You configure this in make menuconfig under "Filesystem images" -> "Root filesystem overlays"
.
Creating an Root Filesystem Overlay directory overlay:
cd buildroot_pi
mkdir overlay
mkdir -p overlay/etc/network
Configure the overlay location in menuconfig. Under System Configuration select the option for overlay.
Configuring for a Static IP Address
place an interfaces file in overlay/etc/network
auto eth0
iface eth0 inet static
address 192.168.1.178
netmask 255.255.255.0
gateway 192.168.1.254
hostname $(hostname)
Buildroot Packages
In Buildroot, the concept of "packages" is central to building your embedded Linux system. A package represents a piece of software (like BusyBox, OpenSSH, or a custom application) that Buildroot can download, configure, compile, and install onto your target device's root filesystem. Buildroot provides a vast collection of pre-defined packages, each with its own .mk file (Makefile fragment) that specifies its version, download location, dependencies, and build steps. Users enable or disable these packages primarily through Buildroot's intuitive make menuconfig interface. Navigating the hierarchical menus, typically under "Target packages," allows you to select or deselect specific software components. When a package is enabled (marked with [*]), Buildroot automatically ensures all its necessary build-time and run-time dependencies are also included. Conversely, disabling a package removes it and any of its unique dependencies, resulting in a smaller, more optimized final image. This granular control over packages empowers developers to create highly customized and minimal systems, only including what's strictly required for their application, thereby saving valuable flash and RAM resources on embedded devices like the Raspberry Pi.
Buildroot can be a little unpredictable about when newly added packages are included in the rootfs, so after turning on a package we may need to force its inclusion in the rootfs, for example, to enable ssh access one would run the commands below:
make dropbear-reinstall
make openssh-reinstall
make
Saving your Configuration
Buildroot will save our configuration in the path set by BR2_DEFCONFIG. So when we do a make savedefconfig that file will be updated.
BR2_DEFCONFIG="/mnt/500GB/buildroot_pi/buildroot_2025/configs/raspberrypi3_defconfig"
Our kernel configuration is based on
BR2_LINUX_KERNEL_USE_DEFCONFIG=y
BR2_LINUX_KERNEL_DEFCONFIG="bcm2709"
These reference a kernel configuration found in
./output/build/linux-headers-custom/arch/arm/configs/bcm2709_defconfig
./output/build/linux-custom/arch/arm/configs/bcm2709_defconfig
We can save a modified config with
make linux-update-defconfig
make linux-update-defconfig can be configured to save the linux configuration to a specified path by setting BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG. It simplifies the config file by removing default values. However, this only works with kernels starting from 2.6.33.
Flashing Images
The most straightforward way of flashing your image to the board is to use the pri-imager. On Ubuntu this can be installed with
sudo apt install rpi-imager
You can also flash the image using a script built around the dd command as shown below.
IMAGE=sdcard.img
SDCARD_LOCATION=/dev/sde
IMAGE_PATH=/mnt/500GB/buildroot_pi/buildroot_2025/output/images/
#rm -rf $IMAGE_PATH/*.img
echo "Writing image $IMAGE ..."
sudo dd if=$IMAGE_PATH/$IMAGE of=$SDCARD_LOCATION bs=4M status=progress
echo "Syncing changes ..."
sync
You can extend this to be more elaborate with error checking and warnings as shown in the next script:
#!/bin/bash
# Usage: sudo ./flash_pi_image.sh /path/to/SDCard.img /dev/sdX
# Example: sudo ./flash_pi_image.sh ./SDCard.img /dev/sde
set -e
IMAGE="$1"
DEVICE="$2"
# Validate arguments
if [ -z "$IMAGE" ](/johnosbb/Automation/wiki/|--z-"$DEVICE"-); then
echo "Usage: sudo $0 /path/to/SDCard.img /dev/sdX"
exit 1
fi
if [ ! -f "$IMAGE" ](/johnosbb/Automation/wiki/-!--f-"$IMAGE"-); then
echo "Error: Image file '$IMAGE' does not exist."
exit 1
fi
if [ ! -b "$DEVICE" ](/johnosbb/Automation/wiki/-!--b-"$DEVICE"-); then
echo "Error: Device '$DEVICE' is not a valid block device."
exit 1
fi
# Confirm with user
echo "You are about to write '$IMAGE' to '$DEVICE'"
echo "This will ERASE all data on $DEVICE!"
read -rp "Are you sure? (yes/NO): " confirm
if [ "$confirm" != "yes" ](/johnosbb/Automation/wiki/-"$confirm"-!=-"yes"-); then
echo "Aborted."
exit 1
fi
echo "Unmounting any mounted partitions on $DEVICE..."
for part in $(ls ${DEVICE}?* 2>/dev/null); do
sudo umount "$part" 2>/dev/null || true
done
echo "Writing image..."
sudo dd if="$IMAGE" of="$DEVICE" bs=4M status=progress conv=fsync
echo "Syncing..."
sync
echo "Ejecting..."
sudo eject "$DEVICE"
echo "Flash complete. You can now remove the SD card."
Serial Port Connection
Kernel Debugging
The vmlinux file can be found in ./output/build/linux-custom/vmlinux
.