第1章 嵌入式 Linux 开发全景图

本章目标

  • 建立嵌入式 Linux 的整体认知,理解 Linux 在嵌入式系统中的角色
  • 区分 MCU、MPU、SoC、SBC 等概念,理解单片机开发与嵌入式 Linux 开发的差异
  • 掌握嵌入式 Linux 软件架构的四层结构:Bootloader、Kernel、RootFS、Application
  • 了解工业控制、消费电子、AIoT 选择 Linux 的原因
  • 明确嵌入式 Linux 工程师的能力模型与学习路径

知识导图

1
2
3
4
5
6
7
8
9
10
嵌入式系统
├── 定义与分类(MCU / MPU / SoC / SBC)
├── 软件架构
│ ├── Bootloader(上电→引导)
│ ├── Kernel(硬件抽象、调度、驱动)
│ ├── RootFS(根文件系统、用户空间基础)
│ └── Application(业务应用)
├── 与单片机开发的差异
├── 典型应用领域(工业、消费、AIoT)
└── 能力模型与学习路径

背景原理

1. 嵌入式系统的定义与分类

嵌入式系统是指以应用为中心、以计算机技术为基础、软硬件可裁剪,适用于对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。与通用 PC 不同,嵌入式系统通常“看不见计算机”,却无处不在:手机、路由器、车载中控、工业 PLC、智能家居、摄像头等。

从处理器形态上,常分为以下几类:

类型 全称 典型特点 常见用途
MCU Microcontroller Unit 单芯片集成 CPU、RAM、Flash、外设;无 MMU;跑 RTOS 或裸机 小家电、电机控制、传感器节点
MPU Microprocessor Unit 以 CPU 为核心,外挂 DDR、Flash;有 MMU;可跑 Linux 工控、网关、复杂人机界面
SoC System on Chip 在单芯片内集成 CPU、GPU、NPU、编解码、各种接口 手机、平板、开发板、AI 盒子
SBC Single Board Computer 以 SoC 为核心的完整板级产品,可直接运行完整 OS 树莓派、泰山派、各类开发板

RK3566 属于 SoC:在一块芯片内集成了 ARM Cortex-A55 CPU、Mali-G52 GPU、0.8 TOPS NPU、视频编解码 VPU、以及 DDR 控制器、eMMC/SD、USB、以太网、MIPI 等接口。泰山派开发板则是在 RK3566 基础上做成的 SBC,方便学习与产品原型开发。

2. MCU/单片机开发与嵌入式 Linux 开发的差异

维度 单片机 / MCU 开发 嵌入式 Linux 开发
运行环境 裸机或 RTOS,直接操作寄存器 多进程、多用户、有内核与文件系统
编程方式 以 C 为主,少量汇编,直接访问硬件 以用户态 C/C++ 为主,通过内核、驱动、系统调用访问硬件
启动流程 上电→复位→从 Flash 取指执行 上电→BootROM→Bootloader→Kernel→init→Shell/应用
资源 KB 级 RAM、Flash 通常百 MB 级 DDR、GB 级 eMMC/SD
调试 JTAG、串口、逻辑分析仪 串口、网络、gdb、内核日志、设备树、驱动调试
软件组成 一个工程里编一个固件 需分别构建 U-Boot、内核、根文件系统、应用

理解这些差异,有助于从“单片机思维”过渡到“系统思维”:在 Linux 下,我们更多是在配置与集成已有组件(Bootloader、内核、根文件系统),并编写用户态程序内核驱动,而不是从零写一个“主循环”。

3. 嵌入式 Linux 软件架构

嵌入式 Linux 从“上电”到“应用运行”,软件上通常分为四层,每一层都有明确职责。

3.1 Bootloader(引导加载程序)

  • 职责:上电后最先运行的程序;初始化关键硬件(如 DDR、时钟、存储控制器);从存储或网络加载内核镜像设备树(及可选的 initramfs),并跳转到内核入口。
  • 常见形态:U-Boot、U-Boot SPL + U-Boot、厂商提供的 loader(如 Rockchip 的 miniloader + U-Boot)。
  • 与本书的关系:泰山派使用 U-Boot,通过环境变量(如 bootargs)把根设备、串口、命令行参数传给内核。

