|
嵌入式 Linux 入门:在 Allwinner H616 上跑 Buildroot

嵌入式 Linux 入门:在 Allwinner H616 上跑 Buildroot

搞嵌入式的朋友,迟早会走到这一步——从裸机/RTOS 跳到真正的 Linux 系统

你可能已经玩过了 STM32、ESP32,写过 FreeRTOS 多任务,觉得”嵌入式也就这样了”。但当你需要跑一个 Web 服务器、处理视频流、或者用 Python 写应用逻辑的时候,RTOS 就不够用了。这时候,嵌入式 Linux 才是正解。

今天我们就用一块 Allwinner H616 开发板(比如 Orange Pi 3 LTS 或类似板子),配合 Buildroot 这个神器,从零构建一个完整的嵌入式 Linux 系统。

为什么选 Allwinner H616?

全志 H616 是一颗性价比极高的 ARM SoC:

参数规格
CPU四核 ARM Cortex-A53 @ 1.5GHz
GPUMali G31 MP2
内存支持 DDR3/DDR4,最大 4GB
视频硬件解码 H.265/H.264,支持 4K@60fps
接口HDMI 2.0a、USB 3.0、千兆以太网、WiFi/BT(部分板载)
存储eMMC、SD 卡启动

关键优势

  • 便宜:开发板 100-200 元就能搞定
  • 社区支持好:mainline Linux 内核已经支持 H6/H616
  • 性能够用:四核 A53 跑 Linux 绰绰有余,还能做轻量级多媒体处理
  • 适合学习:比树莓派更”原始”,需要自己构建系统,学到的东西更多

为什么选 Buildroot?

嵌入式 Linux 系统构建方案主要有三个:

方案特点适合场景
Buildroot极简、快速、配置直观产品固件、专用设备
Yocto/OpenEmbedded功能强大、灵活但复杂大型商业产品
Debian/Ubuntu包管理完善、上手快原型开发、通用设备

Buildroot 的核心哲学:用最简单的方式,生成一个刚好够用的嵌入式 Linux 系统。

它的优势在于:

  1. 配置简单make menuconfig 一个界面搞定所有配置
  2. 构建快速:首次完整编译 20-40 分钟,增量编译几秒钟
  3. 产物精简:生成的 rootfs 可以小到 30MB 以内
  4. 可复现:一份配置生成完全一样的系统,适合量产

硬件清单

开始之前,你需要准备这些东西:

物品说明参考价格
Orange Pi 3 LTS 或 H616 开发板淘宝搜”Orange Pi 3 LTS”¥120-180
MicroSD 卡(16GB+)推荐 SanDisk Class 10¥25
5V/3A 电源Type-C 或 DC 口,看板子¥15
USB-TTL 串口线CH340 或 CP2102 芯片¥8
HDMI 线 + 显示器调试时看输出(可选)-
网线千兆以太网连接(可选)-
SD 卡读卡器电脑端烧录用¥10

串口是必须的! 嵌入式 Linux 调试 90% 靠串口,没有串口等于瞎子摸象。

搭建编译环境

1. 安装依赖

推荐用 Ubuntu 22.04 或 24.04(物理机或虚拟机都行)。安装编译所需的依赖:

sudo apt update
sudo apt install -y \
    build-essential gcc g++ make \
    libncurses5-dev libncursesw5-dev \
    wget curl git \
    unzip bc cpio \
    python3 python3-pip \
    file bzip2 xz-utils \
    rsync texinfo

2. 下载 Buildroot

# 下载最新稳定版(以 2026.05 为例)
wget https://buildroot.org/downloads/buildroot-2026.05.tar.gz
tar xf buildroot-2026.05.tar.gz
cd buildroot-2026.05

或者用 Git 获取最新代码:

git clone https://github.com/buildroot/buildroot.git
cd buildroot

3. 检查磁盘空间

Buildroot 编译需要 至少 10GB 磁盘空间,建议留 20GB 以上:

df -h .

配置 Buildroot

方法一:使用现成的 defconfig(推荐新手)

Buildroot 自带了很多开发板的默认配置。虽然没有直接的 orangepi_h616_defconfig,但我们可以基于通用的 aarch64 配置来改:

# 先看看有没有相关的配置
ls configs/ | grep -i "orange\|allwinner\|h6\|sun50i"

如果有类似的配置可以直接用:

make orangepi_3_defconfig  # 如果有的话

方法二:从头配置(推荐学习)

make qemu_aarch64_virt_defconfig  # 先用一个基础配置
make menuconfig

