【系统移植】
一、什么是系统移植
系统移植(System Porting)是将通用 / 开源的系统(或中间件、协议栈)从原始硬件平台 / 开发环境,通过针对性的适配、修改和编译,使其稳定运行在目标硬件平台上的过程。这个过程可能涉及到许多不同的方面,包括硬件适配、驱动程序开发、 引导加载程序(Bootloader)配置、文件系统适配、内核参数设置等等。核心是屏蔽不同硬件的底层差异,让成熟系统的上层功能在新硬件上直接复用,无需从零开发。
系统移植的主要目的是使一个操作系统能够在不同的硬件平台上正常运行,并充分发挥其功能。在嵌 入式领域,不同的硬件平台可能有不同的处理器架构、外设、内存布局等,因此需要进行适当的调整和配 置,以确保操作系统能够正确地与硬件交互。
移植的核心逻辑是上层功能完全复用,仅对底层与硬件强相关的部分做适配修改,也是嵌入式开发中 “高效复用成熟代码、降低开发成本” 的核心手段。
- 上层:系统 / 中间件的核心功能(如 FreeRTOS 的任务调度、Linux 的进程管理、LWIP 的 TCP 协议)与硬件无关,100% 复用,无需修改;
- 底层:仅对与硬件 / 架构强相关的部分(时钟、中断、外设驱动、内存地址)做针对性适配,这是移植的唯一工作。
系统移植的难度取决于目标硬件与原始平台的架构差异(同架构移植简单,跨架构移植复杂)和系统的复杂度(RTOS 移植简单,Linux 内核移植复杂),核心适配层主要分为:硬件内核层(CPU、时钟、中断)、外设驱动层、编译链接层(工具链、链接脚本)、系统核心层(调度、内存管理)。
通常情况下,系统移植需要进行以下工作
选择操作系统版本: 首先需要选择适合目标硬件平台的操作系统版本,确保其支持目标架构和硬件特性。
硬件适配:修改操作系统的源代码,以适配新的硬件平台。这可能涉及修改底层驱动程序、中断处理、外设配置等。
驱动程序开发: 编写或适配适合目标硬件的驱动程序,使操作系统能够与硬件进行通信。
引导加载程序配置: 配置引导加载程序,使其能够正确加载和启动操作系统内核。
文件系统适配: 调整文件系统以适应新的硬件存储和文件结构
内核参数设置: 配置操作系统内核参数,以适应硬件资源和性能需求。
调试和测试: 进行测试,确保操作系统在新硬件平台上稳定运行。调试可能涉及硬件问题、驱动程序问题、性能问题等。
二、Flash分区映射与Linux系统启动流程
在学习系统移植前徐先了解Flash的分区映射与Linux系统的启动流程,以下所有内容均基于Cortex-A系列下的STM32MP157A开发板进行讲解
2.1、Flash分区映射
Flash具体分区如下:

2.2、Linux 系统启动流程

