截止目前为止 i.MX RT 系列已开始供货的芯片有两款 i.MXRT105x, i.MXRT102x,所以本文的研究对象便是这两款芯片,从参考手册来看,这两款芯片的 BootROM 功能差别不大,所以一篇文章可以概括这两款芯片的 BootROM 特性。
一、Boot 基本原理
1.1 从内部 FLASH 启动
Boot 是任何一款 MCU 都有的特性。提及 Boot,首先应该联想到的是 FLASH,通常 Cortex-M 微控制器芯片内部一般都会集成 FLASH(从 FLASH 分类上来看应该属于 Parallel NOR FLASH),你的 Application 代码都是保存在 FLASH 里,每次上电 CPU 会自动从 FLASH 里获取 Application 代码并执行,这个行为就是 Boot。
大家都知道,ARM Cortex-M 内存使用的是统一编址,32bit 总线的地址空间是 4GB (0x00000000 - 0xFFFFFFFF)。打开最新的 Arm®v6/7/8-M Architecture Reference Manual 手册找到如下 system address map 表,你会发现 ARM 已经将这 4GB 空间内容给初步规划好了,各 ARM Cortex-M 微控制器厂商在设计芯片时一般都会遵守 ARM 规定。
从上述 system address map 表中我们可以知道,ARM 4GB 空间的前 512MB(0x00000000 - 0x1FFFFFFF)规划为非易失性存储器空间。看到这,你是不是明白了为啥各大厂商生产的 Cortex-M 芯片内部 FLASH 地址总是从 0x0 开始,因为仅含 FLASH 的芯片上电启动默认都是从 0x0 地址开始获取 Application 的初始 PC 和 SP 开始 Boot。
1.2 BootROM 是什么
大家是不是也会经常在芯片参考手册里看到 BootROM 的字眼,BootROM 是什么?BootROM 其实是芯片在出厂前固化在 ROM 里的一段 Bootloader 程序。这个 Bootloader 程序可以帮助你完成 FLASH 里的 Application 的更新,而不需要使用额外的外部编程 / 调试器(比如 JLink),Bootloader 一般提供 UART/SPI/I2C/USB 接口与上位机进行通信,与 Bootloader 配套使用的还有一个上位机软件,当芯片从 BootROM 启动后,通过这个上位机软件与 BootROM 建立连接,然后可以将你的 Application 代码(bin/s19/hex 格式)下载进芯片 FLASH。
BootROM 并不是每一款 MCU 都有的。以飞思卡尔 Kinetis 系列 MCU 为例,早期的 Kinetis 产品比如 MKL25 并不含 ROM,第一款支持 ROM 的 Kinetis 芯片是 2014 年推出的 MKL03,而恩智浦的 LPC 系列以及意法半导体的 STM32 系列 MCU 一般都是含 ROM 的。不同厂商芯片的 ROM 起始地址可能不一样(Kinetis ROM 一般从 0x1c000000 开始,LPC ROM 一般从 0x03000000 开始,STM32 ROM 结束地址是 0x1FFFFFFF)。
1.3 Boot Mode 选择
当芯片既有 ROM 也有 FLASH 的时候,便会出现 Boot 位置选择问题,标准术语称为 Boot Mode。芯片上电 CPU 到底是先从 FLASH 启动还是先从 ROM 启动?关于这个问题,各芯片厂商的解决方案不一样。
Kinetis 的 Boot Mode 由 FLASH 偏移地址 0x40d 处的值(上电系统会自动将这个值加载到 FTFx_FOPT 寄存器中)以及 NMI pin 共同决定。LPC 的 Boot Mode 由 ISP[1:0]以及 VBUS pins 决定。STM32 的 Boot Mode 由 BOOT[1:0] pins 决定。
下图为 MK80 的具体 Boot Mode:
下图为 LPC54114 的具体 Boot Mode:
下图为 STM32F407 的具体 Boot Mode:
1.4 从内部 SRAM 启动
SRAM 存在于任何一款 MCU 中,它除了可以保存 Application 数据变量外,当然也可以存放 Application 代码以供 CPU 执行。但是 SRAM 是易失性存储器,存放的数据断电会丢失,所以从 SRAM 启动跟从 FLASH/ROM 启动性质不一样。
从 FLASH/ROM 启动属于一级启动,不依赖除了 Boot Mode 选择之外的条件;而从 SRAM 启动属于二级启动,其需要外部引导一下才能完成。外部引导的方式有两种:一是借助于外部调试器,直接将 Application 下载进 SRAM 并将 PC 指向 Application 开始执行,其实这就是所谓的在 SRAM 调试;二是借助于 FLASH/ROM 中的 Bootloader 程序,Bootloader 会将存放在 FLASH(或其他非易失性存储器,或者从上位机直接接收)中的 Application 先加载到 SRAM 里然后 Jump 过去执行。
1.5 从外部存储器启动
有些 MCU 并没有内部 FLASH,所以会支持外接存储器,常见的外部存储器有 QSPI NOR/NAND, SD/eMMC, SDRAM, Parallel NOR/NAND, SPI/I2C EEPROM 等,MCU 内部集成相应的存储器接口控制器,通过接口控制器可以轻松访问这些外部存储器。一个没有内部 FLASH 的 MCU 肯定会有 ROM(BootROM),因为必须要借助 BootROM 才能 Boot 存储在外部存储器的 Application,所以从外部存储器启动也属于二级启动。
那么怎么理解从外部存储器启动?需要弄明白以下几个问题:
第一个问题:从外部 NOR FLASH 存储器启动(比如 QSPI NOR/Parallel NOR/EEPROM)跟从内部 FLASH 启动有什么区别?最大的区别是从外部 NOR FLASH 启动本质上属于二级启动,其无法像内部 FLASH 那样直接启动,需要由 Bootloader 引导。即使技术上可以做到存储在外部 NOR FLASH 里的 Application 能够原地执行(XIP),但也需要 Bootloader 完成外部 NOR FLASH 的初始化以及 XIP 相关配置。
第二个问题:从外部 NAND FLASH 存储器启动(比如 QSPI NAND/Parallel NAND/SD/eMMC)跟从 NOR FLASH 启动有什么区别?最大的区别是 NAND FLASH 无法像 NOR FLASH 那样可以 XIP 执行,这是由 NAND FLASH 原理决定的,因为 NAND FLASH 是按 Page 访问的并且允许坏块的存在,这意味着 CPU 无法直接从 NAND FLASH 取指和执行,必须先由 Bootloader 将存放在 NAND FLASH 中的 Application 先全部拷贝到内部 SRAM 中,然后从 SRAM 启动执行。
第三个问题:从外部 SDRAM 存储器启动跟从内部 SRAM 启动有什么区别?这里其实区别倒不大,两个都是易失性存储器,都无法直接启动,不过 SRAM 是直接挂在系统 bus 上,而 SDRAM 是挂在存储器接口控制器上,而后者需要 Bootloader 去做初始化。
二、i.MXRTyyyy Boot
在第一部分里讲了 Boot 基本原理以及各种 Boot 方式,那么 i.MXRT Boot 到底属于哪一种?在回答这个问题之前我们先看一下 i.MXRT102x 的 system memory map(i.MXRT105x 也类似,区别是 ITCM/DTCM/OCRAM 的 size 是 512KB)。
从 memory map 里可以看到,i.MXRT 支持存储类型一共有三种:一是 96KB 的 ROM(即 BootROM)、二是总容量 3*256KB 的 RAM(OCRAM/DTCM/ITCM)、三是分配给外部存储器接口控制器(SEMC/QSPI)的 2GB 区域。看到这里你应该明白了,i.MXRT Boot 方式主要是借助 BootROM 从外部存储器加载 Application 到内部 SRAM/ 外部 SDRAM/ 原地 XIP 执行。
那么 i.MXRT 到底支持从哪些外部存储器加载启动呢?翻看 i.MXRT 的参考手册里的 System Boot 章节,可以看到 i.MXRT 启动支持以下 6 种外部存储器:
Serial NOR Flash via FlexSPI
Serial NAND Flash via FlexSPI
Parallel NOR Flash via SEMC
RAW NAND Flash via SEMC
SD/MMC via uSDHC
SPI NOR/EEPROM via LPSPI
其中 Serial/Parallel NOR 这两种 Device 可以 XIP,其他 4 种 Device 无法 XIP,需要拷贝到内部 RAM 或外接 SDRAM 里运行。关于具体如何从这 6 种 Device 启动,痞子衡下篇文章接着聊。