How to Buildroot Kernel Config and Build-Free Embedded Linux Course online

PREV_LEC NEXT_LEC
Buildroot Kernel Config and Build
A free Linux kernel development course lecture from EmbeddedPathashala
Module 6.1
Buildroot Series
Beginner Friendly

If you are following our free Linux kernel development course, you already know how to configure and cross-compile a kernel by hand using a toolchain and a defconfig. Buildroot takes that same workflow and wraps it inside a single reproducible build system, which is why it is one of the most popular tools taught in any serious free embedded Linux course. In this lecture of our free embedded systems course, we plug a custom kernel version and a custom device tree into Buildroot’s menuconfig, then produce a bootable image with one command.

Buildroot Linux Kernel Config Device Tree Cross Compilation defconfig Free Linux Kernel Development Course

What You Will Learn

  • How Buildroot’s menuconfig maps onto the kernel build steps you would otherwise run by hand
  • How to point Buildroot at a specific kernel version and an in-tree device tree source
  • How a single make invocation produces a complete bootable image set
  • How to freeze a working configuration with savedefconfig so it can be reproduced later

Prerequisites

  • Basic familiarity with cross-compilation, covered earlier in our free linux device drivers course
  • A Linux host with build essentials, git, ncurses dev headers, and a few GB of free disk space
  • Comfort navigating a curses-based configuration menu (the same UI as make menuconfig for the kernel itself)

Why Buildroot Wraps the Kernel Build

Building embedded Linux by hand means juggling at least four separate build systems: the toolchain, the bootloader, the kernel, and the root filesystem, each with its own configuration file and its own set of environment variables. Buildroot does not replace any of these tools. It generates the correct invocation for each one and stitches the outputs together into a single output/images directory. When you configure the kernel section inside Buildroot’s menuconfig, you are really telling Buildroot which source tree, which version, and which defconfig to hand to the standard kernel build machinery on your behalf.

This matters for reproducibility. A hand-written build script that hardcodes paths on your machine will not survive a teammate cloning the repository onto a different laptop. Buildroot’s configuration is a single text file, so the whole board support package – toolchain, kernel version, device tree, root filesystem packages – travels as one artifact.

Selecting a Kernel Version and Device Tree

Inside menuconfig, the Kernel submenu exposes the same choices you would set on the kernel command line yourself: which version to fetch, which defconfig fragment to seed it with, and which device tree source to build alongside it. On current Buildroot releases these options live under Kernel -> Linux Kernel, and the important fields are:

Kernel Submenu Fields
[*] Linux Kernel Kernel version → Custom version (6.6.32) Kernel version Kernel configuration → Using a custom config file (board/epboard/ep_defconfig) Configuration file path [*] Build a Device Tree Blob (DTB) Device tree source → Device tree present in the kernel sources (epboard) Device Tree Source file names Kernel binary format → Image

Two choices deserve extra attention. First, Kernel version can point at a tagged release, a git branch, or a custom version string if you maintain your own fork – always prefer a current long-term-support kernel for new designs rather than copying an old tutorial’s version number verbatim. Second, Device Tree Source file names only needs the base name, without the .dts extension; Buildroot resolves it against arch/<ARCH>/boot/dts/ inside the kernel tree it just checked out.

If your device tree lives outside the kernel tree – common when you are bringing up a brand-new board – switch Device tree source to In a directory and give Buildroot the path to your own .dts file. Buildroot copies it into the kernel source tree before invoking the kernel’s own DTB compiler, so it still benefits from every include file already shipped in the kernel.

Running the Build

Once the kernel section is configured alongside your toolchain, bootloader, and root filesystem choices, the entire board image is produced with a single command:

$ make

Buildroot resolves dependencies in the correct order – toolchain first, then bootloader, then kernel, then packages, then the final filesystem image – and only rebuilds the pieces that changed since the last run, similar to how a Makefile only rebuilds stale object files. On a clean checkout this first run can easily take thirty minutes to a couple of hours depending on your host machine, since it is compiling a full cross toolchain in addition to the kernel and every enabled package.

When the build finishes, the artifacts you actually flash or copy onto storage appear together in one directory:

$ ls output/images/
Image  epboard.dtb  rootfs.ext4  u-boot.bin  u-boot.img