1. 最底层:ROM Code(固化在芯片内部的启动代码)
- 存储位置:芯片内置的 ROM(容量 < 128KB),是硬件出厂时就固化的代码。
- 核心作用:
- 完成最基础的时钟初始化,让芯片的时钟模块正常工作。
- 从启动设备(如闪存、串口)加载第一阶段启动加载器
FSBL。 - 启动
FSBL,将系统控制权交给它。
- 这是整个启动流程的 “起点”,仅负责唤醒硬件最基础的功能,并找到下一级启动程序。
2. 第一阶段启动加载器:FSBL(First Stage Boot Loader)
-
核心功能:
- 最小化硬件初始化:仅初始化启动必需的硬件,无任何冗余功能,包括:
- 芯片核心:时钟树(PLL / 晶振)、CPU 核、MMU / 缓存基础配置;
- 存储相关:DDR(SDRAM/DDR3/4)初始化(关键!让系统有可运行的内存)、eMMC/SD 卡 / NOR Flash 的底层驱动;
- 调试相关:串口(UART)初始化(仅用于打印简单启动日志,无交互);
- 其他:电源管理(PMIC)、启动介质检测(识别从 eMMC/SD/ 网口启动)。
- 加载 SSBL 到 DDR:从指定启动介质(如 eMMC BOOT1 分区、SD 卡指定扇区)读取 SSBL(U-Boot)的二进制文件,将其拷贝到 DDR 的指定内存地址(如 STM32MP1 的
0x80000000)。 - 权限移交:FSBL 自身不驻留内存,完成加载后直接跳转到 SSBL 在 DDR 的内存地址,将 CPU 执行权完全交给 SSBL,自身执行结束。
- 最小化硬件初始化:仅初始化启动必需的硬件,无任何冗余功能,包括:
-
关键特点
- 极致轻量:代码量极小(通常几十 KB 到几百 KB),编译后体积远小于 SSBL,适配芯片引导区的小容量空间;
- 不可定制 / 极少定制:由原厂基于芯片底层架构开发(如 STM32MP1 的 FSBL 由 ST 官方基于 STM32Cube 开发),开发者无需修改,仅需按板卡手册烧写到指定介质即可;
- 无交互 / 无配置:无命令行、无环境变量、无用户交互,执行流程固化,仅打印简单的 “初始化成功 / 加载 SSBL 完成” 日志;
- 存储位置固定:必须烧写到芯片指定的 “专用引导分区”(如 eMMC 的 BOOT0/BOOT1 分区、SD 卡的前 128/256 个扇区),否则 ROM Boot 无法识别加载;
- 运行位置:先在芯片内部的 SRAM(片上小内存)运行(DDR 未初始化前无外部内存),DDR 初始化后自身仍在 SRAM,仅将 SSBL 加载到 DDR
- 这一步的核心目标是 “解锁” 外部大容量内存,为后续复杂程序的运行做准备。
3. 第二阶段启动加载器:SSBL(Second Stage Boot Loader)
-
核心功能
- 系统级硬件初始化:在 FSBL 基础上,初始化所有系统运行需要的硬件,包括:
- 扩展硬件:网口(Ethernet)、USB、SPI/I2C、LCD、NAND Flash;
- 存储高级配置:eMMC/SD 卡的分区识别、文件系统驱动(如 FAT32/ext4);
- 内存高级配置:DDR 全区域管理、内存映射(MMU)完整配置;
- 提供交互式命令行:这是 SSBL(U-Boot)的核心特征,支持各种调试 / 配置命令,比如你熟悉的:
- 存储操作:
mmc list/mmc read/ums 0 mmc 1(UMS 模式); - 网络操作:
ping/tftp/nfs(加载内核 / 根文件系统); - 启动配置:
setenv bootcmd/saveenv(修改启动命令、保存环境变量);
- 存储操作:
- 加载并启动 Linux 内核 / 根文件系统:
- 从 eMMC/SD/ 网口(TFTP/NFS)读取 Linux 内核(zImage/Image)和设备树(dtb),加载到 DDR 指定地址;
- 传递启动参数(如根文件系统路径
root=/dev/mmcblk1p2),跳转到内核地址,启动 Linux;
- 启动环境管理:提供非易失性环境变量(保存在 eMMC/SD 的专用分区),可定制启动流程(如从 NFS 挂载根文件系统、默认启动内核版本);
- 系统调试 / 救砖:支持中断内核启动、进入命令行,可修复损坏的内核 / 根文件系统,是嵌入式开发中 “救砖” 的核心工具(比如 eMMC Bootloader 损坏后,用 SD 卡的 SSBL 启动并修复 eMMC)。
- 系统级硬件初始化:在 FSBL 基础上,初始化所有系统运行需要的硬件,包括:
-
关键特点
- 功能丰富、高度可定制:开发者可通过修改 U-Boot 源码、配置
make menuconfig添加 / 删减功能(如开启 NFS/UMS/TFTP),适配自研板卡; - 有交互、有配置:提供完整的命令行交互,支持环境变量配置,可灵活修改启动逻辑;
- 运行位置固定:全程在DDR 内存中运行(由 FSBL 加载到 DDR,自身不占用片上 SRAM);
- 存储位置灵活:可烧写到 eMMC/SD 的用户区分区(非专用引导区),只要 FSBL 能识别其存储地址即可;
- 代码量较大:编译后体积通常几 MB,包含各种硬件驱动和命令逻辑。
- 功能丰富、高度可定制:开发者可通过修改 U-Boot 源码、配置
- 这是连接硬件与 Linux 内核的 “桥梁”,负责准备内核启动所需的文件和环境。
4. Linux Kernel(Linux 内核)
- 存储位置:外部 RAM。
- 核心作用:
- 初始化平台驱动等内核级硬件支持,让内核能管理硬件设备。
- 挂载根文件系统(rootfs)(包含系统的基础文件、目录结构,是用户空间的 “根”)。
- 加载并启动用户空间初始化进程(如
/sbin/init),将控制权交给用户空间。
- 内核启动后,系统进入受内核管理的状态,开始构建用户空间的运行环境。
5. 最上层:Linux User Space(Linux 用户空间)
- 存储位置:外部 RAM。
- 核心作用:
- 加载并运行用户空间的各种服务和应用程序(如桌面环境、网络服务、用户自定义应用等)。
- 这是用户能直接交互的层面,所有上层功能都在这里运行
标准 Linux 启动过程的主要步骤:
STM32MP1启动流程

