2、环境搭建:Ubuntu环境准备、依赖包安装、获取Buildroot源码、目录结构解析

说实话,做嵌入式Linux开发,环境搭建这一步看着简单,但坑是真不少。我见过太多新手卡在依赖包安装上,一编译就报错,心态直接崩了。今天咱们就把这一步走稳,把地基打扎实。

2.1 Ubuntu环境准备

我个人习惯用Ubuntu 20.04 LTS或22.04 LTS。为什么?因为Buildroot的官方CI测试主要跑在这两个版本上,兼容性最好。你非要用Debian或者Deepin也不是不行,但遇到奇怪的问题时,社区能给你的帮助会少很多。

我的建议: 如果你手头没有Ubuntu,用虚拟机装一个。分配4核CPU、8GB内存、60GB磁盘空间,够用了。别用WSL1,文件系统性能太差,编译会慢到让你怀疑人生。

系统装好后,第一件事就是换源。国内用户不换源,apt下载速度会让你崩溃。我一般用清华源或者阿里云源,稳得很。

# 备份原源
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

# 替换为清华源(Ubuntu 22.04为例)
sudo sed -i 's/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list
sudo sed -i 's/security.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list

# 更新
sudo apt update && sudo apt upgrade -y

2.2 依赖包安装

Buildroot对宿主机的依赖说多不多,说少不少。少了任何一个,编译到一半就报错,那才叫折磨。我曾经因为没装rsync,排查了整整两个小时才找到原因。

下面这个列表是我反复验证过的,缺一不可:

类别 包名 用途说明
编译工具链 build-essential, gcc, g++ C/C++编译器,宿主机的编译基础
版本控制 git, wget, curl 下载源码包,拉取Buildroot仓库
文件系统工具 rsync, cpio, unzip, tar 打包、解压、同步文件
库文件 libncurses5-dev, libssl-dev menuconfig界面依赖、HTTPS下载支持
文件系统生成 genext2fs, mtd-utils 生成ext2/3/4、jffs2等镜像
避坑指南: 我曾经在Ubuntu 22.04上漏装了libelf-dev,结果编译Linux内核时报Cannot use CONFIG_DEBUG_INFO错误。所以建议你直接执行下面这条命令,一次性装完所有依赖:
sudo apt install -y build-essential gcc g++ git wget curl rsync cpio \
  unzip tar libncurses5-dev libssl-dev genext2fs mtd-utils \
  libelf-dev bc bison flex

嗯,这里多说一句。bc和bison、flex这三个包,很多人觉得用不上。但如果你要编译某些特定的内核模块或者U-Boot,缺了它们就是不行。装了就图个安心。

2.3 获取Buildroot源码

获取源码有两种方式,我分别说说它们的适用场景。

方式一:从Git仓库克隆(推荐)

这种方式适合你要长期跟踪最新版本,或者需要自己打补丁做二次开发。

git clone https://git.busybox.net/buildroot
cd buildroot
git checkout 2024.02.x   # 切换到稳定分支

我个人习惯用2024.02.x这个长期支持分支。为什么?因为LTS分支的bug修复周期长,社区维护积极,遇到问题容易找到解决方案。

方式二:下载发布版压缩包

如果你只是临时用一次,或者公司网络对Git协议有限制,直接下载tar包更省事。

wget https://buildroot.org/downloads/buildroot-2024.02.tar.gz
tar -xzf buildroot-2024.02.tar.gz
cd buildroot-2024.02
小技巧: 下载前先去Buildroot官网看一眼,确认你想要的版本还在维护。别下了个EOL的版本,后面想升级都麻烦。

2.4 目录结构解析

拿到源码后,别急着编译。先花十分钟把目录结构搞清楚,后面你找配置、改代码会快很多。我刚开始学的时候,就是一头扎进make menuconfig,结果连.config在哪都不知道。

下面这张图是我自己整理的Buildroot核心目录结构,你看一眼就能明白个大概:

Buildroot 核心目录结构 buildroot/ arch/ board/ configs/ package/ fs/ linux/ boot/ toolchain/ system/ support/ output/ dl/ 说明: • configs/ — 存放各开发板的默认配置文件(如 raspberrypi4_defconfig) • package/ — 所有软件包的构建脚本,按包名分目录 • output/ — 编译产物目录,包括 images/(镜像)、build/(编译中间文件) • dl/ — 下载的源码包缓存目录,避免重复下载

下面我把几个关键目录单独拎出来讲一下,这些都是你后面天天要打交道的。

configs/ — 板级配置的入口

这个目录里放的是各个开发板的默认配置。比如你要给树莓派4做系统,直接执行:

make raspberrypi4_64_defconfig

Buildroot就会自动加载configs/raspberrypi4_64_defconfig这个文件。说白了,这就是一个快速启动的模板。

package/ — 软件包的核心

每个软件包在这里都有一个子目录。比如你想看BusyBox是怎么编译的,就去package/busybox/下面看。里面通常包含:

  • busybox.mk — 编译规则,定义下载地址、依赖、配置选项
  • busybox.hash — 源码包的哈希校验值
  • Config.in — 菜单配置项,决定这个包在menuconfig里怎么显示

output/ — 编译成果的集散地

你执行make之后,所有生成的东西都在这里。我重点说几个子目录:

子目录 内容 使用场景
output/images/ 最终生成的镜像文件(zImage、rootfs.ext4等) 烧录到开发板
output/build/ 每个软件包的编译中间文件 调试编译错误、查看源码
output/target/ 根文件系统的目录结构 检查文件系统内容、手动修改
output/host/ 宿主机工具链和交叉编译工具 用于外部交叉编译

重点提醒: 如果你改了某个包的配置,想重新编译,记得先执行make <package>-dirclean清除该包的编译目录,再make。不然Buildroot会认为包已经编译过了,不会重新构建。我刚开始就吃过这个亏,改了配置却看不到效果,折腾了半天才发现是缓存没清。

dl/ — 源码包缓存

Buildroot第一次编译时会从网上下载所有依赖的源码包,都放在dl/目录下。第二次编译时就直接用缓存,不用再下载了。这个目录你可以备份起来,下次换个机器编译,直接把dl/拷过去,能省大量时间。

2.5 验证环境是否就绪

环境搭好没,跑一下就知道。执行下面这条命令,如果能正常弹出配置菜单,说明环境没问题:

make raspberrypi4_64_defconfig
make menuconfig

如果menuconfig界面出来了,恭喜你,环境搭建成功。如果报错,多半是缺了libncurses5-dev或者bc,回去检查一下依赖包列表。

个人经验: 我第一次搭环境时,menuconfig能打开,但一编译就报rsync找不到。后来养成习惯,每次装完依赖都跑一遍make raspberrypi4_64_defconfig && make -j4,让它编译几分钟。如果前几分钟没报错,基本就稳了。