Introduction
Pricinple & Machenism
HA01的內(nèi)存地址空間
BOOT ROM簡介
BOOT ROM中的Bootloader執(zhí)行過程
BVT的數(shù)據(jù)結(jié)構(gòu)
Practice
源碼中關(guān)于BVT的設(shè)計
在集成開發(fā)環(huán)境中調(diào)試
Conclusion
Reference
Introduction
HA系列微控制器基于Arm Cortex-M7處理器內(nèi)核,集成了Security Boot的功能。Security Boot的關(guān)鍵代碼集成在BOOT ROM中的bootloader程序中,用戶不可見,以確保信息安全的需要。然而,開發(fā)者在自行編譯固件時,需要配合BOOT ROM中的bootloader,才能正常地引導(dǎo)到用戶應(yīng)用程序,完成啟動過程。
本文以HA系列的YTM32B1HA01微控制器(下文簡稱HA01)為例,將詳細(xì)介紹BOOT ROM中bootloader的運行機制,以及用戶程序與之對接的設(shè)計要點。
Pricinple & Machenism
HA01的內(nèi)存地址空間
從RM手冊中可以找到HA01的內(nèi)存地址空間映射表,如圖x所示。從表中可以看到,0x0000_0000開始的地址區(qū)是一塊ITCM存儲器(RAM),而存放用戶程序的pflash則被安排在0x0200_0000開始的地址區(qū)間。在0x0100_0000地址開始的內(nèi)存空間中,安排了一塊ROM。按照芯片內(nèi)部的硬件設(shè)計,芯片上電復(fù)位對硬件電路做好初始化后,先進入ROM執(zhí)行預(yù)燒錄的bootloader程序,進一步引導(dǎo)至用戶應(yīng)用程序。
圖x HA01的內(nèi)存地址空間
在Arm Cortex-M7架構(gòu)中,ITCM是專門用來存放程序指令(Instruction),DTCM是專門用來存放數(shù)據(jù)(Data),至于OCRAM,就對應(yīng)于普通的SRAM。如果按照以往Arm Cortex-M架構(gòu)中只區(qū)分flash和SRAM的用法,DTCM和OCRAM都可以當(dāng)做是SRAM使用,所以用戶在常規(guī)用例的linker文件中,也可以把DTCM和OCRAM連續(xù)的地址空間都當(dāng)做SRAM使用。但實際上,ITCM和DTCM都是TCM(Tightly Coupled Memories)存儲器,分別通過I-TCM和D-TCM總線訪問,是等同于Cache存儲器的角色,直接同Arm Cortex-M7內(nèi)核相連,而不同于OCRAM(或者早先Arm Cortex-M架構(gòu)中的RAM)是通過總線(AXI總線)間接同Arm Cortex-M7內(nèi)核連通。如此,一般情況下,若沒有Cache加持,Cortex-M7內(nèi)核訪問TCM的效率要高于訪問OCRAM。
對這些不同同種類的內(nèi)存,可以根據(jù)需要靈活配置,以獲得最優(yōu)的訪問效率。一種典型的用法:
在ITCM中存放中斷向量表。這也是為什么把ITCM安排到0x0000_0000地址的原因。但需要在執(zhí)行到pflash中的用戶程序之后,由用戶程序?qū)⒋娣旁趐flash中的中斷向量表自行搬運到ITCM,然后修改Arm核心的VTOR寄存器重映射到0x0000_0000作為中斷向量表的基地址。如果ITCM的空間大于預(yù)留的中斷向量表占用的空間,剩下的空間用來存放ram code也是不錯的。
在DTCM中存放棧。方便處理器快速地申請和釋放。
在OCRAM中存放堆,以及用戶程序中定義的全局變量、緩沖區(qū)等。
OCRAM可能跟Cache搭配使用,以提高訪問效率,但如果處理器內(nèi)核和DMA進行數(shù)據(jù)同步,Cache機制可能會引入一些麻煩,此時如果不想繁瑣地調(diào)整Cache的配置,也可以將需要同步的緩沖區(qū)安排到DTCM中。
BOOT ROM簡介
HA01上集成的BOOT ROM使用了64KB的存儲器。芯片復(fù)位后,Cortex-M7內(nèi)核從ROM里的bootloader開始執(zhí)行引導(dǎo)程序。其中,將解析存放在pflash開始位置的BVT(Boot Vector Table)。這里的bootloader主要用于實現(xiàn)四個功能:
安全啟動Security Boot
在信息安全的體系中,Security Boot作為整個安全系統(tǒng)的置信根(Root of Trust),可以使用CMAC授權(quán)算法,對用戶指定的程序(例如2nd bootloader或OTA)進行認(rèn)證,這個過程中,利用硬件的HCU外設(shè)模塊進行計算,其配置信息存放在BVT中。進一步,HCU外設(shè)模塊使用的密鑰,存放在HCU_NVR中,由OEM主機廠或Tier-1預(yù)先燒錄,用戶全程不可見。
如果CMAC驗簽失敗,處理器內(nèi)核可以繼續(xù)運行bootloader并引導(dǎo)至用戶程序,但HCU將不會導(dǎo)入存放與HCU_NVR中的密鑰,一切加密相關(guān)的操作將得不到芯片硬件的支持。
快速從Powerdown模式下喚醒
當(dāng)檢測到從Powerdown模式下喚醒而產(chǎn)生的復(fù)位,可以跳過Security Boot和內(nèi)核自檢的過程,從而加速啟動過程。
可選地啟用配置獨立的IVT(Interrupt Vector Table)。這需要配合REGFILE中最開始的兩個存儲字存放配置信息。REGFILE在Powerdown模式下仍能保存數(shù)據(jù)。
對內(nèi)核進行例行自檢(Structural Core Self-Test,SCST)
這是為了配合實現(xiàn)功能安全等級ASIL-D標(biāo)準(zhǔn),而進行的運行時測試。
根據(jù)BVT中的配置,在bootlaoder過程中啟用或者停用看門狗,以及對應(yīng)的超時周期(HA01的WDG在默認(rèn)情況下,使用來自于IPC的SIRC/4作為計數(shù)時鐘源)
BOOT ROM中的Bootloader執(zhí)行過程
在HA01的RM手冊中,可以找到bootloader執(zhí)行過程的示意圖。如圖x所示。
圖x BOOT ROM中的bootloader運行流程圖
從圖x中可以看到,芯片從上電啟動到用戶的main()函數(shù),大體要經(jīng)歷三個階段:
MCU Reset Phase
Boot Code Function
MCU App run Phase
芯片上電后(POR),根據(jù)REGFILE區(qū)域中的REG0的配置值,分別進入快速啟動流程(Fast Wakeup Boot Mode)或常規(guī)啟動流程(Normal Boot Mode)。
在快速啟動流程中:
解析BVT中預(yù)設(shè)的參數(shù),以初始化系統(tǒng)時鐘。
從REGFILE->REG1寄存器中獲取快速啟動流程的應(yīng)用程序入口地址(同常規(guī)啟動流程最終引導(dǎo)的應(yīng)用程序入口地址可能不同)
查看IVT的地址并確保指定IVT的地址空間位于SRAM,后續(xù)將在用戶自行編寫的應(yīng)用程序初始化階段存放中斷向量表。
跳轉(zhuǎn)到快速啟動流程的程序入口。
中間過程如果遇到任何異常,都會進入static mode(原地死循環(huán))。
在常規(guī)啟動流程中:
解析BVT中預(yù)設(shè)的參數(shù)。
若BVT中配置啟用了Security Boot,則執(zhí)行驗簽過程。
若BVT中配置啟用了SCST Test,則執(zhí)行Cortex-M7處理器內(nèi)核的自檢。
根據(jù)BVT中的參數(shù),配置看門狗WDG外設(shè)模塊。
跳轉(zhuǎn)到常規(guī)啟動流程的程序入口。
中間過程如果遇到任何異常,都會進入static mode(原地死循環(huán))。
快速啟動流程中不執(zhí)行Security Boot和SCST Test過程,因此可以縮短啟動時間。但注意,快速啟動流程的應(yīng)用程序入口同常規(guī)啟動的應(yīng)用程序入口可能不是同一個。
BVT的數(shù)據(jù)結(jié)構(gòu)
BVT保存了啟動過程中的很多關(guān)鍵參數(shù),它本身位于pflash存儲區(qū),0x0200_0000開始的一段內(nèi)存空間,可由用戶在編寫應(yīng)用程序時,創(chuàng)建一個結(jié)構(gòu)體,然后在鏈接過程中將其安排至0x0200_0000地址。BVT的參數(shù)占用108個字節(jié),但實際上卻需要預(yù)留2KB的空間,這是由于pflash的一個sector大小為2KB。用戶實際開發(fā)過程中,也可以調(diào)整linker file,避開0x0200_0000開始的一個sector,如此,可保持最近一次燒寫的可用的BVT配置不變。
手冊中列寫了BVT的字段定義,如圖x所示。
圖x 描述BVT的字段信息
從這里可以窺到一個有趣的設(shè)計,竟然提到了有CM7_0、CM7_1和CM7_2三個Cortex-M7處理器核心,并且每個核心有main和secondary兩個核心。從描述上看,這描述的是一對鎖步核(lockstep),并且每個核心都可以有獨立的應(yīng)用起始地址(application start address),將來用于全并行地分別執(zhí)行不同的應(yīng)用程序。實際上,目前的HA01使用的是一個不可拆開的單鎖步核,故只有CM7_0_main可用。可以想見,在后續(xù)的產(chǎn)品規(guī)劃中,可能會出現(xiàn)最多3對鎖步核,如果進一步將鎖步核拆開,可以設(shè)計最多6個獨立的Cortex-M7核心。
BVT中0x4偏移地址上的Boot Configuration Word中進一步定義了啟動相關(guān)的配置項,如圖x中的表格所示。
圖x Boot Configuration Word的字段描述
這里提供了一個信息,運行bootloader程序使用了FIRC(96MHz)作為時鐘源,但可以通過CPDIVS設(shè)置1分頻或者2分頻。
這里還設(shè)計了很多功能的開關(guān),例如看門狗、6個核心的獨立使能開關(guān),SCST自檢功能。
這里還提到了serial security boot mode和normal boot mode,猜測前者可能就是驗簽的計算過程。
Practice
源碼中關(guān)于BVT的設(shè)計
用戶從SDK中導(dǎo)出的樣例工程,就有關(guān)于對BVT的定義,以及在鏈接腳本中專門分配的代碼段。
以hello_world工程為例,其中的secure_boot_YTM32B1HA0.h文件中有關(guān)于BVT類型的定義:
... #defineBVT_HEADER_SEG__attribute__((used))__attribute__((section(".bvt_header"))) ... /*! *@brieftheBVTstructuretypedefinition * *Implements:bvt_header_config_t_Class */ typedefstruct{ uint32_tbvt_marker;/*BVTmarker*/ uint32_tboot_config_word;/*Bootconfigurationword*/ uint32_tsbt_config_group_addr;/*securebootstartaddress*/ uint32_tlc_config;/*lifecycleconfiguration*/ uint32_tcm7_0_main_app_addr;/*CM7_0maincorestartaddress*/ uint32_tcm7_0_secondary_app_addr;/*ReservedforCM7_0_SECONDARY_APP_ADDR*/ uint32_tcm7_1_main_app_addr;/*ReservedforCM7_1_MAIN_APP_ADDR*/ uint32_tcm7_1_secondary_app_addr;/*ReservedforCM7_1_SECONDARY_APP_ADDR*/ uint32_tcm7_2_main_app_addr;/*ReservedforCM7_2_MAIN_APP_ADDR*/ uint32_tcm7_2_secondary_app_addr;/*ReservedforCM7_2_SECONDARY_APP_ADDR*/ uint32_tapp_wdg_timeout;/*timeoutsetoftheWDGwatchdogoftheapplicationcore*/ }bvt_header_config_t;
而在secure_boot_YTM32B1HA0.c文件中,有定義具體的結(jié)構(gòu)體實例:
#defineBOOT_CONFIG_WORD(BVT_BCW_CPDIVS_SET(1)|CM7_0_M_EN) /*definethetimeoutofADGwatchdogoftheapplicationmaincore*/ #defineAPP_WDG_TIMEOUT(120000)/*10msrespectto12MHzSIRCasreferenceclock*/ /*Flasherasedstatus*/ #defineRESERVED(0xFFFFFFFF) /*BVTHeaderconfiguration*/ constbvt_header_config_tbvt_headerBVT_HEADER_SEG={ BVT_VALID_MARK,/*BVTmarker*/ BOOT_CONFIG_WORD,/*Bootconfigurationword*/ (uint32_t)&secure_boot_group,/*securebootstartaddress*/ RESERVED,/*lifecycleconfiguration*/ DEFAULT_START_ADDRESS,/*CM7maincorestartaddress*/ RESERVED, RESERVED, RESERVED, RESERVED, RESERVED, APP_WDG_TIMEOUT,/*timeoutsetoftheWDGwatchdogoftheapplicationcore*/ };
此處注意,定義的bvt_header結(jié)構(gòu)體將位于BVT_HEADER_SEG數(shù)據(jù)段內(nèi)。其中DEFAULT_START_ADDRESS定義了同應(yīng)用軟件約定的啟動地址,具體位于0x0200_0800。位于secure_boot_YTM32B1HA0.h文件中。
/*BVTvalidmarker*/ #defineBVT_VALID_MARK(0xA55AA55A) /*Defaultstartaddress*/ #defineDEFAULT_START_ADDRESS(0x02000800)
同時,在YTM32B1HA01_flash.sct文件中,也相應(yīng)指定了BVT所占用的存儲空間(預(yù)留在0x0200_0000至0x0200_07FF,和應(yīng)用程序的起始地址0x0200_0800:
#definem_bvt_start0x02000000 #definem_bvt_end0x020007FF #definem_bvt_sizem_bvt_end-m_bvt_start+1 #definem_interrupts_start0x02000800 #definem_interrupts_size0x00000400 。。。 LR_m_textm_bvt_start {;loadregionsize_region ER_m_text_2m_bvt_startFIXEDm_bvt_size { .ANY(.bvt_header) .ANY(.sb_config_group) .ANY(.sb_config_section) .ANY(.sb_cmac) } //vectors. VECTOR_ROMm_interrupts_startFIXEDm_interrupts_size { *(RESET+First) } //code. ER_m_textm_text_startFIXEDm_text_size { *(InRoot$$Sections) .ANY(+RO) } 。。。
當(dāng)下載程序后,可以在memory的視圖中可以看到,0x0200_0000開始的位置,有存放關(guān)于BVT的配置信息。如圖x所示。
圖x 下載到HA01芯片中的BVT配置數(shù)據(jù)
在集成開發(fā)環(huán)境中調(diào)試
BOOT ROM + BVT相互配合,在HA01芯片內(nèi)部實現(xiàn)了一個bootloader,但程序的起始地址也不再是常規(guī)默認(rèn)的0x0000_0000,如此,當(dāng)在集成開發(fā)環(huán)境中調(diào)試程序時,可能會需要指定一個程序入口點。實際上,bootloader的存在并不影響在載入調(diào)試環(huán)境時自動將程序斷點到main()函數(shù):
在調(diào)試環(huán)境中,下載程序到芯片后復(fù)位,如果不顯式地執(zhí)行入口程序地址,芯片會自動從bootloader開始執(zhí)行,然后從BVT中取得用戶應(yīng)用程序入口地址后,跳轉(zhuǎn)到用戶應(yīng)用程序。確切地說,是進入到用戶程序的Reset_Handler函數(shù),然后進入到main()函數(shù)。
大多數(shù)集成調(diào)試環(huán)境,會“智能”地在main()函數(shù)開始的位置打一個斷點,作為調(diào)試程序的開始,等待開發(fā)者發(fā)起進一步的調(diào)試動作。
這類似于以往開發(fā)者在有用戶自定義的bootloader的環(huán)境下開發(fā)application。
無論是Keil還是IAR,在集成開發(fā)環(huán)境內(nèi)部啟動調(diào)試時,都可以自動執(zhí)行上述流程至main()函數(shù)的斷點。但是,當(dāng)使用Segger Ozone調(diào)試可執(zhí)行文件時,由于默認(rèn)會顯式指定一個入口地址,如果沒有合適的配置,默認(rèn)從0x0000_0000開始,就會出現(xiàn)錯誤。如圖x。
圖x 在ozone中配置程序入口點
圖x 默認(rèn)配置下載入調(diào)試出錯
從圖x中可以看到,Ozone默認(rèn)從固件程序的開始,0x0200_0000,讀到了初始的PC和SP值,但這里的數(shù)據(jù)其實是BVT的內(nèi)容,不是中斷向量表的項目。故會報錯。
此時,在配置初始載入點時,有幾種可行的配置,都可以實現(xiàn)正常調(diào)試:
Initial PC -> Read from Location -> 0x0100_0004, Initial Stack Pointer -> Read from Location -> 0x0100_0000。這種設(shè)置是從BOOT ROM中的bootloader開始啟動,然后引導(dǎo)到用戶應(yīng)用程序。
Initial PC -> Read from Location -> 0x0200_0804, Initial Stack Pointer -> Read from Location -> 0x0200_0800。這種設(shè)置是跳過BOOT ROM中的bootloader啟動,直接從用戶應(yīng)用程序啟動。
Initial PC -> Do not set, Initial Stack Pointer -> Do not set。這種設(shè)置是軟件工具不要多做,讓芯片的硬件機制起作用。此時芯片從BOOT ROM中的bootloader開始啟動,然后引導(dǎo)到用戶應(yīng)用程序。
建議使用第三種方式,充分利用硬件機制,確保對芯片有最完整的初始化過程,也是最接近在芯片正常上電啟動的運行情況。
Conclusion
YTM32B1HA系列微控制器基于Arm Cortex-M7處理器內(nèi)核,集成了BOOT ROM,并重新劃分了地址空間中的內(nèi)存分配,這使得芯片上電之后的引導(dǎo)過程和用戶應(yīng)用程序的存放地址發(fā)生了一些變化,對應(yīng)地,使用調(diào)試軟件工具也需要做相應(yīng)的適配操作,以避免出現(xiàn)異常的情況。
無論如何,BOOT ROM中的bootloader和BVT的配置,為應(yīng)用帶來了一些新的功能,例如基于硬件計算引擎進行加速和加密的安全啟動過程、對多核心運行的管理等等。這為支持復(fù)雜的片上系統(tǒng)的奠定了一定的基礎(chǔ),也是設(shè)計多核心SoC的啟動過程的一種可行的嘗試。
-
微控制器
+關(guān)注
關(guān)注
48文章
7953瀏覽量
155099 -
處理器
+關(guān)注
關(guān)注
68文章
19896瀏覽量
235280 -
內(nèi)核
+關(guān)注
關(guān)注
3文章
1416瀏覽量
41443
原文標(biāo)題:YTM32的HA系列微控制器啟動過程詳解
文章出處:【微信號:Ithingedu,微信公眾號:安芯教育科技】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
詳解STM32啟動過程
YTM32的LIN通信協(xié)議引擎LinFlexD外設(shè)模塊詳解

YTM32的模數(shù)轉(zhuǎn)換器ADC外設(shè)模塊詳解

講STM32H7的啟動過程
STM32F429啟動過程詳解
STM32H7啟動過程詳解
Linux啟動過程詳解
Windows XP 啟動過程詳解
Linux基礎(chǔ)命令之Linux啟動過程詳解

詳解bootloader的執(zhí)行流程與ARM Linux啟動過程分析

stm32啟動過程

評論