0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

深入理解 RK3506 U-Boot 重定位:从代码到原理

jf_44130326 来源:Linux1024 作者:Linux1024 2025-11-28 07:05 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

嵌入式系统中,U-Boot作为引导加载程序,其启动流程的核心环节之一就是重定位(Relocation)。对于RK3506这类基于ARM Cortex-A架构的芯片,重定位的本质是将U-Boot代码从初始加载地址(通常是片内ROM或Flash)复制到运行效率更高的片外RAM,再切换执行环境到RAM中运行。

本文将结合U-Boot源码中ARM Cortex核心的启动代码,拆解RK3506平台U-Boot重定位的实现逻辑、关键步骤与底层原理。

路径:u-boot/arch/arm/cpu/armv7/start.S

wKgZPGko2kqAGNWAAAck-TkUqlU013.png

一、重定位的核心目的:为何需要“搬家”?

RK3506的U-Boot启动初期,代码通常从片内BootROMSPI Flash加载到片内SRAM(小容量高速内存)执行。但SRAM容量有限(通常仅几十KB),无法容纳完整的U-Boot镜像(包含驱动、命令、文件系统等模块),也无法满足后续加载Linux内核的需求。

重定位的核心目标:

1.释放存储空间:将U-Boot完整镜像从Flash/SRAM迁移到大容量片外DDR内存;

2.提升执行效率:DDR内存带宽更高、容量更大,支持U-Boot运行复杂逻辑(如设备初始化、内核加载);

3.预留内存空间:为Linux内核、设备树等后续加载的镜像预留连续内存区域。

二、重定位的前提:启动初期的关键初始化

在执行重定位前,U-Boot必须完成一系列底层初始化,为“搬家”做好准备。结合本文提供的ARM Cortex启动代码,这些准备工作主要集中在reset入口函数中:

1.模式与中断初始化

reset:  b  save_boot_paramssave_boot_params_ret:  /* 切换到 SVC32 模式,禁用 FIQ/IRQ */  mrs r0, cpsr  and r1, r0,#0x1f    @ 掩码模式位  teq r1,#0x1a       @ 检查是否为 HYP 模式  bicne r0, r0,#0x1f    @ 清除模式位  orrne r0, r0,#0x13    @ 设置为 SVC 模式(管理模式)  orr r0, r0,#0xc0     @ 禁用 FIQ (0x80) 和 IRQ (0x40)  msr cpsr, r0

•切换到ARM特权模式(SVC32):确保U-Boot拥有访问系统寄存器、修改内存配置的权限;

•禁用中断:避免初始化过程中被外部中断打断,导致系统异常。

2.向量表初始化

/* 设置 VBAR 寄存器,指向 U-Boot 向量表 */ldr r0, =_startmcr p15,0, r0, c12, c0,0 @ 写入VBAR(向量表基地址寄存器)

•ARMv7架构通过VBAR寄存器指定异常向量表地址;

•重定位前,向量表位于初始加载地址(如SRAM),后续重定位后需确保向量表地址同步更新(由链接脚本配合处理)。

