2. 环境搭建与首次构建:宿主机环境准备、获取源码、配置与编译
说实话,很多做嵌入式的朋友第一次接触 Buildroot 时,都卡在环境搭建这一步。不是工具链装不对,就是依赖包缺胳膊少腿。我个人习惯是先把宿主机环境收拾利索了,再碰源码。磨刀不误砍柴工嘛。
2.1 宿主机环境准备(Ubuntu/Debian)
我建议你直接用 Ubuntu 20.04 LTS 或 22.04 LTS,Debian 11/12 也行。别用太老的版本,否则有些依赖包版本不够,编译到一半报错,那才叫头疼。
先更新包管理器,然后安装基础构建工具:
sudo apt update
sudo apt upgrade -y
sudo apt install -y \
build-essential \
git \
wget \
cpio \
unzip \
file \
bc \
rsync \
libncurses-dev \
libssl-dev \
flex \
bison \
python3 \
python3-pip \
python3-venv \
cmake \
ninja-build \
pkg-config \
libelf-dev \
libgmp-dev \
libmpc-dev \
libmpfr-dev \
texinfo \
gawk \
patchelf \
u-boot-tools \
device-tree-compiler
libncurses-dev,没有它你连 make menuconfig 都跑不起来。
如果你用的是 Ubuntu 22.04,还需要额外装一个:
sudo apt install -y libncursesw5-dev
嗯,这里要注意。不同 Ubuntu 版本对 ncurses 的包名拆分不太一样。我曾在 22.04 上漏了这个,结果 menuconfig 界面花屏,折腾了半天才发现是缺了这个。
2.2 获取 Buildroot 源码
Buildroot 的源码托管在 GitHub 上。我个人习惯用 git clone 而不是下载压缩包,因为后面方便切分支、看提交历史。
git clone https://github.com/buildroot/buildroot.git
cd buildroot
克隆完之后,看看有哪些稳定版本:
git tag | grep -E '^20[0-9]{2}\.[0-9]{2}' | sort -V
我建议你选最新的 LTS 版本。比如 2024.02.x 系列。为什么要用 LTS?说白了,长期维护版 bug 修得多,社区支持也久。我刚开始用 Buildroot 时图新鲜追最新版,结果碰到一个工具链的 regression,折腾了两天才回退。
git checkout 2024.02.1
2.3 配置目标平台
Buildroot 支持大量目标平台。你可以先看看内置的默认配置:
ls configs/ | head -20
输出大概长这样:
| 配置名 | 目标平台 | 架构 |
|---|---|---|
| raspberrypi4_64_defconfig | Raspberry Pi 4 | aarch64 |
| beaglebone_defconfig | BeagleBone Black | arm |
| qemu_x86_64_defconfig | QEMU x86-64 | x86_64 |
| stm32mp157c_dk2_defconfig | STM32MP157C-DK2 | arm |
如果你手头没有真实开发板,我强烈建议先用 QEMU 的配置练手。这样不用买硬件,也能跑起来。我自己带新人时,都是让他们先跑 QEMU 版本,熟悉了流程再上真板子。
make qemu_x86_64_defconfig
这条命令会把默认配置写入 .config 文件。如果你想微调,可以运行:
make menuconfig
menuconfig 界面里,你可以调整目标架构、工具链类型、包选择、文件系统格式等等。不过第一次构建,我建议先不动任何选项,直接用默认配置编译一次,看看整个流程能不能跑通。
2.4 执行首次编译
配置好之后,直接开编:
make
第一次编译会下载所有源码包、构建交叉编译工具链、编译内核、构建根文件系统。这个过程……嗯,有点慢。取决于你的网络和机器性能,通常需要 30 分钟到 2 小时不等。
如果你想利用多核加速,可以指定并行任务数:
make -j$(nproc)
我个人习惯先用 make -j4,因为有些 Makefile 的依赖关系写得不够严谨,并行数太多反而会报错。等确认没问题了,再开满核心。
dl/,你可以手动把包放进去,然后重新运行 make。
编译成功的话,最后会看到类似这样的输出:
>>> Generating root filesystem image
>>> Generating image(s)
/usr/bin/mkdir -p /home/user/buildroot/output/images
...
Build complete.
2.5 理解输出目录结构
编译完成后,所有产出都在 output/ 目录下。我第一次看到这个目录时,说实话有点懵。里面东西不少,但搞清楚之后就觉得很有条理。
output/
├── build/ # 每个包的构建目录
├── host/ # 主机工具和交叉工具链
├── images/ # 最终镜像文件
├── staging/ # 目标系统的头文件/库(用于交叉编译)
├── target/ # 目标根文件系统的展开目录
└── .config # 当前配置
我来逐个说说:
- images/ —— 你最关心的目录。里面放着最终生成的镜像文件,比如
rootfs.cpio、zImage、sdcard.img等。烧录到板子上用的就是这些。 - build/ —— 每个软件包的编译工作目录。如果某个包编译失败,可以进到对应的目录里看 log 文件排查问题。
- host/ —— 交叉编译工具链和一些主机端工具,比如
arm-linux-gcc、mkimage等。如果你需要手动交叉编译某个第三方库,可以把这个目录的bin/加到 PATH 里。 - target/ —— 目标系统的根文件系统展开后的目录。你可以进去看看里面有哪些文件、库、可执行程序。不过注意,这个目录里的文件是 Buildroot 构建时的中间产物,不要直接用它做根文件系统。
- staging/ —— 用于交叉编译的头文件和库。如果你要在主机上为 target 编译额外的程序,需要链接这里的库。
output/images/ 看看生成了哪些文件。如果发现少了某个镜像,说明配置里可能漏选了对应的选项。比如没有生成 sdcard.img,那大概率是没选 BR2_TARGET_GENERIC_ROOTFS_EXT2 或 BR2_PACKAGE_HOST_GENIMAGE。
下面这张图帮你理清整个构建流程和输出目录的关系:
最后,验证一下镜像是否生成成功:
ls -lh output/images/
对于 QEMU x86_64 配置,你应该能看到 rootfs.cpio 和 bzImage。用 QEMU 启动试试:
qemu-system-x86_64 \
-kernel output/images/bzImage \
-initrd output/images/rootfs.cpio \
-append "console=ttyS0" \
-nographic
看到内核启动日志,最后出现 buildroot login: 提示符,说明你的环境搭建和首次构建完全成功了。