为嵌入式 Linux 构建根系统 — 第 1: 您的第一个构建根文件系统

2026年8月23日2 次浏览来源:Dev.to阅读原文

正文保留英文原文(机翻易破坏代码与排版),标题/摘要已提供中文

Buildroot builds a cross-compiler, a Linux kernel and a complete root filesystem from source, driven by one Kconfig-style configuration file.

Starting from the that ships with Buildroot 2026.05.1, two commands produce a bootable ARM system you can run under QEMU.

The images you ship are the ones in ; looks like a root filesystem but must never be copied to a device.

This post starts a new hands-on series on Buildroot for embedded Linux.

By the end of this part you will have built a working Buildroot root filesystem for an ARM target, booted it under QEMU, and understood which generated directories are safe to ship.

Later parts add your own packages, a tree, kernel and bootloader integration, and reproducible image output.

If the choice between build systems is still open, our earlier Yocto vs Buildroot comparison covers it; this series assumes the decision is made.

What you need A Linux host, several gigabytes of free disk space, and a network connection.

No development board is needed for this part; QEMU stands in for the hardware.

On a Debian or Ubuntu host, this covers the mandatory packages the manual lists, plus the ncurses development files that needs: One rule from the manual is worth stating plainly: build everything as a normal user.

Buildroot never needs root, and running it as root exposes your host to any package that misbehaves during installation.

The command above is the only one in this post that uses .

Getting Buildroot and choosing a target Download and unpack the current stable release — 2026.05.1 at the time of writing — from buildroot.org/downloads, and work from that directory.

Buildroot ships ready-made configurations for many boards and emulated machines, one file each in , and prints them all.

We will use the ARM Versatile Express machine, because QEMU emulates it and Buildroot builds the matching QEMU binary for you: Now read that configuration file.

It is twenty-two lines long, and reading it is the fastest way to understand what a Buildroot target definition is: Six of those lines carry most of the meaning: A Cortex-A9 core, Linux 6.18.7 configured from the in-tree defconfig, the device tree, and a 64 MB ext2 root filesystem image.

The remaining lines set a patch directory, DHCP on , a post-image script and a host build of QEMU; work out what each one does before moving on.

Note also what is absent from the whole file: no C library, no init system, no package list.

Those come from Buildroot's own defaults, which we look at shortly. opens the same options interactively; you can skip it for now.

Start the build.

Buildroot does not support top-level parallel builds by default, so is not required here — it parallelises compilation within each package instead: The first run takes a while, because the cross-compilation toolchain is built from source before anything else; later builds reuse it.

What a Buildroot root filesystem actually contains Everything Buildroot produces lands in a single directory.

Two of its subdirectories decide whether your image works: — the finished artefacts: kernel image, device tree blob, bootloader and root filesystem images.

These are the files you put on the target. — almost the root filesystem, but not usable as one.

Buildroot does not run as root, so it cannot create the device nodes in and cannot set the correct permissions, for example setuid on the BusyBox binary.

Copying this directory to a device gives a system that does not boot correctly.

If you need an extracted root filesystem, for NFS boot say, build the tarball image in and extract that as root instead.

Booting the image under QEMU Every emulated machine ships a readme with the exact command line.

Read it rather than guessing at QEMU options: Because the defconfig enabled , Buildroot has already built a matching QEMU under , so your distribution's QEMU package is not needed: The kernel boot messages appear in the terminal that started QEMU, because attaches the emulated serial port to your shell.

A separate graphical window shows the framebuffer; you can ignore it.

After a few seconds the boot ends at a login prompt: Log in as .

There is no password.

The banner comes from and the machine name from , both generated by Buildroot from configuration options.

To shut down cleanly, run inside the target; to force QEMU to exit, press and then .

The defaults that shape your Buildroot root filesystem The defconfig named none of the following, which is exactly why they are worth knowing.

Each is a decision you will eventually revisit: C library: glibc.

When Buildroot builds its own toolchain, the default C library is glibc. uClibc-ng and musl are the alternatives, chosen under the Toolchain menu.

Init system: BusyBox.

BusyBox provides a small that reads .

Buildroot's default inittab lives in ; it mounts , remounts the root filesystem read-write, runs , and starts a getty. systemV, OpenRC and systemd are the alternatives.

Device nodes: devtmpfs only.

The kernel populates itself.

This needs and in the kernel configuration.

Buildroot enables both when it builds the kernel for you, but if you bring an externally built kernel and forget them, the system will not boot.

Add or on top once devices need firmware loading or module autoloading.

Root login: enabled, with an empty password.

Convenient on a development board and unacceptable on a product.

Set a password before you ship.

Serial console: the defconfig sets to match the Versatile Express UART.

The generic default is .

On a real board this option is the most common cause of "it boots but there is no login prompt".

Saving your configuration so the build is reproducible The file holds thousands of lines, most at their default values, and is not the thing to commit to version control.

Buildroot can strip it down for you: This writes a minimal defconfig containing only the options you changed.

Storing it as is the recommended convention: it then appears in , and anyone can reproduce your configuration: One more habit is worth forming now: Buildroot does not track configuration changes incrementally.

If you change any architecture or toolchain option, an explicit is required, and removes the configuration as well.

Skipping this causes builds that fail in ways that make no sense.

If you would rather learn this workflow on real hardware, with board bring-up and image deployment done end to end, that is what our Embedded Linux and Yocto programme covers.

Key takeaways One small defconfig describes a whole Buildroot target — twenty-two lines specified our ARM system, kernel included. holds what you ship. lacks device nodes and correct permissions, and must not be copied to a device.

The unstated defaults matter: glibc, BusyBox init, devtmpfs-only device management, and root login with no password.

Each emulated machine ships a readme with a working QEMU command line, and Buildroot can build the matching QEMU.

Use for a minimal, reviewable configuration, and after any architecture or toolchain change.

What's next in this series Part 2 covers adding packages to the image and setting up a tree, so your own configuration and recipes live outside the Buildroot source directory and survive an upgrade to the next release.

Frequently asked questions Do I need a development board to follow this part?

No.

The configuration targets an ARM machine that QEMU emulates, and Buildroot builds the matching QEMU binary.

A Linux host with several gigabytes of free disk space is enough.

Why should I not copy output/target/ to my device?

Buildroot runs as a normal user, so it cannot create device nodes in and cannot set permissions such as setuid on the BusyBox binary.

The directory looks complete but produces a system that does not boot correctly.

Use an image from instead.

Which C library does Buildroot use by default?

When Buildroot builds its own toolchain, the default C library is glibc. uClibc-ng and musl are selectable alternatives under the Toolchain menu.

Should I run make with -jN to speed up the build?

Not by defa

分享