第2章:源码获取与目录结构
好,咱们正式开始动手。这一章我带你看看Buildroot的源码怎么拿,以及拿到手后那一堆文件夹到底是干嘛的。
说实话,我第一次接触Buildroot时,也被它的目录结构吓了一跳。心想:这玩意儿怎么这么多文件夹?后来用熟了才发现,每个目录都有它存在的道理。
2.1 从Git仓库获取Buildroot
获取源码的方式很简单。我个人习惯直接用git clone,这样方便后续切换版本。
git clone https://git.buildroot.net/buildroot
cd buildroot
嗯,这里要注意:你拿到的默认是master分支,也就是开发版。我建议你切到一个稳定版本,比如:
git checkout 2024.02.x
为什么?我在项目中吃过亏。有一次用master分支,结果某个包突然更新了API,整个编译链全崩了。从那以后,我都是先看发布页,选一个LTS版本。
2.2 顶层目录结构解析
克隆完后,你执行 ls -l 会看到一堆文件和文件夹。别慌,我带你一个个看。
| 目录/文件 | 作用 |
|---|---|
| arch/ | 架构相关的配置,比如ARM、x86、RISC-V |
| board/ | 板级支持包,存放具体开发板的配置和脚本 |
| boot/ | 引导加载程序,比如U-Boot、Barebox |
| configs/ | 默认配置文件,类似 defconfig |
| docs/ | 文档,包括手册和开发指南 |
| fs/ | 文件系统构建逻辑,比如ext4、squashfs |
| linux/ | Linux内核的构建配置 |
| package/ | 所有软件包的构建脚本,这是核心 |
| support/ | 辅助工具和脚本,比如依赖检查 |
| toolchain/ | 工具链相关,包括gcc、binutils、glibc |
| utils/ | 一些实用工具,比如scanpypi |
| Makefile | 顶层Makefile,整个构建的入口 |
| Config.in | 顶层Kconfig配置菜单 |
你看,其实结构很清晰。顶层就这几个核心目录。我刚开始时总记不住,后来画了个图:配置入口在Config.in,构建入口在Makefile,具体实现在各个子目录。
2.3 board/ 目录:板级支持
这个目录存放的是具体开发板的配置。比如树莓派、BeagleBone、QEMU模拟器等等。
board/
├── raspberrypi/
│ ├── config.txt
│ ├── cmdline.txt
│ └── post-build.sh
├── beaglebone/
│ ├── uEnv.txt
│ └── post-image.sh
└── qemu/
├── aarch64-virt/
└── x86_64/
每个板子目录下,通常有:
- 配置文件:比如树莓派的config.txt
- 后处理脚本:post-build.sh、post-image.sh
- 设备树:dts文件
我记得有一次做项目,客户要求修改启动参数。我直接在board/raspberrypi/cmdline.txt里改,然后重新编译,搞定。方便得很。
2.4 configs/ 目录:默认配置
这个目录存放的是各种开发板的默认配置。说白了,就是 make menuconfig 后的保存结果。
configs/
├── raspberrypi4_64_defconfig
├── beaglebone_defconfig
├── qemu_aarch64_virt_defconfig
└── stm32mp157_dk_defconfig
使用方式很简单:
make raspberrypi4_64_defconfig
这条命令会把配置加载到 .config 文件里。然后你就可以 make 了。
嗯,这里有个坑:不要直接修改 .config 文件。我刚开始时图省事,手动改了 .config,结果下次 make 时被覆盖了。正确做法是:修改 defconfig 文件,或者用 make savedefconfig 保存。
2.5 package/ 目录:软件包管理
这是Buildroot的核心目录。每个软件包都有一个子目录,里面包含:
- Config.in:包的Kconfig配置选项
- *.mk:Makefile构建规则
- *.hash:源码校验文件
- patches/:补丁文件(可选)
举个例子,看看 busybox 包:
package/busybox/
├── Config.in
├── busybox.mk
├── busybox.hash
├── S01busybox
└── patches/
└── 0001-fix-something.patch
我个人觉得,理解 package/ 目录是掌握Buildroot的关键。你想想看,整个嵌入式系统就是由这些包堆起来的。内核是一个包,busybox是一个包,openssh也是一个包。
如果你想添加一个新包,比如 libgpiod,就在 package/ 下新建一个目录,写 Config.in 和 .mk 文件。具体怎么写,我们后面章节会详细讲。
2.6 toolchain/ 目录:工具链
工具链是编译器的集合。Buildroot支持两种方式:
- 内部工具链:Buildroot自己编译gcc、binutils、glibc
- 外部工具链:使用预编译的工具链,比如Linaro、ARM官方
toolchain/ 目录下就是这些逻辑:
toolchain/
├── toolchain-buildroot/
│ ├── Config.in
│ └── toolchain-buildroot.mk
├── toolchain-external/
│ ├── Config.in
│ └── toolchain-external.mk
└── helpers.mk
我建议新手先用外部工具链。为什么?因为编译工具链太慢了。我第一次编译内部工具链,等了整整两个小时。后来改用Linaro的预编译版,10分钟搞定。
2.7 其他重要目录
还有几个目录,虽然不常用,但关键时刻能救命:
- boot/:引导加载程序。如果你要换U-Boot版本,来这里改。
- linux/:内核配置。这里只放内核的构建逻辑,具体补丁在 board/ 里。
- fs/:文件系统类型。比如你要用squashfs还是ext4,在这里配置。
- support/:辅助脚本。比如依赖检查、下载工具。
我记得有一次,客户要求用squashfs文件系统。我直接去 fs/squashfs/ 下看配置,发现有个压缩选项。调成lz4后,启动速度快了30%。
2.8 本章小结
好了,这一章我们看了Buildroot的目录结构。说白了,记住几个关键点:
- configs/ 是配置入口,选板子用
- board/ 是板级定制,改启动参数用
- package/ 是软件包,加功能用
- toolchain/ 是编译器,选工具链用
下一章,我们开始实战:用menuconfig配置一个最小系统。到时候你会看到,这些目录是怎么协同工作的。
嗯,如果你现在就想动手,可以试试:make qemu_x86_64_defconfig && make。等编译完,用 qemu-system-x86_64 -kernel output/images/bzImage -hda output/images/rootfs.ext2 启动看看。相信我,看到内核跑起来的那一刻,你会觉得一切都值了。