RT1170启动详解:Boot配置、Bootable image头的组成

news2025/1/10 23:49:25

文章目录

  • 1 基础知识
  • 2 BOOT配置
    • 2.1 BOOT_CFG配置
    • 2.2 BOOT_MODE
  • 3 Bootable image
    • 3.1 文件格式
    • 3.2 Bootable image头的组成
    • 3.3 Bootable image的生成
    • 3.4 例:BootROM之non-XIP加载过程
    • 3.5 例:bin文件分析

1 基础知识

(1)BootROM
BootROM(ROM Bootloader)是芯片在出厂前固化在ROM里的一段Bootloader程序。每次上电的时候都将执行里面的代码,它完成了对于特定引脚上的FlexSPI、SEMC和SDHC接口的初始化,并从这些接口连接到的Flash和RAM中引导程序启动。
当然,对于BootROM来说,它还可以通过IVT中相关字段的配置完成程序的加密和解密等操作,这个将在后续介绍。
(2)Flashloader
Flashloader是一个RT1170的工程。对于BootROM来说,它主要是完成对于程序的启动功能。而对于Flashloader来说,它实现了一些Flash的擦除和烧写函数,当然还有基于熔丝的读取和烧录、加解密等功能。这些功能之所以没有在BootROM中实现,我想大概率是基于成本考虑而决定的。

  • 用户可以通过USB1或LPUART1与BootROM和Flashloaer进行通信

(3)eFuse
eFUSE是I.MXRT1170内嵌的一块OTP(One time Programmable) memory,初始状态下所有bit均为0,仅能被烧写1次。RT1176的eFUSE有8Kbit,分为32个Bank,每个Bank有8个word(1个word为4字节),即32字节。下图0~0x8F为eFUSE的bank word索引地址(index地址)。
在这里插入图片描述
这里不详细对eFuse进行介绍,简单地说一下:

  • eFuse中部分位的定义在参考手册26.2 Boot Fusemap中有介绍,对于所有位的介绍,比如加密启动的一些字段,需要参考Secure Reference Manual,这个手册需要找FAE要,自己是下载不了的。
  • eFuse除了有OTP特性外,还有Lock特性,它包含三层:写保护、覆盖保护和访问保护
  • eFuse空间有两类:一类受冗余保护(牺牲一半的空间保存数据的备份以防止数据损坏),一类受ECC保护(可纠正损坏位)
  • eFuse空间的读写由RT1170中的OCOTP控制器来实现,如果想要修改eFuse,用户可以参考SDK中OCOTP相关代码自己来实现。也可以通过集成了eFuse烧写的工具:blhostsdphostMCUBootUtility(通过Flashloader)来修改。

(4)从外部存储器启动

(1)NOR Flash:可以XIP执行,但也需要BootROM引导完成Nor的初始化及XIP相关配置

(2)Nand Flash:无法XIP执行,由BootROM从Nand拷贝代码到RAM中执行

(3)SDRAM与SRAM:SRAM挂在系统BUS上,无需初始化;而SDRAM挂载存SEMC控制器上,需要初始化。在BootROM中,可以通过DCD字段对SDRAM进行初始化。

2 BOOT配置

2.1 BOOT_CFG配置

前面我们知道,BootROM可以帮助我们从外部存储器中启动程序。但是BootROM需要知道一些信息:启动设备连接在从哪个FlexSPI接口,这个接口上接的是Nand还是NOR或者是EMMC等设备,还有是否需要加密启动等信息。这些信息就BOOT_CFG引脚来告诉BootROM,这些引脚在硬件上也是固定的,如下图所示。
在这里插入图片描述

  • 引脚的具体含义,参考手册10.6 Boot Device章节。对于不同的外部存储器,引脚的定义都不相同。这个章节对于BOOT_CFG的介绍实际是eFuse BOOT_CFG相关位的定义,但这和GPIO BOOT_CFG的定义是相同的。这是因为eFuse中有和GPIO的BOOT_CFG相同的定义的位,在eFuse中的BT_FUSE_SEL位置1时,将使用eFuse中的BOOT_CFG配置。

2.2 BOOT_MODE