3.2 Kernel(Linux 内核)

  • 职责:硬件抽象、进程调度、内存管理、文件系统、网络协议栈;加载设备树描述的驱动;挂载根文件系统;最后启动用户空间第一个进程(如 /sbin/init 或 systemd)。
  • 与本书的关系:本工程使用 rockchip_linux_defconfig 及泰山派设备树 tspi-rk3566-user-v10-linux.dts 构建内核,生成 Image.dtb,并打包为 boot.img

3.3 RootFS(根文件系统)

  • 职责:提供 / 下的目录结构、必备命令(如 lsmount)、库、脚本和配置文件;提供 init 程序及启动脚本(如 /etc/init.d 或 systemd 单元),完成系统服务与应用的启动。
  • 与本书的关系:本工程支持 Buildroot 默认 rootfs,也可使用 Ubuntu 24.04 作为根文件系统(见 BUILD.md),通过 RK_ROOTFS_SYSTEM=ubuntu24.04./build.sh rootfs 生成 ubuntu-rootfs.img

3.4 Application(应用程序)

  • 职责:实现具体业务逻辑,如网络服务、GUI、音视频、AI 推理等。运行在用户态,通过系统调用、设备节点、网络接口等与内核和硬件交互。

四层关系可概括为:Bootloader 加载并启动 Kernel → Kernel 挂载 RootFS 并启动 init → init 拉起各种服务与 Application

4. 为什么工业控制、消费电子、AIoT 选择 Linux

  • 生态丰富:成熟的文件系统、网络协议栈、数据库、脚本语言、容器与云原生工具,便于快速集成和二次开发。
  • 多任务与多用户:适合同时跑多个服务、远程登录、权限管理,符合工业与网关场景需求。
  • 硬件支持广泛:主流 SoC 厂商都会提供 Linux BSP,驱动与社区资源多。
  • AI 与多媒体:RK3566 等 SoC 的 NPU、GPU、VPU 在 Linux 下有成熟 SDK(如 RKNN、Mali、MPP),便于做边缘推理与音视频处理。
  • 可维护性与升级:支持远程升级、日志、脚本化运维,适合量产后的问题定位与功能迭代。

5. 嵌入式 Linux 工程师的能力模型与学习路径

  • 系统认知:清楚从上电到 Shell 的完整流程,能区分 Bootloader、Kernel、RootFS、应用各自的作用。
  • 构建与部署:能使用本工程中的 build.sh 完成 uboot、kernel、rootfs、firmware、update 镜像的构建与烧录。
  • 用户态开发:交叉编译、Makefile、C 系统编程(文件、进程、线程、网络)、Shell 脚本与自动化。
  • 板级与驱动:设备树、GPIO、I2C、SPI、UART、字符设备与 platform 驱动,以及内核调试。
  • 工程化能力:Buildroot/Yocto、日志与看门狗、升级与恢复、安全与量产部署。

建议学习路径:先搞清全景与启动流程(本篇),再练用户态与调试(第三篇),然后深入设备树与驱动(第四篇),最后拓展多媒体、AI 与工程化(第五、六篇)。


关键概念说明

  • BSP(Board Support Package):板级支持包,一般包括该板子对应的 Bootloader、内核配置与设备树、根文件系统定制和厂商提供的库与工具。本仓库即为 RK3566 泰山派的 BSP 工程。
  • 设备树(Device Tree):一种描述硬件拓扑与资源(寄存器、中断、GPIO、时钟等)的数据结构,由 Bootloader 传给内核,内核据此加载对应驱动,避免把板级细节写死在内核里。
  • 交叉编译:在 PC(x86_64)上使用针对 ARM64 的编译器生成在开发板上运行的二进制,本工程使用 aarch64-linux-gnu-gcc 等工具链。

泰山派实验步骤

实验 1:通过启动日志认识系统的启动阶段

  1. 准备:泰山派接好电源、串口(连接主机)、存储(TF 卡或 eMMC 已烧录镜像)。
  2. 串口连接:在主机上打开串口终端(如 minicom、screen、或 IDE 串口工具),波特率一般为 1500000(与设备树中 fiq-debuggerrockchip,baudrate 一致)。
  3. 上电或复位:观察终端输出,按时间顺序可大致看到:
    • Bootloader 阶段:U-Boot 或 loader 的版本与初始化信息;
    • Kernel 阶段:Linux 版本、设备树、驱动 probe、挂载 rootfs;
    • 用户态阶段:systemd 或 init 启动服务、出现登录提示或 Shell。
  4. 记录:将完整启动日志保存为文本,用不同颜色或注释标出各阶段边界,便于后续章节对照分析。