menuconfig 中,重点配置以下几项:

Target Architecture(目标架构)

Target Options  --->
    Target Architecture: AArch64 (little endian)
    Target Architecture Variant: cortex-a53

Toolchain(工具链)

Toolchain  --->
    Toolchain type: Buildroot toolchain
    C library: glibc
    Kernel Headers: Linux kernel headers (from the kernel we're building)
    GCC version: 13.x

Kernel(内核)

Kernel  --->
    [*] Linux Kernel
    Kernel version: Custom version (选 6.6 或更新的 LTS)
    Kernel configuration: sunxi defconfig
    (sun50i-h616) Device Tree Source file name

注意:H616 的 Device Tree 文件名可能是 sun50i-h616-orangepi-3-lts,具体看内核源码中 arch/arm64/boot/dts/allwinner/ 目录下有哪些。

Bootloader(引导加载程序)

Bootloaders  --->
    [*] U-Boot
    U-Boot version: Custom version (选最新)
    U-Boot configuration: orangepi_3_defconfig (或 orangepi_3_lts_defconfig)

Filesystem(文件系统)

Filesystem images  --->
    [*] ext4 root filesystem
    [*] tar the root filesystem

配置要点速查

一个典型的 H616 Buildroot 配置(.config 关键项):

# 目标平台
BR2_aarch64=y
BR2_cortex_a53=y

# 工具链
BR2_TOOLCHAIN_BUILDROOT_GLIBC=y

# 内核
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.6.32"
BR2_LINUX_KERNEL_USE_DEFCONFIG=y
BR2_LINUX_KERNEL_DEFCONFIG="sunxi"
BR2_LINUX_KERNEL_DTS_SUPPORT=y
BR2_LINUX_KERNEL_INTREE_DTS_NAME="allwinner/sun50i-h616-orangepi-3-lts"

# U-Boot
BR2_TARGET_UBOOT=y
BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y
BR2_TARGET_UBOOT_CUSTOM_VERSION=y
BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2026.04"
BR2_TARGET_UBOOT_BOARD_DEFCONFIG="orangepi_3_lts"
BR2_TARGET_UBOOT_NEEDS_DTC=y
BR2_TARGET_UBOOT_NEEDS_PYTHON3=y
BR2_TARGET_UBOOT_FORMAT_CUSTOM=y
BR2_TARGET_UBOOT_FORMAT_CUSTOM_NAME="u-boot-sunxi-with-spl.bin"

# 文件系统
BR2_TARGET_ROOTFS_EXT2=y
BR2_TARGET_ROOTFS_EXT2_4=y

开始编译

配置完成后,一条命令开始编译:

make -j$(nproc)

提示:Buildroot 从 2020 版本开始支持顶层并行编译,-j 参数可以放心用。

编译过程会依次完成:

  1. 下载源码包(约 5-10 分钟,取决于网络)
  2. 解压并打补丁
  3. 配置并编译交叉编译工具链
  4. 编译 Linux 内核
  5. 编译 U-Boot
  6. 生成 rootfs

首次编译大约需要 30-60 分钟(取决于 CPU 性能)。

编译产物

编译完成后,在 output/images/ 目录下会生成:

output/images/
├── bl31.bin              # ARM Trusted Firmware
├── Image                 # Linux 内核镜像
├── sun50i-h616-orangepi-3-lts.dtb  # 设备树
├── u-boot-sunxi-with-spl.bin       # U-Boot(含 SPL)
├── rootfs.ext4           # 根文件系统
└── sdcard.img            # 完整的 SD 卡镜像(如果有配置)

烧录到 SD 卡

方法一:使用 sdcard.img(最简单)

如果 Buildroot 配置了生成 sdcard.img,直接烧录即可:

# 查看 SD 卡设备名(小心别写错!)
lsblk

# 烧录(假设 SD 卡是 /dev/sdb)
sudo dd if=output/images/sdcard.img of=/dev/sdb bs=4M status=progress
sync

方法二:手动分区烧录

如果没有 sdcard.img,需要手动操作:

# 1. 分区(假设 SD 卡是 /dev/sdb)
sudo fdisk /dev/sdb
# 创建一个 Linux 分区(/dev/sdb1)

# 2. 格式化
sudo mkfs.ext4 /dev/sdb1

# 3. 挂载并写入
sudo mount /dev/sdb1 /mnt
sudo cp output/images/rootfs.ext4 /mnt/
# 或者解压 tar:
# sudo tar xf output/images/rootfs.tar -C /mnt/

# 4. 拷贝内核和 DTB
sudo mkdir -p /mnt/boot
sudo cp output/images/Image /mnt/boot/
sudo cp output/images/*.dtb /mnt/boot/

# 5. 写入 U-Boot(SPL 在 8KB 偏移处)
sudo dd if=output/images/u-boot-sunxi-with-spl.bin of=/dev/sdb bs=1024 seek=8

# 6. 卸载
sudo umount /mnt
sync

首次启动

1. 连接串口

# 接线:TX→RX, RX→TX, GND→GND
# 波特率:115200

# Linux/Mac:
screen /dev/ttyUSB0 115200

# Windows 用 PuTTY 或 MobaXterm

H616 开发板的串口引脚一般在板子边缘的排针上,具体看板子的原理图。Orange Pi 3 LTS 的 UART0 引脚:

引脚功能
Pin 6 (TX)串口发送
Pin 8 (RX)串口接收
Pin 10 (GND)地线

2. 插入 SD 卡,上电

你应该能在串口看到 U-Boot 启动信息:

U-Boot SPL 2026.04 (Jul 02 2026 - 04:00:00 +0800)
DRAM: 2048 MiB
Trying to boot from MMC1

U-Boot 2026.04 (Jul 02 2026 - 04:00:00 +0800) Allwinner Technology

CPU:   Allwinner H616 (SUN50I)
Model: OrangePi 3 LTS
DRAM:  2 GiB
...

然后是 Linux 内核启动日志,最后到达登录提示符:

Welcome to Buildroot
buildroot login: root
# 

恭喜!你的嵌入式 Linux 系统跑起来了!

3. 基础验证

# 查看系统信息
uname -a
# Linux buildroot 6.6.32 #1 SMP ... aarch64 GNU/Linux

# 查看 CPU 信息
cat /proc/cpuinfo

# 查看内存
free -h

# 查看磁盘
df -h

# 网络(如果板子有网口)
ifconfig eth0 up
udhcpc -i eth0
ping -c 3 8.8.8.8

添加自定义应用

Buildroot 最强大的地方在于可以轻松添加你需要的软件包。

方法一:通过 menuconfig 添加

make menuconfig

# 进入以下路径选择需要的包:
# Target packages  --->
#     [*] Networking applications  --->
#         [*] openssh
#     [*] Text editors and viewers  --->
#         [*] vim
#     [*] Interpreter languages and scripting  --->
#         [*] python3

然后重新编译:

make

方法二:添加自定义程序

创建一个简单的 C 程序:

mkdir -p package/hello-world

创建 package/hello-world/Config.in

config BR2_PACKAGE_HELLO_WORLD
    bool "hello-world"
    help
      A simple hello world program

创建 package/hello-world/hello-world.mk

HELLO_WORLD_VERSION = 1.0
HELLO_WORLD_SITE = $(TOPDIR)/../custom-packages/hello-world
HELLO_WORLD_SITE_METHOD = local

define HELLO_WORLD_BUILD_CMDS
    $(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(@D) all
endef

define HELLO_WORLD_INSTALL_TARGET_CMDS
    $(INSTALL) -D -m 0755 $(@D)/hello $(TARGET_DIR)/usr/bin/hello
endef

$(eval $(generic-package))

package/hello-world/ 目录下创建源码 hello.c

#include <stdio.h>

int main(void) {
    printf("Hello from Allwinner H616!\n");
    printf("Running embedded Linux with Buildroot.\n");
    return 0;
}

以及 Makefile

CC ?= gcc
CFLAGS ?= -Wall -O2

all: hello

hello: hello.c
	$(CC) $(CFLAGS) -o $@ $<

clean:
	rm -f hello

重新配置并编译:

make menuconfig
# Target packages  --->
#     Miscellaneous  --->
#         [*] hello-world

make

常见问题排查

问题 1:串口没有输出

排查步骤

  1. 检查 TX/RX 是否接反(交叉连接)
  2. 确认波特率是 115200
  3. 检查板子的 UART 引脚定义是否正确
  4. 用万用表量一下 TX 引脚是否有电平变化

问题 2:U-Boot 启动后找不到内核

=> 

卡在 U-Boot 命令行,说明内核加载失败。

解决方法

# 在 U-Boot 命令行手动指定启动参数
setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p1 rootwait
fatload mmc 0 0x40080000 boot/Image
fatload mmc 0 0x4fa00000 boot/sun50i-h616-orangepi-3-lts.dtb
booti 0x40080000 - 0x4fa00000

问题 3:内核 Panic - not syncing: VFS: Unable to mount root fs

原因:rootfs 分区找不到或格式不对。

解决

  • 检查 bootargs 中的 root= 参数是否与实际分区匹配
  • 确认 SD 卡分区格式正确(ext4)
  • 查看 U-Boot 的 boot.cmd / boot.scr 配置

问题 4:编译报错 “No rule to make target”

通常是 .config 配置有误。解决方法:

# 清理并重新配置
make clean
make menuconfig
make

问题 5:网络不通

# 检查网卡是否识别
ip link show

# 手动配置 IP
ifconfig eth0 192.168.1.100 netmask 255.255.255.0 up
route add default gw 192.168.1.1

# 或者用 DHCP
udhcpc -i eth0

如果 ip link 看不到 eth0,可能是内核没编译对应的网卡驱动。回到 menuconfig 检查:

Kernel  --->
    [*] Linux Kernel
    Kernel configuration: sunxi defconfig

sunxi defconfig 应该包含了 H616 的 GMAC 驱动,但如果你用了自定义内核配置,需要确认:

CONFIG_STMMAC_ETH=y
CONFIG_DWMAC_SUNXI=y

Buildroot 进阶技巧

1. 使用 overlay 目录

overlay 可以让你在生成的 rootfs 上叠加自定义文件,而不需要修改 Buildroot 源码:

# 在 menuconfig 中设置
# System configuration  --->
#     (/path/to/overlay) Root filesystem overlay directories

# 然后在 overlay 目录下创建跟 rootfs 一样的目录结构
overlay/
├── etc/
   └── hostname
├── root/
   └── .bashrc
└── usr/
    └── bin/
        └── my-script.sh

2. 使用 post-build 脚本

在编译完成后自动执行脚本:

# System configuration  --->
#     (board/h616/post-build.sh) Run a post-build script

# board/h616/post-build.sh
#!/bin/bash
TARGET_DIR=$1
echo "Customizing rootfs..."
echo "h616-board" > ${TARGET_DIR}/etc/hostname
# 添加自定义配置等

3. 使用 br2-external

如果你有多个产品共用同一个 Buildroot 版本,用 br2-external 机制把板级配置分离出来:

# 创建外部配置目录
mkdir -p br2-external-h616/{configs,board/h616,package}

# 创建 desc 文件
cat > br2-external-h616/external.desc <<EOF
name: H616
desc: Allwinner H616 board support
EOF

# 使用时
make BR2_EXTERNAL=/path/to/br2-external-h616 menuconfig

4. 加速编译

# 使用 ccache 缓存编译结果
# Toolchain  --->
#     [*] Enable compiler cache (ccache)

# 或者设置 DL_DIR 共享下载目录
# 在 .config 中:
BR2_DL_DIR="/home/user/buildroot-dl"

从 Buildroot 到产品

Buildroot 构建的系统适合做专用设备,比如:

  • 智能网关:跑 MQTT 客户端 + 协议转换
  • 数字标牌:HDMI 输出 + 轻量 Web 浏览器
  • 工业控制器:Modbus 通信 + 本地 HMI
  • 边缘 AI 盒子:摄像头接入 + 推理引擎

产品化注意事项

  1. 安全加固:禁用 root 登录、启用 SSH 密钥认证
  2. 看门狗:配置硬件看门狗防止死机
  3. OTA 更新:使用 A/B 分区方案实现远程升级
  4. 日志管理:用 tmpfs 存放日志,保护 SD 卡寿命
  5. 电源管理:配置 cpufreq 降低功耗

总结

今天我们完成了从零开始的嵌入式 Linux 之旅:

  1. ✅ 了解了 Allwinner H616 和 Buildroot 的基本概念
  2. ✅ 搭建了交叉编译环境
  3. ✅ 配置并编译了完整的 Linux 系统
  4. ✅ 烧录到 SD 卡并成功启动
  5. ✅ 学会了添加自定义应用和常见问题排查

下一步建议

  • 尝试给系统添加 Python 支持,写一些 IoT 应用
  • 研究 Device Tree,了解硬件是如何被描述的
  • 学习 U-Boot 的环境变量和启动流程
  • 尝试用 Buildroot 的 legal-info 功能生成软件许可证报告

嵌入式 Linux 的世界很大,Buildroot 是你最好的入门工具。它足够简单让你快速上手,又足够灵活让你做到产品级。

有什么疑问欢迎留言讨论,我们下篇文章见!