对于I.MXRT1XXX系列单片机来说,上电永远是从BootROM开始启动,而用户可以通过BOOT_MODE[1:0]决定BootROM程序的不同行为模式。这两个字段由硬件进行配置,它们所对应的引脚是固定的:
在这里插入图片描述
总共有四种不同的启动方式,如下图所示:
在这里插入图片描述
1、Boot From Fuses模式
在这个模式下,将根据Fuse里的Boot配置来决定从哪个外部存储器Boot,如下图所示。
在这里插入图片描述
由上图可以看出:

Internal BootBoot from Fuses
BT_FUSE_SEL=0BOOT_CFG从GPIO相关引脚中获取从USB的Serial Loader启动(通过USB传输程序)
BT_FUSE_SEL=1BOOT_CFG从eFuse相关字段中获取BOOT_CFG从eFuse相关字段中获取

2、Serial Downlaoder模式
在此模式下,用户可以与参考手册中指定引脚连接的UART或USB与BootROM进行通信,从而接收程序并在SRAM中运行。该模式主要用来从SRAM中启动Flashloader,用户可以将Flashloader程序烧录,然后与Flashloader进行通信,通过Flashloader里面的函数来对Flash、eFuse等内容进行修改。

  • Serial Downloader模式的通讯遵从一定的协议,NXP官方提供了几个相关的工具可用于此通信:sdphost.exemfgtoolMCUBootUtility

3、Internal Boot模式(Serial NOR/NAND、Parallel NOR/NAND、SD/eMMC、1bit Recovery SPI NOR)
该模式支持从串行/并行的NOR/NAND Flash、SDCard、EMMC和带1位恢复位的Recovery SPI NOR中启动,这是最常使用的一种启动模式。
在这个模式下,也会参考eFuse中的BT_FUSE_SEL位来使用不同的配置:
BT_FUSE_SEL=0:BootROM将使用BOOT_CFG[x:0] pins 的配置
BT_FUSE_SEL=1:BootROM将使用Fuse中的配置

  • 我们可以在确定了启动设备后,将BT_FUSE_SEL烧录为1,然后将GPIO已经测试过没有问题的BOOT_CFG位烧录到eFuse中对应的BOOT_CFG位中,这样启动设备就不可能被硬件上更改了。
  • 如果Internal Boot失败,比如用户的BOOT_CFG配置有错,系统将进入Serial Downlaoder模式。

3 Bootable image

前面BootROM帮我们初始化了外部的存储器,可以从里面获取到我们写的程序。但是程序的大小是多少、需要链接到哪里运行呢?这就需要我们在生成的程序最前面加一个头来让BootROM知道这些信息,从而完成程序的拷贝和跳转。

3.1 文件格式

对于不同的IDE来说,编译后生成的程序的文件格式都不太一样,常见的有以下几种:

  • AXF:用于基于ARM的微控制器。它包含可执行代码、数据和调试信息。AXF文件通常在开发和调试过程中使用
  • HEX:由十六进制数及其对应的内存地址组成,可以将程序解析和编程到目标设备的内存中
  • S19:以特定格式的ASCII字符表示二进制数据。S19文件包含数据和内存地址,常用于编程旧的微控制器和EEPROM
  • ELF:包含可执行代码、数据和其他加载和执行程序所需的信息,可用于调试、分析和部署到目标设备
  • SREC:类似于S19的文件格式。它以ASCII字符表示二进制数据,但遵循不同的格式
  • BIN:BIN文件是直接包含可执行机器代码的二进制文件。它们通常用于以原始二进制格式存储最终编译的代码。

不管什么格式,都是为不同下载器或者调试而服务的,经过解析后下载进MCU内部FLASH的数据还是bin格式。

3.2 Bootable image头的组成

以下偏移均以NOR Flash为例,对于Nand Flash来说,有略微的不同,但大致相同。
1、FCB(FlexSPI Configuration Block):偏移0x400
可选,用于Serial/Parallel NOR FLASH。其数据结构随着Flash的接口的不同而不同,用来存储FLASH的特性参数。因为BootROM需要兼容不同的Flash,所以BootROM上电会使用比较通用的、低速的配置来初始化FLASH。那如果我们希望Flash能工作在更高的频率下,就可以通过此字段保存配置信息,BootROM会根据此字段重新配置Flash。
2、IVT(Image Vector Table):偏移0x1000
必选的与FLASH无关的structure,IVT中记录了Application、DCD、BD、CSF的位置信息,与BootROM加载启动有关。IVT大小固定为32byte,数据结构如下:

