第2章:Buildroot环境搭建

好,咱们正式开始动手。这一章的目标很明确——在你的Ubuntu 22.04上把Buildroot环境跑起来,并且完成第一次编译。别小看这一步,环境搭得顺不顺,直接影响后面几十章的心情。我见过太多人在依赖包上卡半天,最后发现是版本不对。

2.1 安装依赖包

Ubuntu 22.04是个不错的起点。它够新,但又不至于激进到让你踩坑。我个人习惯是先把基础编译工具链装全,免得编译到一半报错说缺这个缺那个。

打开终端,执行下面这条命令:

sudo apt update
sudo apt install -y \
    git \
    gcc \
    g++ \
    make \
    cmake \
    autoconf \
    automake \
    libtool \
    pkg-config \
    libncurses5-dev \
    libssl-dev \
    flex \
    bison \
    bc \
    rsync \
    unzip \
    wget \
    cpio \
    python3 \
    python3-pip \
    python3-venv \
    file \
    lzop \
    zstd

这里我重点提几个容易忽略的:

  • libncurses5-dev:Buildroot的menuconfig界面依赖它。没装的话,你连配置菜单都打不开。
  • flex 和 bison:这两个是词法分析和语法分析工具。Buildroot内部有些脚本依赖它们生成代码。
  • cpio:制作initramfs文件系统时必备。我第一次编译qemu_x86_64时忘了装,结果卡在打包阶段,查了半天日志才发现。
小提示:如果你用的是Ubuntu 20.04或更早版本,记得把python3换成python,或者单独装python-is-python3。Buildroot有些脚本默认调用python,而不是python3。

2.2 下载Buildroot源码

依赖装完,接下来拿源码。我建议用git clone,而不是下载压缩包。为什么?因为git能让你随时切换分支、查看历史、回退版本。做嵌入式开发,版本管理是基本功。

cd ~
git clone https://git.buildroot.net/buildroot
cd buildroot

克隆完成后,你可以看看当前在哪个版本:

git tag | tail -5

我写这章时,最新的稳定版是2024.02.x。如果你想跟着课程走,建议切到同一个大版本:

git checkout 2024.02
注意:不要直接使用master分支。master是开发分支,可能包含未稳定的改动。我曾经在master上编译到一半,发现某个包的新版本有bug,折腾了两天才定位到问题。稳定版才是你的朋友。

2.3 目录结构解析

源码下载完,先别急着编译。花五分钟看看目录结构,后面你会感谢自己。Buildroot的目录设计很清晰,我把它分成几个核心区域:

目录/文件 作用 我的经验
package/ 所有软件包的构建脚本,按包名分目录 你后面加新功能,90%的时间都在这里
configs/ 预置的默认配置文件,比如qemu_x86_64_defconfig 从这里开始,省去从头配置的麻烦
board/ 板级支持文件,包括设备树、分区表、启动脚本 换板子时,这里是你主要修改的地方
fs/ 文件系统构建逻辑,比如ext4、squashfs、cpio 默认用ext4,但嵌入式场景常用squashfs
linux/ Linux内核的构建入口 Buildroot会自动下载并编译内核
boot/ 引导加载程序,比如U-Boot、GRUB qemu_x86_64默认用GRUB
output/ 编译产物,第一次编译后自动生成 这个目录很大,别往git里提交
dl/ 下载的源码包缓存 第二次编译会快很多,因为不用重新下载

嗯,这里有个细节要注意——output/和dl/都是编译过程中自动生成的。你第一次clone完,它们还不存在。别慌,编译一次就有了。

为了让你更直观地理解这些目录之间的关系,我画了一张图:

Buildroot 核心目录结构及数据流 buildroot/ package/ configs/ board/ fs/ output/ dl/ images/ build/ target/ host/ 数据流向说明: 1. configs/ 提供默认配置 → 驱动 package/ 选择哪些包要编译 2. package/ 从 dl/ 获取源码 → 编译到 output/build/ 3. board/ 提供板级文件 → 最终打包到 output/images/ 4. output/images/ 包含最终产物:内核、文件系统、引导程序

2.4 首次编译体验

好了,重头戏来了。第一次编译,我建议你选一个最简单的目标——qemu_x86_64。它不需要真实硬件,编译完直接用QEMU虚拟机跑,最适合验证环境。

执行以下两步:

make qemu_x86_64_defconfig
make

就这么简单?嗯,第一行命令是加载预置配置,第二行就是开始编译。但这里有几个坑,我得提前跟你说:

常见问题:
  • 编译时间:第一次编译大约需要30分钟到2小时,取决于你的网络和CPU。Buildroot会下载所有依赖包的源码,然后交叉编译。我建议你泡杯咖啡,或者去干点别的。
  • 网络问题:如果下载失败,检查dl/目录。Buildroot会把下载好的包缓存到这里。下次编译时,如果包已经存在,就不会重新下载。
  • 磁盘空间:确保至少有10GB空闲空间。output/目录会膨胀到5-8GB。

编译成功后,你会看到类似这样的输出:

>>>   Generating root filesystem image
>>>   Generating images
>>>   Done

然后看看output/images/里有什么:

ls -lh output/images/

你会看到:

  • bzImage:编译好的Linux内核
  • rootfs.ext2:根文件系统镜像
  • start-qemu.sh:启动脚本,直接运行就能进系统

运行一下试试:

./output/images/start-qemu.sh

如果一切顺利,你会看到一个QEMU窗口弹出,Linux内核开始启动,最后出现登录提示符。默认用户名是root,没有密码。

验证要点:
  • 系统能正常启动到登录提示符
  • 执行uname -a能看到内核版本
  • 执行free -m能看到内存信息
  • 执行ls /能看到根文件系统目录结构

我第一次编译成功时,看到那个登录提示符,心里还是挺激动的。说白了,这就是嵌入式开发的"Hello World"。你从零开始,让一个完整的Linux系统跑了起来——虽然是在虚拟机里,但背后的编译流程、依赖关系、文件系统构建,跟真实硬件完全一致。

小技巧:如果你觉得每次编译都从头开始太慢,可以试试make -j$(nproc),用多核加速。但第一次编译建议不加-j参数,方便看日志排查问题。

嗯,到这里,环境搭建就完成了。你有了一个可以正常编译的Buildroot环境,也跑通了第一个系统。后面的章节,我们会在这个基础上,一步步往里面加东西——加应用、加驱动、换板子、调性能。每一步我都会把当年踩过的坑、总结的经验告诉你。