4. 基于Buildroot的汽车Linux最小系统构建

说实话,Buildroot 这东西,我第一次接触的时候觉得它挺「土」的。没有 Yocto 那种复杂的层叠结构,也没有 OpenEmbedded 的庞大生态。但干得久了你会发现,做汽车嵌入式 Linux,很多时候要的不是大而全,而是小而精。Buildroot 恰恰擅长这个。

这一章,我们就拿它来给 QEMU virt ARM64 平台搭一个最小系统。顺便把汽车上常用的 libsocketcan 和 GStreamer 塞进去。嗯,这里要注意,「最小」不代表「简陋」,而是指只包含你真正需要的东西。

4.1 为什么选 Buildroot?

我个人习惯把构建系统分成两类:

  • Yocto:适合大团队、多平台、需要长期维护的产品线。功能强,但学习曲线陡,构建一次够喝杯咖啡再睡一觉。
  • Buildroot:适合原型验证、单板定制、快速迭代。配置简单,编译快,特别适合我们做 QEMU 仿真——你总不想每次改个配置都等半小时吧?

我在项目中遇到过好几次这样的情况:用 Yocto 搭环境花了两周,最后发现客户要的只是 CAN 通信加个视频流。Buildroot 一下午搞定。所以,工具选对了,事半功倍。

核心思路:Buildroot 通过 make menuconfig 选择目标架构、内核版本、库和工具链,然后自动下载、编译、打包,最终生成内核镜像 Image 和根文件系统 rootfs.cpio。

4.2 配置 Buildroot 针对 QEMU virt ARM64

先下载 Buildroot。我建议用长期支持版本,比如 2023.02.x 或 2024.02.x,稳定一些。

wget https://buildroot.org/downloads/buildroot-2024.02.tar.gz
tar xf buildroot-2024.02.tar.gz
cd buildroot-2024.02

然后开始配置。运行:

make qemu_aarch64_virt_defconfig

这个默认配置已经帮我们选好了 ARM64 架构、QEMU virt 机器类型、内核版本和基础文件系统。但离「汽车最小系统」还差几步。

接着执行:

make menuconfig

这里我列一下必须改的几项:

配置项 路径 推荐值 说明
Target Architecture Target options AArch64 (little endian) ARM64 架构
Target Binary Format Target options ELF 标准格式
Kernel binary format Kernel Image QEMU 需要 raw 镜像
Root filesystem Filesystem images cpio the root filesystem initramfs 方式启动
Enable MMU Target options Yes 必须开启
小技巧:如果你希望根文件系统是 ext4 格式挂载到 virtio 磁盘上,也可以选 ext4。但 initramfs 方式启动更快,适合仿真调试。

4.3 集成汽车常用库

汽车嵌入式 Linux 里,有两个库几乎绕不开:libsocketcan 和 GStreamer。前者是 CAN 总线通信的瑞士军刀,后者是多媒体处理的标配。

4.3.1 添加 libsocketcan

在 make menuconfig 中搜索 libsocketcan:

/libsocketcan

然后勾选:

Target packages → Networking → libsocketcan

这个库提供了 socketcan 接口的封装,包括打开/关闭 CAN 设备、设置波特率、发送/接收帧等。我当年做 T-Box 项目时,就是靠它和 can-utils 配合,在三天内调通了 CAN 收发。

顺便把 can-utils 也加上:

Target packages → Networking → can-utils

这样你就能在目标系统里用 candump、cansend 等命令了。

4.3.2 添加 GStreamer

GStreamer 在汽车里主要用来处理摄像头视频流、音频播放、RTSP 流媒体等。配置路径:

Target packages → Audio and video applications → gstreamer1

建议勾选以下插件包:

  • gst1-plugins-base:基础元素,如 videotestsrc, audiotestsrc
  • gst1-plugins-good:常用编解码器,如 jpeg, png, v4l2
  • gst1-plugins-bad:部分实验性插件,如 rtsp
  • gst1-libav:FFmpeg 封装,支持 H.264/H.265
注意:GStreamer 依赖较多,勾选后 Buildroot 会自动处理依赖。但如果你发现编译报错,多半是缺了 glib 或 libffi,手动勾上就行。

4.4 生成根文件系统与内核镜像

配置完成后,执行编译:

make -j$(nproc)

第一次编译会下载所有源码包,时间取决于网络。我建议用代理或提前下载好源码包放到 dl/ 目录下。

编译成功后,在 output/images/ 下会生成:

文件 说明
Image ARM64 内核镜像,QEMU 直接使用
rootfs.cpio 根文件系统,initramfs 格式
qemu_aarch64_virt.dtb 设备树文件,描述硬件拓扑
start-qemu.sh 自动生成的 QEMU 启动脚本

你可以直接用 start-qemu.sh 启动,也可以手动执行:

qemu-system-aarch64 \
  -M virt \
  -cpu cortex-a72 \
  -smp 2 \
  -m 1G \
  -kernel output/images/Image \
  -initrd output/images/rootfs.cpio \
  -append "console=ttyAMA0 root=/dev/ram0" \
  -nographic

启动后,你会看到一个精简的 Linux shell。输入 candump --help 和 gst-launch-1.0 --help 验证库是否安装成功。

4.5 整体构建流程

下面这张图总结了从配置到启动的完整流程:

Buildroot 汽车最小系统构建流程 下载 Buildroot make defconfig menuconfig 定制 关键配置项 • 架构: AArch64 (little endian) • 内核格式: Image • 文件系统: cpio (initramfs) • 库: libsocketcan + GStreamer make -j$(nproc) 生成 output/images/ 产出物 • Image • rootfs.cpio • .dtb QEMU 启动验证 验证命令 candump --help gst-launch-1.0 --help

4.6 避坑指南

我曾经在配置 GStreamer 时踩过一个坑:默认配置下 GStreamer 的插件包只编译核心库,不包含实际元素。结果启动后 gst-launch-1.0 videotestsrc 报错说找不到元素。后来发现需要在 menuconfig 里手动勾选 gst1-plugins-base 下的 videotestsrc 子选项。

另外,libsocketcan 依赖内核的 CAN 子系统。如果你启动 QEMU 后执行 ip link set can0 up 报错,说明内核没开启 CAN 支持。需要在 make linux-menuconfig 里勾选:

Networking support → CAN bus subsystem support

以及对应的驱动(比如 Virtual CAN driver)。

我的习惯:每次改完配置后,先 make clean 再 make,避免旧文件干扰。虽然慢一点,但能省去排查诡异问题的时间。