实验 2:结合泰山派软件包结构理解 BSP 的组成

在工程根目录下执行:

1
2
cd /path/to/tspi_linux_sdk_repo_20240131
./build.sh lunch # 选择 rk3566-tspi 对应的 BoardConfig

然后浏览以下目录与文件,建立“BSP 由哪些部分组成”的直观认识:

路径 说明
device/rockchip/.BoardConfig.mk 当前板型配置的软链接,指向 BoardConfig-rk3566-tspi-v10.mk
device/rockchip/rk356x/BoardConfig-rk3566-tspi-v10.mk 泰山派板级配置:架构、U-Boot/Kernel 的 defconfig、DTS、rootfs 类型等
u-boot/ U-Boot 源码与构建产物
kernel/ 内核源码;arch/arm64/boot/dts/rockchip/ 下为泰山派相关设备树
buildroot/ Buildroot 根文件系统构建(当使用 buildroot rootfs 时)
ubuntu/ Ubuntu 24.04 根文件系统脚本(如 mk-rootfs-noble.sh
rockdev/ 构建后生成的各分区镜像(boot.img、rootfs.img、recovery.img 等)

理解:一次完整构建会依次生成 U-Boot → Kernel(含 DTB)→ RootFS,再通过 build.sh firmwarebuild.sh updateimg 打包成可烧录的 rockdev/update.img


代码讲解

1. 板级配置:BoardConfig-rk3566-tspi-v10.mk

本工程中,泰山派的“选型”和“构建开关”集中在 device/rockchip/rk356x/BoardConfig-rk3566-tspi-v10.mk。下面摘录与“软件架构”直接相关的几项并做说明。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Target arch
export RK_ARCH=arm64

# Uboot defconfig
export RK_UBOOT_DEFCONFIG=rk3566

# Kernel defconfig / fragment / dts
export RK_KERNEL_DEFCONFIG=rockchip_linux_defconfig
export RK_KERNEL_DEFCONFIG_FRAGMENT=rk3566_tspi_wifi.config
export RK_KERNEL_DTS=tspi-rk3566-user-v10-linux

# boot image
export RK_BOOT_IMG=boot.img
export RK_KERNEL_IMG=kernel/arch/arm64/boot/Image

# parameter for GPT table(分区表)
export RK_PARAMETER=parameter-buildroot-fit.txt

# Buildroot / rootfs
export RK_CFG_BUILDROOT=rockchip_rk3566
export RK_ROOTFS_TYPE=ext4
export RK_ROOTFS_IMG=rockdev/rootfs.${RK_ROOTFS_TYPE}

# Recovery:本板使用 boot.img 作为 recovery,不单独构建 recovery
export RK_USE_BOOT_AS_RECOVERY=yes
  • RK_ARCH=arm64:目标为 64 位 ARM,与 RK3566 的 Cortex-A55 对应。
  • RK_KERNEL_DTS:指定内核使用的设备树基名,构建时会编译 tspi-rk3566-user-v10-linux.dts 并打包进 boot.img
  • RK_USE_BOOT_AS_RECOVERY=yes:recovery 分区直接使用内核的 boot.img,不再单独编 recovery 镜像,简化维护。

这些变量会被根目录的 build.sh 以及 device/rockchip/common/build.sh 使用,完成 uboot、kernel、rootfs、firmware 的串联。

2. 构建入口:build.sh 与“all”流程

主构建脚本为仓库根目录的 build.sh,实际逻辑在 device/rockchip/common/build.sh。执行 ./build.sh all 时,会依次调用(摘录自脚本逻辑):

  1. build_uboot:编译 U-Boot,生成 loader 与 U-Boot 镜像;
  2. build_kernel:编译内核与设备树,生成 Image.dtb,并打成 boot.img
  3. build_toolchain:如需则构建交叉工具链;
  4. build_rootfs:根据配置构建 Buildroot 或 Ubuntu 等根文件系统,得到 rootfs.img
  5. build_recovery:本板为使用 boot.img 作为 recovery;
  6. 后续 build_firmware / build_updateimg 会把各分区镜像打包到 rockdev/ 并生成 update.img

对应“软件架构”:uboot → kernel → rootfs → 打包,与前面四层模型一致。

3. 设备树顶层:tspi-rk3566-user-v10-linux.dts

设备树是“板级硬件描述”,内核和驱动依赖它识别外设。泰山派用户可见的顶层 DTS 为 kernel/arch/arm64/boot/dts/rockchip/tspi-rk3566-user-v10-linux.dts。开头如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/dts-v1/;

#include "rk3566.dtsi"
#include "tspi-rk3566-core-v10.dtsi"
// #include "tspi-rk3566-edp-v10.dtsi"
// #include "tspi-rk3566-dsi-v10.dtsi"
#include "tspi-rk3566-hdmi-v10.dtsi"
#include "tspi-rk3566-csi-v10.dtsi"
// #include "tspi-rk3566-gmac1-v10.dtsi"

/ {
model = "lckfb tspi V10 Board";
compatible = "lckfb,tspi-v10", "rockchip,rk3566";
// ...
};
  • rk3566.dtsi:SoC 级公共节点(CPU、内存、各控制器)。
  • tspi-rk3566-core-v10.dtsi:泰山派核心板公共配置(电源、调试串口、音频、部分外设)。
  • tspi-rk3566-hdmi-v10.dtsitspi-rk3566-csi-v10.dtsi:HDMI 与摄像头等板级功能;注释掉的为未启用功能(如 EDP、DSI、千兆网)。

通过“包含/注释”即可做板级功能裁剪,这是 BSP 中设备树组织的典型方式。


运行结果与现象分析

  • 实验 1:串口应看到从 U-Boot 到内核再到 systemd/init 的连续输出;若在某阶段卡住,可初步判断是 Bootloader、内核还是 rootfs/init 问题。
  • 实验 2:执行 ./build.sh lunch 并选择 rk3566-tspi 后,device/rockchip/.BoardConfig.mk 应指向 BoardConfig-rk3566-tspi-v10.mk;随后执行 ./build.sh allsave(或 all + firmware + updateimg),应在 rockdev/ 下得到 boot.imgrootfs.imgrecovery.img 等,对应 Bootloader 之后要加载的 Kernel+DTB 与 RootFS。

常见错误与排查方法

现象 可能原因 排查建议
串口无输出 串口线接错、波特率不对、未选对串口设备 确认 TX/RX、GND;波特率试 1500000 或 115200;在主机上确认 ttyUSB0 等设备
选错板型 lunch 选了其他 BoardConfig 重新执行 ./build.sh lunch 选 rk3566-tspi
构建报错缺少工具链 未安装 aarch64 交叉编译器或未构建 toolchain 按 BUILD.md 安装依赖,或执行 ./build.sh toolchain
启动卡在内核或 rootfs bootargs 中 root= 错误、rootfs 未正确烧录 对照第 5、6、8 章检查 bootargs 与分区、镜像

本章小结

  • 嵌入式系统按处理器形态可分为 MCU、MPU、SoC、SBC;RK3566 为 SoC,泰山派为基于 RK3566 的 SBC。
  • 嵌入式 Linux 软件可归纳为四层:Bootloader → Kernel → RootFS → Application,本工程通过 build.sh 与 BoardConfig 依次构建 U-Boot、内核(含设备树)、根文件系统并打包为镜像。
  • 通过串口观察启动日志可建立“阶段边界”的感性认识;通过浏览 device/rockchipkernelu-bootrockdev 等目录可理解 BSP 的组成与构建流程。
  • 后续章节将围绕启动流程、存储与分区、U-Boot、内核与设备树、根文件系统等展开,并逐步过渡到用户态开发、设备树与驱动、以及工程化内容。

思考题与扩展实验

  1. 查阅 RK3566 芯片手册,列出其 CPU 核数、主频、以及 GPU、NPU、VPU 的简要规格,并说明它们在本工程中对应的软件组件(内核、驱动、用户库)可能在哪里体现。
  2. device/rockchip/common/build.sh 中搜索 build_kernelbuild_rootfs,画出从 build.sh all 到生成 boot.imgrootfs.img 的调用关系。
  3. 若将 tspi-rk3566-user-v10-linux.dts 中 HDMI 的 #include "tspi-rk3566-hdmi-v10.dtsi" 注释掉并重新编译内核,预期启动后显示会有什么变化?在学完设备树章节后再做验证。