与标准流程基本一致,多提供了一种安全监控的模式,可以由 FSBL 或者 SSBL 启动。由于该开发板 采用异核架构,有 A 核和 M 核,如果要加载 M 核的固件,可以在 SSBL 或者 linux 启动。
STM32MP1 非安全启动流程


2.3、启动过程中的外设初始化
2.3.1、ROM Code

流程总览
ROM Code 是芯片上电 / 复位后执行的第一段代码,核心作用是初始化硬件、选择启动路径、加载并验证启动镜像,最终完成系统启动。整个流程按功能分为 5 个核心模块:
- 安全启动子流程(左上)
- 主启动分支判断(中间)
- 待机唤醒处理(右侧)
- 特殊模式启动(左下:RMA/ENGI)
- 错误处理(底部)
核心模块详解
1. 安全启动子流程(左上灰色模块)
这是正常冷启动的核心路径,负责从外部设备加载并验证启动镜像:
- Select boot device
- 功能:遍历启动设备列表(如 SPI Flash、eMMC、SD 卡),选择当前优先级最高的设备。
- 触发:冷启动时进入,或前一个设备认证失败后重试。
- Load image from boot device
- 功能:从选中设备读取启动镜像(如 BL1、U-Boot)到内部 RAM。
- Authenticate the boot image
- 功能:校验镜像签名 / 哈希值,确保镜像未被篡改、来源合法。
- Auth Ok?(判断)
- ✅ Yes → Jump to image:跳转到验证通过的镜像入口,执行后续启动(如加载内核)。
- ❌ No → 回到
Select boot device:切换到下一个设备重试,直到所有设备尝试完毕。
2. 主启动分支判断(中间核心逻辑)
系统复位后,先区分主核 / 从核,再根据复位原因选择启动模式:
- Get reset reason
- 功能:读取复位状态寄存器,判断复位类型(冷复位、待机唤醒、看门狗复位等)。
- CPU#0?(判断是否为主核)
- ✅ Yes → System init:主核(A7 主核)执行硬件初始化(时钟、RAM、外设复位等)。
- ❌ No → Secondary A7 core boot:从核进入从核启动流程,等待主核同步。
3. 复位原因分支(System init 之后的判断)
主核初始化完成后,根据复位原因进入不同模式:
- Standby Exit?(是否为待机唤醒?)
- ✅ Yes → 进入右侧「待机唤醒处理流程」
- ❌ No → 继续判断
- RMA?(是否为售后维修模式?)
- ✅ Yes →
RMA boot process→RMA boot:加载维修专用镜像,跳过部分安全校验,用于硬件检测 / 修复。 - ❌ No → 继续判断
- ✅ Yes →
- ENGI boot?(是否为工程调试模式?)
- ✅ Yes →
ENGI boot process→ENGI boot:加载未签名的调试镜像,开放调试接口,用于研发验证。 - ❌ No → Cold boot:进入正常冷启动,触发「安全启动子流程」。
- ✅ Yes →
4. 待机唤醒处理流程(右侧灰色模块)
处理系统从深度待机(CSTANDBY)唤醒的场景,此时 A7 休眠,需优先恢复低功耗的 M4 核:
- A7 in CSTANDBY(初始状态):唤醒前 A7 处于深度低功耗状态。
- Suspend boot:暂停 A7 启动,优先处理唤醒源(如 M4 触发的唤醒)。
- Boot A7?(判断是否立即启动 A7)
- ❌ No → 先处理 M4 唤醒:
- Boot M4?(判断是否启动 M4)
- ✅ Yes →
Get M4 wakeup request:读取 M4 唤醒请求参数。 - ❌ No →
Standby exit:直接退出待机,恢复到唤醒前状态。
- ✅ Yes →
- M4 wakeup process:初始化 M4 时钟、RAM,加载并启动 M4 镜像。
- M4 boot ok(判断 M4 启动是否成功)
- ✅ success → 回到
Boot A7?再次判断。 - ❌ failed →
M4 boot ko:回到主流程(如触发冷启动或启动失败)。
- ✅ success → 回到
- Boot M4?(判断是否启动 M4)
- ✅ Yes → Cold boot:触发正常冷启动流程。
- ❌ No → 先处理 M4 唤醒:
5. 错误处理流程
- Endless loop:启动失败(如所有设备认证失败、核心初始化失败)时进入无限循环,防止系统异常跳转。
- Boot Failed:循环后标记启动失败,通过硬件引脚 / 日志通知外部。
2.3.2、TF-A

