截止目前為止 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 啟動,痞子衡下篇文章接著聊。