3.缓存与MMU初始化(cpu_init_cp15

重定位前需禁用MMU(内存管理单元)和缓存,避免地址映射干扰内存复制:

ENTRY(cpu_init_cp15) /* invalidate L1 I/D 缓存、TLB */  mov r0,#0  mcr p15,0, r0, c8, c7,0 @ invalidate TLBs  mcr p15,0, r0, c7, c5,0 @ invalidate I-cache /* 禁用 MMU、缓存相关配置 */  mrc p15,0, r0, c1, c0,0  bic r0, r0,#0x00002000  @ 清除 V 位(向量表地址偏移)  bic r0, r0,#0x00000007  @ 清除 CAM 位(缓存相关)  orr r0, r0,#0x00000800  @ 启用 BTB(分支预测)#ifdef CONFIG_SYS_ICACHE_OFF  bic r0, r0,#0x00001000  @ 禁用 I-cache#else  orr r0, r0,#0x00001000  @ 启用 I-cache(重定位后生效)#endif  mcr p15,0, r0, c1, c0,0

•初始化CP15寄存器(ARM系统控制寄存器),清空缓存和TLB(地址转换缓存);

•禁用MMU:此时CPU访问的是物理地址,确保内存复制过程中地址无映射偏差;

•按需启用I-cache(指令缓存):重定位后代码在DDR中运行时,缓存可提升执行效率。

4.板级底层初始化(cpu_init_crit

ENTRY(cpu_init_crit) b lowlevel_init    @ 跳转到板级初始化ENDPROC(cpu_init_crit)

•lowlevel_init是RK3506平台的板级初始化函数(由瑞芯微适配);

•核心任务:初始化DDR内存控制器、配置PLL时钟(提升DDR带宽)、初始化SPI Flash等外设;

•关键:只有完成DDR初始化,U-Boot才能将自身复制到DDR中,这是重定位的硬件基础

三、重定位的核心实现:_main函数的“搬家”逻辑

当底层初始化(尤其是DDR初始化)完成后,代码通过bl _main跳转到U-Boot核心初始化流程,重定位的核心逻辑就在_main函数中(位于common/main.c)。

结合RK3506的平台特性,_main函数中重定位的关键步骤如下:

1.确定重定位地址(链接脚本定义)

U-Boot的重定位目标地址由链接脚本(如arch/arm/cpu/armv7/rk3506/u-boot.lds)定义,核心符号:

•_start:U-Boot初始加载地址(SRAM或Flash地址);

•__image_copy_start:镜像复制起始地址(初始加载地址的代码段起始);

•__image_copy_end:镜像复制结束地址;

•__bss_start/__bss_end:BSS段起始/结束地址(重定位后需清零);

•CONFIG_SYS_TEXT_BASE:重定位目标地址(RK3506通常配置为DDR起始地址,如0x80000000)。

2.内存复制:从初始地址到DDR

重定位的核心操作是逐字节复制U-Boot镜像到DDR目标地址,代码逻辑简化如下:

// 简化自 common/main.cvoid_main(void) { // 1. 获取链接脚本定义的地址符号 externulong__image_copy_start, __image_copy_end; externulong__bss_start, __bss_end; ulongdst = CONFIG_SYS_TEXT_BASE; // 重定位目标地址(DDR) ulongsrc = (ulong)&__image_copy_start; // 源地址(SRAM/Flash) // 2. 只有当源地址 != 目标地址时,才需要复制(避免自身覆盖) if(src != dst) {    memcpy((void*)dst, (void*)src, &__image_copy_end - &__image_copy_start);  } // 3. 清零 BSS 段(未初始化全局变量)  memset((void*)&__bss_start,0, &__bss_end - &__bss_start); // 4. 跳转到 DDR 中的 U-Boot 继续执行  board_init_f_r_trampoline(dst);}

复制范围:从__image_copy_start到__image_copy_end,包含代码段(.text)、数据段(.data)等已初始化部分;

避免自身覆盖:若源地址与目标地址重叠(如部分SRAM与DDR地址重叠),U-Boot会先复制不重叠部分,再处理重叠区域,防止复制过程中覆盖未复制的代码;

BSS段清零:BSS段存储未初始化全局变量,C语言标准要求其初始值为0,因此重定位后需手动清零。

3.跳转至DDR执行:地址切换

复制完成后,通过board_init_f_r_trampoline函数跳转到DDR中的U-Boot代码继续执行。此时CPU执行的指令已从DDR读取,重定位完成。

4.栈指针更新

重定位后,栈指针(SP)也需更新到DDR中的安全地址(避免使用SRAM栈导致溢出),由board_init_f函数初始化:

// 简化自 common/board_f.cvoidboard_init_f(ulongboot_flags){ ulongsp = CONFIG_SYS_INIT_SP_ADDR; // DDR 中的栈地址  sp -=sizeof(structglobal_data); // 预留全局数据结构空间  gd = (structglobal_data *)sp;  memset(gd,0,sizeof(structglobal_data)); // 初始化栈指针 asmvolatile("mov sp, %0": :"r"(sp) : "memory"); // 后续初始化:设备树加载、命令初始化、内核引导等}

•CONFIG_SYS_INIT_SP_ADDR:RK3506配置为DDR中的一段连续地址,确保栈空间足够;

•global_data:U-Boot全局数据结构,存储系统状态(如内存布局、设备信息),重定位后需在DDR中重新初始化。

四、重定位后的关键处理

1.向量表同步更新

重定位后,向量表地址需同步更新到DDR中的新地址,避免异常处理时跳转到旧地址(SRAM/Flash)。由于之前已通过VBAR寄存器设置向量表基地址为_start,而_start在重定位后指向DDR地址,因此无需额外修改(链接脚本确保_start对应DDR目标地址)。

2.缓存重新配置

重定位完成后,U-Boot会重新启用I-cache/D-cache(若配置),提升执行效率。此时MMU仍处于禁用状态(直到Linux内核启动时启用),CPU直接访问DDR物理地址。

3.避免重定位后的地址错误

•所有全局变量、函数指针均使用位置无关代码(PIC)编译,确保重定位后地址正确映射;

•链接脚本通过TEXT_BASE强制指定目标地址,确保复制后的镜像在DDR中地址对齐。

五、RK3506重定位的特殊注意事项

1.DDR初始化优先级:RK3506的DDR控制器初始化是重定位的前提,需通过lowlevel_init配置DDR时序、电压,确保DDR稳定工作;

2.Flash访问兼容性:若初始加载地址为SPI Flash(如0x10000000),复制时需通过RK3506的SPI控制器驱动读取Flash数据,再写入DDR;

3.内存布局优化:RK3506的DDR起始地址通常为0x80000000,U-Boot重定位后,会在DDR中预留后续加载Linux内核(如0x80200000)和设备树(如0x80100000)的空间,避免地址冲突。

六、总结:重定位的完整流程

RK3506 U-Boot重定位的核心是“初始化硬件→复制镜像→切换执行环境”,完整流程可概括为:

1.复位入口(reset):切换SVC模式、禁用中断、初始化向量表;

2.底层初始化:初始化CP15寄存器(缓存/ MMU)、板级硬件(DDR/PLL);

3.确定地址:通过链接脚本获取源地址、目标地址(DDR);

4.镜像复制:memcpy复制代码段/数据段到DDR,清零BSS段;

5.切换执行:更新栈指针,跳转到DDR中的U-Boot继续执行;

6.后续初始化:加载设备树、初始化外设、引导Linux内核。

重定位是U-Boot从“小容量初始环境”到“大容量运行环境”的关键一步,理解其原理不仅能帮助排查启动故障(如DDR初始化失败导致重定位失败),也能为定制化U-Boot(如调整内存布局、优化启动速度)提供基础。

对于RK3506开发者,建议结合链接脚本和lowlevel_init代码,重点关注CONFIG_SYS_TEXT_BASE和DDR初始化参数,确保重定位地址与硬件配置一致。

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • u-boot
    +关注

    关注

    0

    文章

    123

    浏览量

    39464
  • RK3506
    +关注

    关注

    0

    文章

    82

    浏览量

    716
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    如何让RK3506流畅刷图,用好RGA?

    本文基于触觉智能RK3506核心板/开发板,介绍RGAIM2D进行图像处理,包括相关编译与测试方法。
    的头像 发表于 10-29 10:00 420次阅读
    如何让<b class='flag-5'>RK3506</b>流畅刷图,用好RGA?

    2025瑞芯微开发者大会万象奥科展出RK3506邮票孔核心板

    2025瑞芯微开发者大会万象奥科展出RK3506邮票孔核心板2025年7月17-18日,第九届瑞芯微开发者大会(RKDC2025)在福州海峡国际会展中心盛大举行。本次大会以“AIoT模型创新重做产品
    的头像 发表于 10-10 14:10 1241次阅读
    2025瑞芯微开发者大会万象奥科展出<b class='flag-5'>RK3506</b>邮票孔核心板

    明远智睿 RK3506 核心板:工业物联网领域的性能 “小巨人”

    终端等领域的理想选择,为行业应用注入全新活力。 硬件设计来看,RK3506 核心板颠覆了传统核心板 “大体积、低集成” 的刻板印象。其采用新能源汽车同款的 LGA 封装技术,这一封装方式在汽车电子领域经过长期验证,具备出色的稳定性与
    的头像 发表于 09-11 18:01 627次阅读

    RK3506开发板Linux开发板极致性价比之选

    RK3506开发板Linux开发板极致性价比之选瑞芯微RK3506开发板,3核Cortex-A7@1.5GHz+Cortex-M0,Linux+RT-Thread系统支持,128MB超大
    的头像 发表于 09-11 16:26 2753次阅读
    <b class='flag-5'>RK3506</b>开发板Linux开发板极致性价比之选

    明远智睿RK3506:嵌入式领域新标杆

    嵌入式领域新标杆:RK3506开发板引领多行业应用革新 随着科技的不断进步,各行业对嵌入式系统的要求日益提高。在工业自动化精细化管控、智能家居全场景交互、智能交通协同化运行的大趋势下,嵌入式系统
    的头像 发表于 08-26 17:51 435次阅读

    【米尔RK3506国产开发板评测试用】开箱体体验

    很高兴今天收到了米尔科技的RK3506开发板,下面是开箱体验,后期的测试使用中将会做详细的测试和试用。 1.开箱,包含以下: RK3506开发板1 USB_TYPEC1 10Pin连接端子1 快速
    发表于 07-30 01:06

    有奖丨米尔 瑞芯微RK3506开发板免费试用来啦!

    米尔与瑞芯微合作发布的新品基于瑞芯微RK3506应用处理器的MYD-YR3506开发板免费试用名额增加啦
    的头像 发表于 07-10 08:03 634次阅读
    有奖丨米尔 瑞芯微<b class='flag-5'>RK3506</b>开发板免费试用来啦!

    瑞芯微RK3506 vs NXP i.MX6ULL

    在关键技术国产化浪潮中,国产芯片正以更高性能、更优成本及自主可控优势实现对海外方案的成功替代。今天触觉智能拿出自家新品瑞芯微RK3506核心板(IDO-SOM3506-S1),与线上某款热销
    的头像 发表于 06-19 16:26 938次阅读
    瑞芯微<b class='flag-5'>RK3506</b> vs NXP i.MX6ULL

    米尔瑞芯微多核异构低功耗RK3506核心板重磅发布

    近日,米尔电子发布MYC-YR3506核心板和开发板,基于国产新一代入门级工业处理器瑞芯微RK3506,这款芯片采用三核Cortex-A7+单核Cortex-M0多核异构设计,不仅拥有丰富的工业接口
    发表于 05-16 17:20

    触觉智能RK3506核心板,工业应用之RK3506 RT-Linux实时性测试

    触觉智能RK3506核心板,工业应用方案分享之RT-Linux实时性测试
    的头像 发表于 04-27 19:27 1380次阅读
    触觉智能<b class='flag-5'>RK3506</b>核心板,工业应用之<b class='flag-5'>RK3506</b> RT-Linux实时性测试

    如何用RK3506核心板自研一款嵌入式工业网关?

    飞凌嵌入式RK3506核心板做工业网关
    的头像 发表于 03-19 16:32 1786次阅读
    如何用<b class='flag-5'>RK3506</b>核心板自研一款嵌入式工业网关?

    RK3506到底有多香?抢先看核心板详细参数配置

    RK3506到底有多香?触觉智能已推出RK3506核心板,抢先了解核心板详细参数配置!
    的头像 发表于 01-18 11:33 3176次阅读
    <b class='flag-5'>RK3506</b>到底有多香?抢先看核心板详细参数配置

    RK3506各型号该怎么选?瑞芯微全新工业芯片介绍 触觉智能出品

    RK3506各型号该怎么选?瑞芯微全新工业芯片介绍,还将推出与星闪技术相结合的RK3506星闪网关开发板
    的头像 发表于 12-25 10:27 2262次阅读
    <b class='flag-5'>RK3506</b>各型号该怎么选?瑞芯微全新工业芯片介绍 触觉智能出品

    低成本解决方案,RK3506的应用场景分析!

    RK3506 是瑞芯微推出的MPU产品,芯片制程为22nm,定位于轻量级、低成本解决方案。该MPU具有低功耗、外设接口丰富、实时性高的特点,适合用多种工商业场景。本文将基于RK3506的设计特点,为大家分析其应用场景。
    的头像 发表于 12-11 15:26 2167次阅读
    低成本解决方案,<b class='flag-5'>RK3506</b>的应用场景分析!

    RK3506各型号间有什么差异?

    RK3506单板机(卡片电脑)是一款高性能三核Cortex-A7处理器,内部集成Cortex-M0核心,RK3506单板机具有接口丰富、实时性高、显示开发简单、低功耗及多系统支持等特点,非常适合于工业控制、工业通信、人机交互等应用场景。
    的头像 发表于 12-05 16:39 2553次阅读
    <b class='flag-5'>RK3506</b>各型号间有什么差异?