三、什么是U-Boot
U-Boot 全称 Universal Boot Loader,是一款开源的、跨平台的嵌入式系统引导加载程序(Bootloader),也是嵌入式领域应用最广泛的 Bootloader 之一,你在 STM32MP1 上接触到的 U-Boot 就是其针对该异构多核平台的移植版本,它是嵌入式系统上电启动后,介于硬件裸机和操作系统内核之间的核心程序。
简单来说,嵌入式设备(如 STM32MP1、嵌入式开发板、工业控制器等)没有 PC 的 BIOS/UEFI,U-Boot 就承担了类似 BIOS 的核心作用,同时功能更贴合嵌入式场景的定制化需求。
3.1、核心定位
嵌入式系统启动流程的关键中间层:上电后 CPU 先执行片内 ROM 中的固化引导程序(如 STM32MP1 的 ROM Boot),由其加载 U-Boot 到内存中运行;U-Boot 完成硬件初始化后,再加载 Linux/RTOS 内核、根文件系统等,最终将系统控制权交给内核,完成整个启动流程。
3.2、U-Boot 的核心功能(贴合 STM32 开发场景)
- 硬件底层初始化这是最基础的功能:上电后硬件处于裸机状态,U-Boot 会初始化核心硬件(CPU、内存 SDRAM/DDR、时钟、串口、MMC/SD/eMMC、NAND Flash 等),为后续加载内核搭建可用的硬件环境(比如你之前用
mmc dev命令,前提是 U-Boot 已经初始化了 MMC 控制器)。 - 加载并启动系统镜像从存储设备(MMC、NAND、SPI Flash、网络等)读取系统镜像(Linux 的 zImage/uImage、裸机程序、根文件系统 ramdisk 等),加载到指定的内存地址,并执行启动(这也是你之前接触的
go/bootz/bootm命令的核心作用)。 - 提供交互式命令行环境这是 U-Boot 的特色功能:启动后会进入串口命令行,支持各种操作命令(如 MMC 设备管理、内存读写、镜像烧写、网络下载、环境变量配置等),方便开发、调试和系统配置(比如你之前用到的
mmc dev、go都是 U-Boot 命令行的常用命令)。 - 环境变量管理支持自定义环境变量(如
bootcmd启动命令、bootargs内核启动参数、mmcdev默认 MMC 设备号等),保存在非易失性存储中,无需修改 U-Boot 源码即可定制启动逻辑(比如设置bootcmd为mmc dev 1;bootz,即可实现上电自动从 eMMC 启动 Linux)。 - 辅助开发 / 调试功能支持网络下载(tftp、nfs)、镜像烧写(将内核 / 文件系统烧写到 MMC/NAND)、内存查看 / 修改(md/mw 命令)、分区管理等,大幅降低嵌入式系统的开发和调试成本。
3.3、U-Boot 的核心特点
- 开源免费:基于 GPL 协议,可根据硬件平台自由移植和修改;
- 跨平台:支持 ARM、x86、MIPS 等几乎所有嵌入式 CPU 架构,适配各种嵌入式硬件;
- 可定制化:按需裁剪功能(比如仅保留 MMC 和串口功能,减小 U-Boot 镜像体积),适配资源受限的嵌入式设备;
- 支持多种存储 / 网络:兼容嵌入式领域几乎所有的存储设备和网络协议。
3.4、对 STM32MP1 开发的实际意义
STM32MP1 是异构多核平台(A7 核 + M4 核),其 U-Boot 不仅完成 A7 核侧的硬件初始化、Linux 内核加载,还能实现对 M4 核的引导(加载 M4 核的 FreeRTOS / 裸机程序),是 STM32MP1 异构系统启动和调试的核心工具,你之前接触的 MMC 命令、启动命令,都是其在该平台上的具体应用。
简单总结:U-Boot 是嵌入式系统的 “启动管家”,也是开发调试的 “便捷工具”,是嵌入式 Linux 开发(包括 STM32MP1)的必备基础。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐



所有评论(0)