1.1 嵌入式Linux系统概述

嵌入式Linux系统是指将Linux操作系统裁剪、配置后,部署到特定硬件平台(如ARM、RISC-V、MIPS)上的专用计算机系统。与通用PC上的Linux发行版不同,嵌入式Linux强调资源受限、功能专用、实时性与稳定性。一个完整的嵌入式Linux系统通常由四个核心部分组成:Bootloader、Linux内核、根文件系统以及交叉编译环境(开发主机侧)。

核心概念:嵌入式Linux系统的“三件套”通常指 Bootloader、Kernel、Rootfs。这三者缺一不可,且必须与目标硬件平台(如ARM Cortex-A系列)的体系结构严格匹配。

1.1.1 嵌入式Linux系统组成

下图展示了嵌入式Linux系统在目标硬件上的典型分层架构,从底层硬件到上层应用,每一层都承担着关键职责。

嵌入式Linux系统分层架构图 嵌入式Linux系统分层架构 用户应用程序 (GUI / 网络 / 业务逻辑) C库 / 系统库 (glibc / musl / pthread) Linux 内核 (进程调度 / 内存管理 / 驱动 / 网络栈) 设备树 (DTB) — 硬件描述 Bootloader (U-Boot / ATF / SPL) ARM 硬件平台 (CPU / RAM / Flash / 外设) 说明:设备树(DTB)位于内核层,负责将硬件拓扑信息传递给内核驱动。

1.1.2 交叉编译环境

由于嵌入式目标设备(如ARM开发板)资源有限,无法在其上直接编译大型Linux内核或应用程序。因此,开发工作通常在性能强大的宿主机(Host)(x86架构PC)上进行,使用交叉编译工具链生成目标设备(ARM架构)可执行的二进制代码。

组件 宿主机 (Host) 目标机 (Target)
架构 x86_64 ARM (armv7-a / aarch64)
编译器 gcc (本地编译) arm-linux-gnueabihf-gcc (交叉编译)
运行环境 Ubuntu / Fedora 嵌入式Linux (裁剪后)
性能 高 (多核、大内存) 受限 (低主频、小内存)
交叉编译工具链命名规则:以 arm-linux-gnueabihf-gcc 为例,arm 表示目标架构,linux 表示操作系统,gnueabihf 表示使用glibc库且支持硬件浮点。在配置内核时,必须指定正确的交叉编译器前缀。

1.1.3 Bootloader

Bootloader是系统上电后第一个执行的程序,负责初始化硬件(时钟、DDR、串口)、加载内核映像到内存,并将控制权交给内核。在ARM平台中,U-Boot是最主流的Bootloader。

U-Boot的典型启动流程如下:

  1. 第一阶段(SPL): 执行汇编代码,初始化CPU、关闭Cache、设置栈指针,加载完整的U-Boot到DDR。
  2. 第二阶段(U-Boot Proper): 初始化串口、Flash、网络等外设,解析环境变量,从存储介质(eMMC、SD卡、NAND)读取内核和设备树。
  3. 启动内核: 通过 bootm 或 bootz 命令跳转到内核入口点,传递启动参数(如 console=ttyS0,115200)。
常见陷阱:设备树(DTB)必须与内核版本匹配,且Bootloader加载DTB的地址不能与内核解压地址重叠,否则会导致内核启动崩溃。

1.1.4 Linux内核

Linux内核是嵌入式系统的核心,提供进程管理、内存管理、文件系统、网络协议栈和设备驱动。在ARM平台移植中,内核的配置与编译是核心工作。

内核编译的关键步骤:

# 1. 清理之前的编译产物
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean

# 2. 加载默认配置(基于具体开发板,如vexpress)
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- vexpress_defconfig

# 3. 菜单配置(裁剪驱动、文件系统支持等)
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig

# 4. 编译内核镜像(zImage)和设备树(dtb)
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage dtbs -j4

# 5. 编译内核模块
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules

编译完成后,会在 arch/arm/boot/ 目录下生成 zImage(压缩内核镜像)和 dts/ 目录下的 .dtb 文件(设备树二进制)。

1.1.5 根文件系统

根文件系统(Rootfs)是内核启动后挂载的第一个文件系统,它包含了系统运行所需的目录结构、库文件、配置文件和应用程序。没有根文件系统,内核会因无法执行 init 进程而崩溃(Kernel Panic)。

嵌入式系统中常用的根文件系统类型:

类型 特点 适用场景
initramfs 集成在内核中,内存盘形式,启动快 早期启动、调试、极小系统
BusyBox 单一二进制文件集成常用命令,体积小 资源受限的嵌入式设备
Buildroot 自动化构建工具,生成完整Rootfs 快速原型开发、量产固件
Yocto 高度可定制,支持复杂包管理 大型产品、需要定制化Linux发行版
最小根文件系统结构:至少需要包含 /dev、/proc、/sys、/etc、/bin、/sbin、/lib 目录,以及 /sbin/init 程序。BusyBox可以大幅简化这一过程。

1.1.6 系统启动流程总览

从按下电源键到用户登录,嵌入式Linux系统的完整启动流程可以概括为以下阶段:

嵌入式Linux系统启动流程图 嵌入式Linux系统启动流程 上电 / ROM Boot Bootloader (SPL) U-Boot Proper 加载 Kernel + DTB 内核解压 / 初始化 挂载 Rootfs / 启动 init 关键阶段说明 1. ROM Boot:芯片内部固化代码,初始化基本时钟,加载SPL。 2. SPL:初始化DDR,加载U-Boot Proper到内存。 3. U-Boot Proper:初始化外设,从存储介质读取Kernel和DTB。 4. Kernel:解压自身,解析DTB,初始化驱动,挂载根文件系统。 5. init:执行第一个用户态进程(如systemd或BusyBox init)。

1.1.7 本章小结