typedef struct _ivt_
{
    uint32_t hdr;
    uint32_t entry;
    uint32_t reserved1;
    uint32_t dcd;
    uint32_t boot_data;
    uint32_t self;
    uint32_t csf;
    uint32_t reserved2;
} ivt;

具体每个字段的含义后面实例分析时会解释,有实例也更好理解。
3、BD(Boot Data):偏移0x1020

必选的与FLASH无关的structure,BD中记录了Bootable image的起始地址与总长度,其大小固定为16byte,数据结构如下:

typedef struct _boot_data_
{
    uint32_t start;       /* boot start location */
    uint32_t size;        /* size */
    uint32_t plugin;      /* plugin flag - 1 if downloaded application is plugin */
    uint32_t placeholder; /* placehoder to make even 0x10 size */
} BOOT_DATA_T;

4、DCD(Device Configuration Data)

可选的用于初始化SEMC接口的配置信息,主要用于SDRAM的初始化,它由寄存器地址和数据对组成,有三种指令类型:写指令、检查指令和空指令。可以在MCUXPresso IDE中配置DCD字段:
在这里插入图片描述

  • 可以看到是可以初始化任意寄存器的值的,所以还可以用来初始化HyperRAM
  • Bootable image中还有一个XMCD字段可以用来对HyperRAM进行初始化,具体参考reference manual

5、Application Binary:偏移0x2000
即用户编译出的程序,偏移位置固定为0x2000。
6、CSF(Command Sequence File)
主要用于安全启动的认证相关特性。
7、KeyBlob
主要用于安全启动的加密相关特性。

  • 对于安全启动加密相关内容,将在后续博客中介绍

3.3 Bootable image的生成

(1)IDE:MCUXPresso IDE、IAR、Keil
通过在链接脚本中声明IVTBoot DataDCD等段,然后在C文件中声明其数据结构对应的结构体,再用attribute关键字将对应结构体变量链接到指定段中。

  • 注意需要打开一些宏定义,如使用DCD,则需要声明XIP_BOOT_HEADER_ENABLE = 1

(2)elftosb.exe
elftosb.exe是NXP提供的一个软件,可以用来生成Bootable image,当然还有一些其它的功能,比如生成可以与Flashloader能识别的指定协议的镜像文件,可以实现修改eFuse、烧录Flash、AES固件加密等功能。
对于生成Bootable image,其命令格式固定如下:

elftosb.exe -f imx -V -c config_application.bd -o ivt_application.bin application.out
  • ivt_application.bin:最终生成的Bootable image

  • application.out:编译链接生成的ELF文件

  • config_application.bd:用户配置文件

.bd指示elftosb如何在binary基础上添加IVTBD等其他信息数据从而形成Bootable image,在Flashloader目录下给了很多bd文件示例,只需在某一个bd文件基础上修改即可
(3)MCUBootUtility
自动检测有没有IVT、BD头,没有的话将根据镜像文件自动填充该字段。

3.4 例:BootROM之non-XIP加载过程

假设程序保存在Nand Flash,然后要在ITCM(0x00000000~0x20000000)运行,下图显示了BootROM加载image的四个阶段:
(1)Bootable image存储在Nand Flash中
(2)BootROM从Nand Flash读取Bootable image前4KB(包含IVTBD)数据到OCRAM(0x20240000~0x202C0000)
(3)为了避免重复读取,BootROM会把读取的4KB数据先复制到ITCM
(4)BootROM根据IVTBD的字段,获得程序的偏移和大小,将剩下的image从Nand Flash中读到ITCM
在这里插入图片描述

3.5 例:bin文件分析

以NOR Flash,程序XIP执行为例,对SDK中的evkmimxrt1170_freertos_hello_cm7编译生成的bin文件进行分析:
1、FCB(FlexSPI Configuration Block):偏移0x400
可选的,格式参考手册10.6.3 Serial NOR and NAND Configuration based on FlexSPI Interface,主要是Flash一些参数的声明、时钟频率的初始化还有保存Flash读写时序的FlexSPI LUT(Look Up Table)
在这里插入图片描述

2、IVT(Image Vector Table):偏移0x1000
在这里插入图片描述
其中TAG为d1,IVT Length为0x2000,version为0x41,entrypoint Address为0x300024e9(Reset_ISR的地址),DCD的绝对地址为0x30001030,Boot Data链接地址为0x30001020,IVT链接地址为0x30001000

3、BD(Boot Data):偏移0x1020
在这里插入图片描述
其中镜像的绝对起始地址为0x30000000,程序镜像的大小为0x1000000(实际保存的是Flash的大小)。
4、DCD:偏移0x1030
在这里插入图片描述
前面在IVT中指定了DCD的地址为0x30001030(绝对地址),BootROM就会从这个地址读取DCD。其中Tag为0xd2;整个DCD的长度为0x4b8(这个大小为大端存储),即结束地址为0x14E8;版本为0x41。也就是说从0x1040~0x14E8就是DCD配置字段。

  • 前面有提到,XMCD可以用来hyperRAM,实际上是将其FlexSPI配置块FCB填充到0x1040处,也就是说BootROM不能同时初始化DCD和XMCD字段。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/580706.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

地面分割--Patchwork