Compare this with a manual build: you would normally have a kernel Image and a .dtb sitting in the kernel’s own arch/.../boot directory, a bootloader binary sitting in a completely different repository, and a root filesystem you assembled by hand with BusyBox and static device nodes. Buildroot’s real value is collecting all of that into one predictable output folder every single time.

Freezing a Working Configuration

Once you have a build that boots correctly on real hardware, the full .config generated by menuconfig is far too large and machine-specific to check into version control directly – it records absolute paths, timestamps, and every default value Buildroot ever offered. Instead, save a minimal defconfig that only lists the options you actually changed:

$ make savedefconfig BR2_DEFCONFIG=configs/epboard_defconfig
$ git add configs/epboard_defconfig board/epboard
$ git commit -m "Add EP board Buildroot configuration"

Anyone who later runs make epboard_defconfig from a clean checkout reproduces your exact toolchain, kernel version, device tree, and package selection – this is the same discipline the kernel itself uses for its own arch/*/configs/*_defconfig files, just applied one layer up.

Common Mistakes and Troubleshooting

SymptomLikely CauseFix
Build fails with a missing DTS file errorDevice tree name in menuconfig does not match a file under arch/<ARCH>/boot/dts/Check the exact base filename inside the checked-out kernel source, or switch to an external DTS directory
Kernel version mismatch after changing the version stringBuildroot cached the old kernel source downloadRun make linux-dirclean before rebuilding
Board hangs at bootloader, never reaches the kernelDTB not matching the board’s memory layoutVerify the correct DTS was selected and rebuilt with make linux-rebuild
savedefconfig output looks emptyAll options still match Buildroot’s defaultsExpected if you have not changed anything beyond the target architecture yet

Best Practices

  • Always pin an explicit kernel version string rather than tracking a moving branch, so builds stay reproducible months later
  • Keep board-specific device trees under board/<vendor>/<board>/ so the whole board support package sits in one place
  • Commit the defconfig, not the full .config, and regenerate the full config with make epboard_defconfig on every fresh checkout
  • Run make linux-menuconfig when you only need to tweak the kernel config without re-running the full top-level menuconfig

Summary and Key Takeaways

  • Buildroot’s Kernel submenu is a thin, structured front end over the same kernel version, defconfig, and device tree choices you would set manually
  • One make invocation produces every image the board needs, all landing in output/images
  • make savedefconfig is how a working board bring-up becomes a reproducible, version-controlled artifact

Conclusion

Configuring the kernel inside Buildroot is not a different skill from configuring the kernel by hand – it is the exact same skill, expressed through a menu that Buildroot then executes consistently every time. That consistency is precisely why Buildroot shows up in almost every free linux device drivers course and every serious production embedded Linux project: the same defconfig that built on your laptop last week will build identically on a CI server next year. Once your board boots from a Buildroot image, the next lecture in this free embedded linux course covers layering your own compiled programs onto the root filesystem using overlays.

Frequently Asked Questions

Does Buildroot download the kernel source itself?

Yes. Once you set a kernel version in menuconfig, Buildroot fetches the matching tarball or git tree automatically the first time you run make, and caches it under its download directory for reuse.

Can I use my own out-of-tree device tree with Buildroot?

Yes. Switch the device tree source option to point at an external directory containing your .dts file, and Buildroot copies it into the kernel tree before building the DTB.

Why does the first Buildroot build take so long?

The first run compiles a complete cross toolchain from source in addition to the kernel and root filesystem packages, which is far more work than a normal incremental kernel build.

What is the difference between the full .config and a defconfig?

The full .config lists every option Buildroot knows about, including defaults. A defconfig only lists the values you changed from the default, making it small enough to review and version control.

Is Buildroot only for kernel builds?

No. This lecture focuses on the kernel submenu, but Buildroot also configures the toolchain, bootloader, and hundreds of user-space packages in the same menu system.

Do I still need to understand cross-compilation to use Buildroot?

Yes. Buildroot automates the mechanics, but debugging a failed board bring-up still requires the same cross-compilation and kernel configuration knowledge taught throughout this free linux kernel development course.

Can I rebuild just the kernel without rebuilding everything else?

make linux-rebuild forces a kernel-only rebuild, and make linux-menuconfig opens just the kernel’s own configuration menu without touching the rest of the build.

Continue the Free Linux Kernel Development Course

Next up: layering your own programs onto the root filesystem with Buildroot overlays.

Next Lecture Browse the Full Course
PREV_LEC NEXT_LEC

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *