目录
imx-RT是恩智浦新出的一款基于M7内核的芯片,其特点是高性能,低售价。
目前是MCU市场上一款炙手可热的芯片。
本文针对RT ROM做一些介绍。
具体内容如下:
Boot流程
各种类型的boot
image架构
ROM Boot process
Get boot mode
上电后,Boot_mode拨码的值会自动加载到SBMR2寄存器中,ROM读取SBMR2[25:24]来决定boot_mode
RT支持四种启动模式
- Boot from fuse。 根据fuse中的boot device进行boot
- Serial download。 ROM进入detect mode,等待上位机跟ROM通信。
- internal boot。 根据boot device拨码进行boot
- Test mode。 ROM will run into loop
- ROM读取SBMR2
#define HAPI_SRC_get_bootmode() ((SRC->SBMR2 & SBMR2_BMOD_MASK) >> SBMR2_BMOD_SHIFT)
SRC->SBMR2右移24位截取bit[25:24]得到boot_mode
读取fuse,确定HAB是否使能
hab_rvt.report_status(&hab_config, NULL);
HAB - high assurance boot.
一旦开启HAB,签名的image需要ROM认证后才能boot。
Get boot device
ROM支持的boot device有flexspi nand
、flexspi nor
、SEMC nand
、SEMC nor
、SD
、EMMC
、EEP
如果BT_FUSE_SEL没有烧写,boot device拨码的值会加载到SBMR1寄存器中。
否则,fuse 0x450关于boot device的值会加载到SBMR1中
ROM根据SRC->SBMR1寄存器的值来判断boot device- Boot device初始化代码
pu_irom_setup_boot_selection();
Boot device拨码
讲到这里,我们来回顾下。
首先,上电后板子会自动将boot_mode的信息加载到SBMR2寄存器中。将boot_device的值加载到SBMR1中
关于boot device分两种情况。
- 如果BT_FUSE_SEL 没有烧写,boot_device的值从拨码加载
- 如果烧写了BT_FUSE_SEL,boot_device的值从fuse加载。
ROM会根据SBMR2中的信息来确定boot mode,然后根据SBMR1中值确定boot device
从对应的device boot或者进入相应的boot mode
Boot类型综述
Primary boot
FlexSPINor\Nand boot,SD\EMMC boot
FlexSPI nor可以选择XIP boot。其他的device都是Non-XIPboot。。即image需要从boot device中搬到RAM中执行
Nand支持redundant boot,最多给4次boot机会
SD、EMMC支持secondary boot,在offset 0x200处重新制定image的存储架构。EMMC支持fast boot
Redundant boot
primary boot失败后进入redundant boot。只有烧写了支持redundant boot的fuse后,才能进入此种boot。Boot device一般都是EEPROM
MFG boot
如上boot 失败后,会从SD卡中尝试最后一次boot。
Plug-in boot
ROM支持的boot device只有flexspi nand\nor等等。。但是想要支持其他的boot device,比如从USB boot的话ROM是否支持呢。Plug-in boot的存在目的就是如此。
plug-in boot的话需要两个image。
一个image存在ROM支持的boot device上,这个image的目的是用来初始化USB,将USB的数据读取到RAM中。
第二个image存储在USB中,这个就是用来boot的image
Primary boot
- 支持XIP的device,FlexSPI nor, SEMC nor
以FlexSPI nor为例,ROM从0x60000000处读取12K数据。从0x60001000处获取IVT,根据IVT中的boot data进行数据处理。如果boot image运行地址在nor上,则进行XIP。否则将image copy到ram中boot - 不支持XIP的device,FlexSPI nand等
ROM从device中读取2K数据到0x20208000处,然后从0x20208400处获取IVT。根据IVT中的boot data将boot image coppy对应的运行地址进行boot
Redundant boot
- nand 支持redundant boot。给4次boot机会
- NAND FCB会制定image的存储,备份信息。
- ROM根据FCB找到对应的block,根据IVT将image复制到对应的运行地址。如果boot失败,ROM会根据FCB查找下一个备份的image,然后进行boot
- redundant register用来标记当前是第几次boot。 Bit[23:22]= 0b00表示第一份image,以此类推。
UINT32 redundant_boot = get_persist_redundant_boot_value();
while (++redundant_boot <= REDUNDANT_IMG_IDX_MAX)
{
/* Set secondary image persistent bit /
set_persist_redundant_boot_value(redundant_boot);
/ Add secondary image log entry /
pu_irom_log_add((pu_irom_log_entry_t)(ROM_LOG_PRIM_IMAGE_SELECT + redundant_boot));
/ Try download secondary image /
if (download_initial_image() == TRUE)
{
/ Update data_ptr on success /
data_ptr = (hab_ivt_v0_t )((UINT32)driver_data->initial_image_address + driver_data->ivt_offset);
break;
}
}
Secondary boot
- SD emmc支持secondary boot。Normal boot制定image base address为0x0,IVT offset为0x400.ROM会从0x0处读取数据,抓取0x400处的IVT来得到boot information。
Secondary boot table位于offset0x200处。ROM第一次从0x400获取IVT后,如果boot失败,则从0x200处获取table,table中可以重定义image base address为firstSectorNumber。那么ROM就会从firstSectorNumber处获取image。
举例说明:
结构体里面的数据是小端模式。
SD\EMMC 一个block的长度为0x200
Tag : 0x00112233
FirstSectorNumber :
EMMC的image start address = 0x8000 IVT offset = 0x400
Table address = 0x200
设定secondary start address为0x9000,则firstSectorNumber为:
(0x9000-0x8000) /0x200 = 8
secondary table如下
- typedef struct
- {
- UINT32 chipNum; /* Chip Select, ROM does not use it */
- UINT32 driveType; /* Always system drive, ROM does not use it */
- UINT32 tag; /* Tag, must be 0x584D2E69 (i.MX) */
- UINT32 firstSectorNumber; /* Block address of secondary image, block size is 512B */
- UINT32 sectorCount; /* Not used by ROM */
- } SECONDARY_IMG_TBL_T;
Recovery boot
使能这个fuse即可。如果promary boot失败,ROM会从recovery boot device中进行boot。
EEPROM_RECOVERY_EN
MFG boot
所有primary、recovery boot失败后,从SD boot。
Plugin boot
这个boot类型是为了满足ROM从不支持的device中boot。
- 当配置IVT中BootData的plugin为1时。bootRom支持boot plugimage
- Plug-in boot需要两个image
- 供ROM boot的image,IVT, base address等都需要根据ROM的规定制定。此处的image就是没有使用plug in功能时的boot image。
只不过这个image的功能不是我们常用的点灯,而是将IVT,base address,image length指向plug in image。如果有需要的话,还需要对存放plugin image的设备进行初始化 - plug-in image
当1中的image制定了plug-in image的base address, IVT offset, image length后。BOOTROM对这个image认证后,执行此image
- 供ROM boot的image,IVT, base address等都需要根据ROM的规定制定。此处的image就是没有使用plug in功能时的boot image。
示例
依照ROM的规则做第一个image
- int main(uint32_t **start, uint32_t *bytes, uint32_t *ivt_offset)
- {
- *start = (uint32_t *)0x60004000;
- *bytes = 0x5000;
- *ivt_offset = 0x1000;
- return 1;
- }
第二个image的功能为点灯,image中断向量地址为NOR中的0x60006000。给这个image加上IVT,IVT的存储地址设置为0x60005000,image的base address设置为0x60004000
将第一个image烧写到0x6000000处,第二个image烧写到0x60004000处。reset 板子,plug-in boot即可成功。
我们来分析下image是如何运行的。
- 上电后,ROM从0x60000000处找image,0x1000处的IVT中查找到plug-in flag打开。
- ROM运行这个image。这个image的作用是告诉ROM plug-in image存储在0x60004000处。
- 然后ROM从0x60004000处查找image,0x60005000处获取IVT,然后进行boot。
Serial download
ROM 进到这个模式后,会等待上位机通讯。支持USB跟UART。
可以通过SD\P_host上位机的write_filem命令将image写到RAM中,然后Jump_addr命令执行image
读到这里,我们应该知道了primary boot,recovery boot,MFG boot,Plug-in boot
- primary boot中,SD、EMMC支持secondary boot。NAND 支持redundant boot。这两种boot我们都可以通过persist register来查看使用第几份image进行boot。
- recovery boot是在primary boot失败后的一种boot,需要开启recovery boot的fuse
- MFG boot呢,就是如上如上两个boot都失败,ROM给与的最后一次boot。它从SD boot
- plug-in boot则是为了让ROM支持目前未曾支持的device,需要两份image。第一份image的IVT中需要开启plug-in boot flag。
我们用Nor模拟了这种boot。plug-in boot支持如上所有的boot类型 - 如果所有boot都失败的话,ROM会进入serial download等待上位机与其通信。可以使用上位机烧写image到RAM中,然后运行RAM中的image。
关于RT的boot 流程,boot类型就介绍到此。下个章节我们来谈谈image的架构,看看ROM是如何根据IVT的内容进行boot的。