第 8 章:M33 领航——引导 A35 加载 U-Boot 与 Linux 内核

在之前的章节中,M33 已经完成了"圈地"和"自检"。现在,我们要执行最关键的一步:由 M33 释放 A35 的 Hold Reset 信号,并引导其进入 Linux 世界。 在 STM32MP257F-DK 上,这相当于 M33 扮演了传统架构中安全启动(Secure Boot)发起者的角色。


8.1 异构启动的"点火"流程

A35 核心在复位后默认处于 Hold Reset 状态。要拉起它,M33 需要完成以下"三部曲":

  1. 加载镜像 :将 A35 的引导程序(通常是 u-boot-spl.stm32TF-A)搬运到指定的 DDR 物理地址。

  2. 设置启动向量:配置系统控制寄存器(SYSCON),告诉 A35 复位后第一行代码去哪里跑。

  3. 释放复位:修改 RCC 寄存器,撤销 A35 的复位信号。


8.2 实战:配置 A35 的启动基地址

在 MP257 中,A35 的复位向量地址是由 SYSCON 寄存器控制的。

#define SYSCON_BASE 0x44230000

#define SYSCON_A35_RVBAR_L (*(volatile uint32_t *)(SYSCON_BASE + 0x60)) // 低32位

#define SYSCON_A35_RVBAR_H (*(volatile uint32_t *)(SYSCON_BASE + 0x64)) // 高32位

void A35_Set_Boot_Address(uint64_t boot_addr) {

// 设置 A35 复位后的跳转起始点

// 假设我们将 U-Boot 搬到了 0x90200000

SYSCON_A35_RVBAR_L = (uint32_t)(boot_addr & 0xFFFFFFFF);

SYSCON_A35_RVBAR_H = (uint32_t)((boot_addr >> 32) & 0xFFFFFFFF);

}

8.3 深度实战:释放 A35 复位信号

这一步是真正的"点火"。我们需要操作 RCC (Reset and Clock Control) 模块。

#define RCC_BASE 0x44200000

#define RCC_A35_BOOT_CR (*(volatile uint32_t *)(RCC_BASE + 0xC00))

void A35_Release_Reset(void) {

// 开启 A35 核心时钟并释放复位

// 具体的位偏移需参照 MP257 参考手册 RM0457

// BIT 0 通常对应 Core 0 的复位释放

RCC_A35_BOOT_CR |= 0x01;

printf("[M33] A35 Reset Released! Linux is booting...\r\n");

}

8.4 镜像搬运:M33 侧的"搬运工"

在实战中,A35 的镜像通常存储在 SD 卡的特定分区。M33 可以通过 SDMMC 驱动读取,也可以利用我们在第 4 章实现的 DMA 串口 从上位机接收。

为了简化演示,我们假设镜像已经通过调试器加载到了 DDR 的 0x90200000

void Start_A35_Workflow(void) {

// 1. 确保 DDR 已经初始化(在 M33 引导模式下,M33 需负责 DDR 控制器初始化)

// DDR_Init();

// 2. 设置跳转地址

A35_Set_Boot_Address(0x90200000);

// 3. 释放 A35

A35_Release_Reset();

}

8.5 关键同步:跨核握手标志

在 A35 启动初期,M33 往往需要知道 A35 是否运行到了内核。我们可以利用第 7 章划定的 Shared Memory (0x90000000) 做一个简单的握手信号。

  • M33 逻辑 :在内存 0x90000000 写入 0x00000000

  • A35 U-Boot 逻辑 :启动后往 0x90000000 写入 0xDEADBEEF

  • M33 观察:通过串口打印出状态变化。


8.6 避坑指南 (Debug Tips)

  • 陷阱 1:DDR 未就绪 。如果 M33 没调好 DDR 就释放 A35,A35 会因为取不到指令立即触发 Prefetch Abort

    • 检查 :使用 STM32CubeMP2 提供的 DDR 测试脚本验证稳定性。
  • 陷阱 2:中断向量冲突。A35 启动后会配置 GIC(通用中断控制器)。如果 RIF 没分好,A35 可能会误关掉 M33 的 NVIC 中断。

    • 对策:在引导 A35 前,确保 RIF 已对核心外设加锁。
  • 陷阱 3:地址空间可见性。M33 属于 32 位架构,访问 64 位的 A35 空间时,需确认总线窗口映射。


章节小结

到此为止,你已经完成了一个异构多核系统的"冷启动"全过程。此时,开发板上会出现奇妙的一幕:M33 依然在稳定地读取 IMU 数据并通过串口打印,而 A35 已经开始在后台疯狂刷屏启动 Linux 了。

相关推荐
lularible几秒前
PTP协议精讲(3.7):传输层实现——PTP报文的“高速公路“
网络·网络协议·开源·嵌入式·ptp
S1998_1997111609•X4 分钟前
RSS/RSA\-SSh,G\-bps^&&·iOS\Cd/,~…:cade?_code in/@$&¥_buy=ID card|want_M_GEN.M*L
网络协议·百度·ssh·gpu算力·oneapi
郝学胜-神的一滴9 分钟前
深入epoll反应堆模型:从libevent源码看高性能IO设计精髓
linux·服务器·开发语言·c++·网络协议·unix·信息与通信
LCG元9 分钟前
STM32实战:基于STM32F407的LWIP以太网通信(TCP Server)
stm32·嵌入式硬件·tcp/ip
H_老邪18 分钟前
CentOS 9 解决 root 登录及重置密码指南
linux·运维·centos
Full Stack Developme23 分钟前
Linux CURL 教程
linux·运维·chrome
Wave84525 分钟前
嵌入式底层核心架构详解 (Cortex-M3)
stm32·架构
渡己之道36 分钟前
笔记-lvgl移植到stm32f407
c语言·笔记·stm32
Lumos_77741 分钟前
Linux -- 共享内存
java·linux·运维
李日灐42 分钟前
<5> Linux 开发工具:包管理 + Vim 实操 + GCC 编译流程 + 静态与动态链接详解
linux·运维·服务器·面试·vim·gcc