1. 嵌入式Linux系统概述
1.1 嵌入式系统定义
嵌入式系统是以应用为中心、以计算机技术为基础,软硬件可裁剪,适用于对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。它通常作为某个更大系统的一部分,执行预定义的专用任务。
核心特征: 专用性、资源受限、实时性要求、高可靠性、低功耗、成本敏感。
| 对比维度 | 通用计算机系统 | 嵌入式系统 |
|---|---|---|
| 应用场景 | 多任务、多用户、通用计算 | 专用功能、单一任务或有限任务集 |
| 资源约束 | CPU/内存/存储充裕 | CPU/内存/存储严格受限 |
| 功耗要求 | 相对宽松 | 极低功耗,常电池供电 |
| 实时性 | 非实时或软实时 | 硬实时或软实时 |
| 开发模式 | 应用开发为主 | 软硬件协同设计、交叉编译 |
| 典型代表 | PC、服务器、笔记本 | 路由器、智能家电、工控设备、汽车ECU |
1.2 Linux在嵌入式领域的优势
Linux操作系统凭借其开放源码、稳定可靠、生态丰富的特点,已成为嵌入式系统领域的主流选择。以下从多个维度分析其核心优势:
- 开源免费: 无许可证费用,可自由修改和分发,降低产品开发成本。
- 内核可裁剪: 通过配置选项可定制内核大小,适配从MCU到MPU的各类硬件。
- 驱动生态丰富: 支持大量硬件外设(USB、PCIe、I2C、SPI、UART、Ethernet、WiFi、蓝牙等),社区驱动代码持续更新。
- 网络协议栈成熟: 内置完整的TCP/IP协议栈,支持IPv4/IPv6、路由、防火墙、VPN等。
- 文件系统多样: 支持ext4、F2FS、UBIFS、JFFS2、SquashFS、tmpfs等,满足不同存储介质需求。
- 实时扩展能力: 通过PREEMPT_RT补丁或Xenomai/Cobalt实现硬实时能力。
- 开发工具链完善: GCC、GDB、QEMU、Yocto、Buildroot等工具链成熟,降低开发门槛。
- 社区与商业支持: 全球开发者社区活跃,同时有Wind River、MontaVista等商业公司提供企业级支持。
选型建议: 对于需要复杂网络、图形界面、多任务管理、长期维护的嵌入式产品,Linux是首选。对于资源极度受限(如< 2MB Flash、< 64KB RAM)的场景,可考虑FreeRTOS或裸机方案。
1.3 典型嵌入式Linux系统架构
一个完整的嵌入式Linux系统由三个核心层次构成:Bootloader(引导加载程序)、Linux内核(Kernel)、根文件系统(Root Filesystem)。三者协同工作,完成从硬件上电到用户应用运行的全过程。
1.3.1 Bootloader(引导加载程序)
Bootloader是系统上电后第一个执行的软件,负责初始化硬件(时钟、内存、串口、存储控制器等),并将Linux内核从存储介质(Flash、SD卡、网络)加载到内存中,然后跳转到内核入口执行。
| Bootloader | 适用架构 | 特点 |
|---|---|---|
| U-Boot | ARM、x86、RISC-V、MIPS等 | 功能最丰富,社区活跃,支持网络启动、Flash烧写、环境变量 |
| Barebox | ARM、x86 | 代码简洁,POSIX风格API,适合快速开发 |
| GRUB | x86、x86_64 | 主要用于PC/服务器,支持多引导、模块化 |
常见误区: Bootloader不负责驱动所有外设,它只需初始化启动内核所需的最小硬件集(时钟、DDR、存储控制器、串口)。其余外设驱动由内核接管。
1.3.2 Linux内核
Linux内核是系统的核心,提供进程管理、内存管理、文件系统、网络协议栈、设备驱动等基础服务。嵌入式场景下,内核通常通过make menuconfig或Buildroot的配置界面进行裁剪,移除不需要的功能以减小体积和内存占用。
# 典型嵌入式内核配置裁剪示例
# 移除不需要的文件系统
# CONFIG_EXT4_FS is not set
# CONFIG_XFS_FS is not set
# CONFIG_BTRFS_FS is not set
# 保留嵌入式常用文件系统
CONFIG_SQUASHFS=y
CONFIG_UBIFS_FS=y
CONFIG_TMPFS=y
# 移除不必要的网络协议
# CONFIG_IPV6 is not set
# CONFIG_WIRELESS is not set
# 保留必要驱动
CONFIG_SERIAL_8250=y
CONFIG_SPI=y
CONFIG_I2C=y
CONFIG_GPIO_SYSFS=y
1.3.3 根文件系统
根文件系统(Root Filesystem)是内核启动后挂载的第一个文件系统,包含系统初始化脚本、系统库、配置文件、用户应用程序等。嵌入式系统中常用的根文件系统类型包括:
- SquashFS: 只读、高压缩比,适合存放不变的系统文件和应用程序。
- UBIFS: 针对NAND Flash优化的读写文件系统,支持磨损均衡和坏块管理。
- JFFS2: 较老的Flash文件系统,适合NOR Flash。
- tmpfs: 基于内存的临时文件系统,用于
/tmp、/var等运行时数据。 - overlayfs: 联合文件系统,实现只读根文件系统+可写上层,常用于OTA升级。
Buildroot优势: Buildroot可以一键生成完整的根文件系统镜像,自动包含BusyBox、glibc/musl、dropbear(SSH)、udhcpc(DHCP客户端)等常用组件,并支持SquashFS、UBIFS、ext4等多种文件系统格式输出。
1.3.4 系统启动流程详解
从硬件上电到用户应用运行,嵌入式Linux系统经历以下关键阶段:
- ROM代码(一级Bootloader): 芯片内部固化代码,初始化基本时钟和内存,加载二级Bootloader到SRAM。
- SPL/MLO(二级Bootloader): 初始化DDR控制器,从存储介质加载完整U-Boot到DDR。
- U-Boot(三级Bootloader): 初始化串口、网络、存储等外设,加载内核和设备树(DTB)到内存,设置启动参数(bootargs),跳转到内核。
- 内核解压与初始化: 内核自解压(若为压缩镜像),初始化内存管理、进程调度、中断控制器,挂载临时根文件系统(initramfs)。
- 挂载真正根文件系统: 根据bootargs中的root参数,挂载最终根文件系统(如
/dev/mmcblk0p2或UBI卷)。 - 启动init进程: 内核启动第一个用户空间进程
/sbin/init(通常为BusyBox init或systemd),执行/etc/inittab或/etc/init.d/中的启动脚本。 - 用户应用运行: 启动网络服务、守护进程、业务应用程序,系统进入工作状态。