1. 课程导论与开发环境搭建

各位同学,欢迎来到这门实战课。我是你们的老朋友,一个在嵌入式 Linux 领域摸爬滚打了十几年的工程师。今天咱们先不急着敲代码,把地基打牢了,后面盖楼才稳当。

这一章,我带你走一遍 ARM 架构的轮廓、嵌入式 Linux 系统的骨架,再把交叉编译工具链装好,最后把开发板连上电脑。嗯,都是些“磨刀”的活儿,但刀磨快了,砍柴才不费劲。

1.1 ARM 架构概述

ARM 处理器,说白了就是一颗低功耗、高性能的 RISC 芯片。你手机里、路由器里、甚至你家的智能电视里,都有它的影子。我最早接触 ARM 是在 2008 年,那时候还是 ARM9 和 ARM11 的天下,跑个 200MHz 就觉得很快了。现在呢?Cortex-A76 动不动就 2GHz 以上,时代变了。

ARM 架构有几个关键点,你得先记住:

  • RISC 设计哲学:指令精简,每条指令干一件事,执行效率高。
  • 低功耗:这是 ARM 的看家本领,特别适合嵌入式设备。
  • 丰富的生态系统:从 MCU 到服务器芯片,ARM 几乎覆盖了所有场景。

ARM 处理器家族主要分三大类,我整理了一张表,方便你对比:

系列 典型型号 应用场景 特点
Cortex-A A7, A53, A72, A76 应用处理器(Linux、Android) 高性能,支持 MMU,跑操作系统
Cortex-R R4, R5, R52 实时控制(汽车、工业) 低延迟,硬实时,无 MMU
Cortex-M M0, M3, M4, M7 微控制器(IoT、传感器) 超低功耗,裸机或 RTOS

咱们这门课主要聚焦在 Cortex-A 系列上。为什么?因为只有 A 系列才能跑完整的 Linux 内核,才能做系统裁剪和移植。你想想看,一个 Cortex-M3 跑个 FreeRTOS 还行,但要跑完整 Linux 内核,内存和 MMU 都不够用。

我的经验: 选型时别只看主频。Cortex-A7 虽然主频不高,但功耗极低,适合电池供电的设备。Cortex-A72 性能强,但发热也大,需要散热设计。我在一个工业平板项目里就吃过亏,选了 A72 没加散热片,结果跑 10 分钟就过热降频了。

1.2 嵌入式 Linux 系统组成

一个完整的嵌入式 Linux 系统,由四层组成。我画了一张图,帮你理清它们的关系:

嵌入式 Linux 系统分层结构 应用层 用户程序、Qt/GUI、网络服务、业务逻辑 系统库层 C 库(glibc/musl)、OpenSSL、SQLite、libpthread 内核层 Linux 内核、设备驱动、文件系统、网络协议栈 Bootloader + 硬件层 U-Boot、ATF、设备树、ARM SoC、外设控制器 从硬件到应用,逐层抽象

这四层,每一层都缺一不可。我简单解释一下:

  1. Bootloader + 硬件层:上电后第一个跑的程序,负责初始化硬件、加载内核。U-Boot 是主流选择。
  2. 内核层:Linux 内核,管理进程、内存、设备、网络。咱们这门课的核心就是裁剪它。
  3. 系统库层:C 库、加密库、数据库等。glibc 功能全但体积大,musl 轻量但兼容性稍差。
  4. 应用层:你写的业务代码、Qt 界面、Web 服务器等。
核心观点: 系统裁剪,本质上就是在这四层里做减法。去掉不需要的驱动、库、应用,把系统体积从几百 MB 压缩到几十 MB,甚至几 MB。

1.3 交叉编译工具链安装与配置

交叉编译,说白了就是在你的 PC(x86 架构)上编译出能在 ARM 开发板上运行的代码。为什么不能直接在开发板上编译?因为开发板的 CPU 性能弱、内存小、存储也小,编译个 Linux 内核可能要几个小时。而 PC 上几分钟就搞定了。

我推荐使用 Linaro GCC 工具链,稳定且社区活跃。安装步骤很简单:

# 下载 ARM64 交叉编译工具链(以 aarch64-linux-gnu 为例)
wget https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz

# 解压到 /opt 目录
sudo tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz -C /opt/

# 添加环境变量
echo 'export PATH=$PATH:/opt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin' >> ~/.bashrc
source ~/.bashrc

# 验证安装
aarch64-linux-gnu-gcc --version

验证成功后,你会看到类似这样的输出:

aarch64-linux-gnu-gcc (Linaro GCC 7.5-2019.12) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
我曾经踩过的坑: 工具链版本必须与内核版本匹配。比如 Linux 4.19 内核,用 GCC 7.x 没问题。但如果你用 GCC 4.x 编译 5.x 内核,可能会遇到内联汇编语法不兼容的问题。我有个项目就因为这个折腾了两天,最后换了工具链版本才解决。

另外,如果你用的是 ARM32 架构(比如 Cortex-A7),工具链前缀是 arm-linux-gnueabihf。ARM64 则是 aarch64-linux-gnu。别搞混了。

1.4 开发板选型与连接

开发板怎么选?我个人的建议是:看你的目标场景。如果你做工业控制,选 STM32MP1 或 i.MX6ULL;如果你做多媒体或 AI 边缘计算,选 RK3588 或树莓派 4B;如果你只是想学习,选 QEMU 模拟器也行,零成本。

下面是我常用的几款开发板对比:

开发板 SoC 架构 内存 适用场景
树莓派 4B BCM2711 Cortex-A72 1-8GB 学习、原型验证
STM32MP157 STM32MP157 Cortex-A7 + M4 512MB-1GB 工业控制、HMI
RK3588 RK3588 Cortex-A76 + A55 4-32GB AI、边缘计算、多媒体
QEMU virt 模拟 模拟 Cortex-A53 动态分配 学习、无硬件环境

连接开发板,通常需要三根线:

  • USB 串口线:用于串口终端,查看内核启动日志。波特率通常是 115200。
  • USB 网卡或以太网线:用于网络通信,比如 NFS 挂载根文件系统。
  • 电源线:5V/2A 或 5V/3A,别用手机充电头糊弄,电流不够会导致开发板重启。

连接完成后,用串口工具(如 minicom、putty)打开串口,上电后你应该能看到 U-Boot 的启动信息。如果看不到,检查一下串口线是否插对、波特率是否设置正确。

我的习惯: 我会在 PC 上开两个终端。一个用串口看内核日志,另一个用 SSH 登录开发板操作。这样调试起来效率高很多。