3、配置系统入门:make menuconfig详解、Target options配置、Build options配置、Toolchain配置
好,咱们进入正题。上一章我们把Buildroot跑起来了,生成了第一个镜像。但说实话,那个镜像就是个「毛坯房」——能开机,但啥也没有。这一章,我们来搞「精装修」。
配置系统,说白了就是Buildroot的灵魂。你想想看,一个嵌入式系统要跑在什么CPU上?文件系统用哪种?编译器用哪个版本?这些全得靠配置来定。我个人习惯,拿到一个新板子,第一件事就是跑一遍 make menuconfig,把底子搭好。
3.1 make menuconfig——你的配置主战场
先敲命令:
$ cd buildroot
$ make menuconfig
你会看到一个蓝底白字的界面,有点像Linux内核的配置菜单。嗯,其实它就是基于内核的Kconfig体系做的。界面分三块:左边是菜单项,右边是帮助信息,底部是操作提示。
操作很简单:
- 上下键:移动光标
- 回车:进入子菜单
- 空格或Y:选中(显示为
*) - N:取消选中(显示为
) - M:编译为模块(显示为
M,仅内核模块有效) - ? 或 H:查看帮助
- /:搜索关键字
/ 输入关键词,回车就能定位。我在项目中经常用这个功能快速找到配置项,比一层层翻菜单快多了。
配置完成后,按 → 键移动到 <Exit>,一路退出,最后会问你是否保存。选 Yes,配置会写入 .config 文件。
make clean 再重新编译。我曾经偷懒没clean,结果新配置没生效,排查了半天才发现是缓存搞的鬼。
3.2 Target options——给系统定个「人设」
进入 Target options,这里配置的是目标硬件的基本信息。说白了,就是告诉Buildroot:「我的板子长什么样」。
主要配置项:
| 配置项 | 说明 | 常见选择 |
|---|---|---|
| Target Architecture | 目标CPU架构 | ARM、ARM64、x86、MIPS等 |
| Target Architecture Variant | CPU变体 | cortex-a7、cortex-a53、i686等 |
| Target ABI | 应用程序二进制接口 | EABI、EABIhf(硬浮点) |
| Floating point strategy | 浮点运算策略 | VFPv3、VFPv4、NEON等 |
| Target Binary Format | 二进制格式 | ELF(几乎都是这个) |
举个例子。我在做全志V3s芯片的项目时,配置是这样的:
Target Architecture: ARM (little endian)
Target Architecture Variant: cortex-a7
Target ABI: EABIhf
Floating point strategy: VFPv4-D16
Target Binary Format: ELF
为什么选 EABIhf?因为V3s支持硬件浮点,用硬浮点ABI性能更好。如果你选错了,比如选了软浮点,程序跑起来会慢不少,尤其是做音视频处理的时候,差距很明显。
3.3 Build options——编译过程的「调度室」
回到主菜单,进入 Build options。这里控制的是编译过程本身的行为,不是目标系统的功能。
几个关键配置:
- Download dir:源码包下载目录。默认是
dl/,我建议保持默认,方便管理。 - Host dir:主机工具安装目录。默认
output/host,一般不用改。 - Enable compiler cache:启用编译器缓存。强烈建议开启!第二次编译能快很多。
- Number of jobs to run simultaneously:并行编译线程数。一般设为你CPU核心数的1.5到2倍。比如4核CPU,设
6或8。 - Build packages with debugging symbols:是否带调试符号。开发阶段建议开启,发布时关掉以减小体积。
还有一个容易被忽略的选项:Root FS skeleton customization。这里可以指定你自定义的文件系统骨架。比如你想在根文件系统里预置一些脚本或配置文件,可以在这里指定路径。
3.4 Toolchain——编译器的「选型大会」
Toolchain配置,说白了就是选编译器。这是整个系统的基础,因为所有代码都要靠它来编译。
Buildroot提供两种方式:
- Buildroot internal toolchain:Buildroot自己编译工具链。推荐新手使用,省心。
- External toolchain:使用外部预编译的工具链。比如Linaro、ARM官方提供的工具链。
进入 Toolchain 菜单,主要配置项:
| 配置项 | 说明 | 建议 |
|---|---|---|
| Toolchain type | 工具链类型 | Buildroot internal(新手)或 External(有特殊需求) |
| Kernel headers | 内核头文件版本 | 尽量和你编译的内核版本一致 |
| C library | C库选择 | glibc(功能全)、uClibc-ng(体积小)、musl(安全) |
| GCC compiler version | GCC版本 | 选较新的稳定版,比如gcc 12.x或13.x |
| Enable C++ support | 是否支持C++ | 如果应用用C++写的,必须开启 |
关于C库的选择,我多说两句:
- glibc:功能最全,兼容性最好。但体积大,适合存储空间充裕的设备。
- uClibc-ng:体积小,适合嵌入式。但有些软件可能不兼容。
- musl:安全性好,静态链接方便。我在做IoT设备时喜欢用musl,生成的二进制文件小,而且安全漏洞少。
version magic mismatch 错误。折腾了一天才发现是头文件版本和内核版本差了三个小版本。所以,内核头文件版本一定要和你的内核源码版本严格一致。
如果你选择 External toolchain,还需要指定工具链的路径和前缀。比如Linaro的工具链,前缀通常是 arm-linux-gnueabihf-。路径要指向工具链的安装目录。
Toolchain path: /opt/linaro/gcc-arm-12.3-x86_64-arm-linux-gnueabihf
Toolchain prefix: arm-linux-gnueabihf
External toolchain kernel headers: 6.1.x
配置完这些,基本就完成了系统的「骨架搭建」。下一章我们会深入 System configuration 和 Kernel 配置,把系统的血肉填上。
嗯,这一章内容不少,但都是基础中的基础。你可以在自己的板子上动手试试,把Target options和Toolchain配好,然后编译一次看看。遇到问题很正常,多看看 output/build 目录下的日志,慢慢就熟悉了。