文章目录 1问题定义2同心区域模型3按照区域划分的平面拟合4地面点似然估计(GLE)总结 patchwork是一种比较优秀的地面分割方法。其过程主要分为三个部分:同心圆环区域(CZM:concentric Zone Model),按照区域划分的平面拟合(R-GPF:re…

OpenCV基础操作(5)图像平滑、形态学转换、图像梯度

import numpy as np import cv2 as cv from matplotlib import pyplot as plt一、图像平滑 1、2D卷积 我们可以对 2D 图像实施低通滤波(LPF),高通滤波(HPF)等。 LPF 帮助我们去除噪音,模糊图像。HPF 帮助…

【数字信号处理】Goertzl算法详解推导及双音多频(DTMF)信号检测

Geortzel算法 【要点解析】 根据卷积公式 y ( n ) = ∑ m = − ∞ ∞ x ( m )

前端切图仔跑路真经

一、闭包 谈到闭包,我们首先要讨论的就是作用域。 1、作用域: 是指程序源代码中代码定义的范围。规定了如何设置变量,也就是确定了当前执行代码对变量的访问权限。 JavaScript采用词法作用域,也就是静态作用域,就是在…

直接带你使用 FreeRTOS 的 API 函数(基于 CubeMX 生成)(不断更新)

作者有话要说 对于这个越来约浮躁的社会,什么都要钱,特别是网上那些垃圾教程,越听越模糊,那行吧,我直接就从 FreeRTOS 的 API函数 学起,管你这么多底层内容的,以后再说吧!&#xff0…

[中间件漏洞]apache漏洞复现

目录 apache未知扩展名解析漏洞 漏洞复现 防范建议 AddHandler导致的解析漏洞 防范建议 Apache HTTPD 换行解析漏洞(CVE-2017-15715) 漏洞复现 防范建议 apache未知扩展名解析漏洞 Apache默认一个文件可以有多个以点分割的后缀,当最右边的后缀…

【LeetCode热题100】打卡第5天:最长回文子串

文章目录 最长回文子串⛅前言🔒题目🔑题解 最长回文子串 ⛅前言 大家好,我是知识汲取者,欢迎来到我的LeetCode热题100刷题专栏! 精选 100 道力扣(LeetCode)上最热门的题目,适合初识…

部署OA系统

文章目录 前言一、OA系统基础1.OA系统2.魔方OA3.OA系统架构4.部署OA系统 二、使用步骤总结 前言 部署OA系统,以魔方OA为例 一、OA系统基础 1.OA系统 办公自动化(Office Automation,简称OA),是将计算机、通信等现代化…

⑥电子产品拆解分析-食物电子秤

⑥电子产品拆解分析-食物电子秤 一、功能介绍二、电路分析以及器件作用三、原理图复现与学习1、电源电路2、按键电路3、其它接口电路 一、功能介绍 ①高精度0.1g称重;②内置锂电池和外加2个7号电池超长续航;③可进行克和盎司单位称重;④一键智…

Flask or FastAPI? Python服务端初体验

1. 引言 最近由于工作需要,又去了解了一下简单的python服务搭建的相关工作,主要是为了自己开发的模型或者工具给同组的人使用。之前介绍的针对于数据科学研究比较友好的一个可以展示的前端框架Streamlit可以说是一个利器。不过,随着ChatGPT的…

由前序和中序创建二叉树

算法分析 首先,前序是按照 根 -> 左子树 -> 右子树 这样的顺序来进行访问的,也就是说,前序给出的顺序一定是先给出根结点的,那么我们就可以根据前序的顺序来依次递归判断出每个子树的根结点了。 如下所示: 我…

源码角度分析多线程并发情况下数据异常回滚方案

一、 多线程并发情况下数据异常回滚解决方案 在需要多个没有前后顺序的数据操作情况下,一般我们可以选择使用并发的形式去操作,以提高处理的速度,但并发情况下,我们使用 Transactional 还能解决事务回滚问题吗。 例如有下面表结…

Go语言并发

Go语言并发学习目标 出色的并发性是Go语言的特色之一 • 理解并发与并行• 理解进程和线程• 掌握Go语言中的Goroutine和channel• 掌握select分支语句• 掌握sync包的应用 并发与并行 并发与并行的概念这里不再赘述, 可以看看之前java版写的并发实践; 进程和线程 程序、进程…

C语言3:根据身份证号输出生年月日和性别

18位身份证号码第7到10位为出生年份(四位数),第11到12位为出生月份,第13 到14位代表出生日期,第17位代表性别,奇数为男,偶数为女。 用户输入一个合法的身份证号,请输出用户的出生年月日和性别。(不要求较验…

Java数据结构之第十三章、字符串常量池

目录 一、创建对象的思考 二、字符串常量池(StringTable) 三、再谈String对象创建 一、创建对象的思考 下面两种创建String对象的方式相同吗? public static void main(String[] args) {String s1 "hello";String s2 "hello";String s3 …

C# | 线性回归算法的实现,只需采集少量数据点,即可拟合整个数据集

C#线性回归算法的实现 文章目录 C#线性回归算法的实现前言示例代码实现思路测试结果结束语 前言 什么是线性回归呢? 简单来说,线性回归是一种用于建立两个变量之间线性关系的统计方法。在我们的软件开发中,线性回归可以应用于数据分析、预测和…

每日一博 - 对称加密算法 vs 非对称加密算法

文章目录 概述一、对称加密算法常见的对称加密算法优点:缺点:Code 二、非对称加密算法常见的非对称加密算法优点:缺点:Code 概述 在信息安全领域中,加密算法是保护数据安全的重要手段。 加密算法可以分为多种类型&am…

【Linux】线程互斥 与同步

文章目录 1. 背景概念多个线程对全局变量做-- 操作 2. 证明全局变量做修改时,在多线程并发访问会出问题3. 锁的使用pthread_mutex_initpthread_metux_destroypthread_mutex_lock 与 pthread_mutex_unlock具体操作实现设置为全局锁 设置为局部锁 4. 互斥锁细节问题5.…

哈夫曼树(Huffman)【数据结构】

目录 ​编辑 一、基本概念 二、哈夫曼树的构造算法 三、哈夫曼编码 假如<60分的同学占5%&#xff0c;60到70分的占15%…… 这里的百分数就是权。 此时&#xff0c;效率最高&#xff08;判断次数最少&#xff09;的树就是哈夫曼树。 一、基本概念 权&#xff08;we…

Zabbix4.0 自动发现TCP端口并监控

java端口很多&#xff0c;每台机器上端口不固定&#xff0c;考虑给机器配置组不同的组挂载模版&#xff0c;相对繁琐。直接使用同一个脚本自动获取机器上java相关的端口&#xff0c;推送到zabbix-server。有服务端口挂了自动推送告警 一、zabbix-agent配置过程 1、用户自定义参…