Skip to content

Buildroot: Minimal Linux Image

Time estimate: ~90+ minutes (build time depends on host CPU) Prerequisites: SSH Login

Learning Objectives

By the end of this tutorial you will be able to:

  • Build a minimal Linux image using Buildroot
  • Configure a Buildroot defconfig for Raspberry Pi 4
  • Compare boot time and image size between custom and stock images
  • Explain why custom images matter for embedded products
Why Build a Custom Linux Image?

A stock Raspberry Pi OS is designed for general-purpose use: ~4 GB image, 1,500+ packages, 100+ running services, and 20-40 second boot times. For an embedded product that runs a single application, most of that is waste. Building a custom image with Buildroot gives you dramatic improvements:

  • Boot time: 35 s down to 3-10 s -- by removing unnecessary services and packages
  • Image size: 4 GB down to 30-80 MB -- only what your product needs ships
  • Security surface: 1,500 packages down to ~20 -- fewer packages means fewer CVEs to track and patch
  • Reliability: a read-only rootfs is trivial to configure, making the device immune to filesystem corruption on power loss
  • Reproducibility: builds are deterministic -- the same config always produces the same image, unlike apt-based systems that depend on mirror state

Buildroot vs Yocto: Buildroot uses a simple menuconfig interface (like the Linux kernel), produces a single image, and is ideal for learning and small teams. Yocto is a more complex layer-based system with recipes, designed for multi-team products that need fine-grained package management. For this course and most single-application embedded devices, Buildroot is the right choice.

For a deeper treatment of custom image engineering, see the Building Custom Linux reference.


Introduction

Raspberry Pi OS is excellent for development but carries baggage for products: hundreds of packages, GUI services, update managers, and background daemons. A stock RPi OS image is ~4 GB; a minimal Buildroot image can be under 50 MB.

Buildroot is a build system that generates a complete Linux image (bootloader + kernel + rootfs) from source. You select exactly which packages to include, and nothing else ships.

Raspberry Pi OS Buildroot Minimal
Image size ~4 GB ~30-80 MB
Boot time 20-40 s 3-10 s
Running services 100+ 5-10
Package manager apt None (by design)
Reproducibility Depends on mirror state Fully reproducible

1. Install Build Dependencies

Concept: Buildroot runs on your workstation, not the target. This step prepares the host toolchain.

sudo apt-get update
sudo apt-get install -y build-essential git bison flex libssl-dev

2. Get Buildroot

Concept: Buildroot is a self‑contained build system that produces kernel + rootfs images.

git clone https://github.com/buildroot/buildroot.git
cd buildroot

3. Select Raspberry Pi 4 Config

Concept: The defconfig provides a known‑good baseline; you then trim or add features.

make raspberrypi4_64_defconfig
make menuconfig

menuconfig opens an ncurses text-based configuration interface. Navigate with arrow keys, press Enter to enter a submenu, and press Y to enable an option, N to disable it, or M for module (where supported). Press ? on any option to see its help text. When done, press Exit and save — your choices are written to a .config file that controls the entire build.

Host vs Target

Buildroot runs on your host machine (your x86 laptop or build server) and cross-compiles everything for the target (the Raspberry Pi's ARM CPU). The host downloads source packages, compiles them with a cross-compiler, and assembles the resulting binaries into a bootable SD card image. The target never compiles anything — it just runs the pre-built image.

Recommended changes for a minimal image:

  • Target options → Target Architecture — should be AArch64 (little endian) for RPi 4
  • System configuration → Root filesystem overlay directories — leave empty for now
  • System configuration → Enable root login — ensure enabled for testing
  • Filesystem images → ext4 — ensure rootfs is built as ext4
  • Target packages → Networking applications → dropbear — enable this lightweight SSH server (so you can SSH into the custom image)

What to disable (if enabled): - Any GUI/X11 packages - Multimedia libraries you don't need - Documentation and man pages

Stuck?

menuconfig can be overwhelming. Start with the defconfig as-is, build once to verify, then incrementally disable packages and rebuild.


4. Build

Concept: This produces a reproducible image; build time depends on host CPU.

make -j4

Output images are in output/images.

Warning

The first build takes 30-90 minutes depending on your host CPU and internet speed. Subsequent rebuilds are much faster (minutes) as Buildroot caches compiled packages.

Checkpoint

After make completes, verify the output:

ls -lh output/images/sdcard.img
The image should be 30-100 MB — dramatically smaller than a stock RPi OS image.


5. Flash to SD Card

Concept: You are writing a complete system image, not just files.

sudo dd if=output/images/sdcard.img of=/dev/sdX bs=4M status=progress
sync

6. Boot and Measure

Concept: Boot time is a measurable requirement, not just a feeling.

On boot:

systemd-analyze time

Record boot time and compare to Raspberry Pi OS.

Checkpoint

After booting the RPi from the new image: - You should see a login prompt on the serial console or SSH (if dropbear is enabled) - Login as root (default Buildroot password is empty unless you configured one)

Stuck?
  • Build fails with missing dependencies — install: sudo apt install -y build-essential git bison flex libssl-dev bc rsync cpio unzip wget
  • No network after boot — ensure dhcpcd or ifupdown is enabled in Buildroot config
  • Can't SSH — verify dropbear is included and your network is configured

What Just Happened?

You built an entire Linux system from source — bootloader, kernel, and root filesystem — and booted it on real hardware. The resulting image is a fraction of the size of stock RPi OS because you included only what you need.

Metric Raspberry Pi OS Your Buildroot Image
Image size
Boot time (systemd-analyze time)
Running processes (ps aux \| wc -l)
Installed packages

Fill in the table above as your deliverable.


Challenges

Challenge 1: Read-Only Root

Rebuild with a read-only root filesystem. Add an overlayfs setup for writable areas. Measure boot time difference.

Challenge 2: Add a Custom Application

Add a simple Python script to the Buildroot image using a rootfs overlay directory. Verify it runs on boot via a systemd service.

Deliverable

  • Completed comparison table (image size, boot time, process count)
  • Brief explanation: When would you choose Buildroot over Raspberry Pi OS?

Course Overview | Next: PREEMPT_RT Latency →