[ ST NUCLEO-U575ZI-Q 测评] 6-TrustZone工程的启动流程
<div class='showpostmsg'><p>TrustZone的工程中是包含2个工程文件的,安全区的工程和非安全区的工程。这两个工程是下载到不同的flash地址的。</p><p><strong>TrustZone的工程要求从安全区的工程启动,然后在跳转到非安全区执行的。</strong></p>
<p>这是因为需要在启动的时候设置安全属性,比如SAU、GTZC之类的安全外设,这些安全属性只能在安全区进行设置。因此安全区的工程下载到Flash的起始地址,0x08000000,但因为这是安全区的代码,因此实际上用的是0x08000000的别名地址0x0C000000,这2个地址实际上是同一个地址。别名区的概念在STM32F1时就出现过,当时的位带区也是别名区的一种。当安全区的工程配置好安全属性之后,就要跳转到非安全区了。非安全区的代码下载到另一个地址,比如0x08100000。当然这个地址取决于用户是如何划分Flash的区域的,这个地址是可以更改的。</p>
<pre>
<code>int main(void)
{
/* SAU/IDAU, FPU and interrupts secure/non-secure allocation setup done */
/* in SystemInit() based on partition_stm32u575xx.h file's definitions. */
/* USER CODE BEGIN 1 */
/* Enable SecureFault handler (HardFault is default) */
SCB->SHCSR |= SCB_SHCSR_SECUREFAULTENA_Msk;
/* STM32U5xx **SECURE** HAL library initialization:
- Configure the Flash prefetch
- Configure the Systick to generate an interrupt each 1 msec
- Set NVIC Group Priority to 3
- Low Level Initialization
*/
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the System Power */
SystemPower_Config();
/* GTZC initialisation */
MX_GTZC_S_Init();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ICACHE_Init();
/* All IOs are by default allocated to secure */
/* Release them all to non-secure except PC.07 (LED1) kept as secure */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
HAL_GPIO_ConfigPinAttributes(GPIOA, GPIO_PIN_ALL, GPIO_PIN_NSEC);
HAL_GPIO_ConfigPinAttributes(GPIOB, GPIO_PIN_ALL, GPIO_PIN_NSEC);
HAL_GPIO_ConfigPinAttributes(GPIOC, (GPIO_PIN_ALL & ~(GPIO_PIN_7)), GPIO_PIN_NSEC);
HAL_GPIO_ConfigPinAttributes(GPIOD, GPIO_PIN_ALL, GPIO_PIN_NSEC);
HAL_GPIO_ConfigPinAttributes(GPIOE, GPIO_PIN_ALL, GPIO_PIN_NSEC);
HAL_GPIO_ConfigPinAttributes(GPIOF, GPIO_PIN_ALL, GPIO_PIN_NSEC);
HAL_GPIO_ConfigPinAttributes(GPIOG, GPIO_PIN_ALL, GPIO_PIN_NSEC);
HAL_GPIO_ConfigPinAttributes(GPIOH, GPIO_PIN_ALL, GPIO_PIN_NSEC);
/* Secure SysTick should rather be suspended before calling non-secure*/
/* in order to avoid wake-up from sleep mode entered by non-secure */
/* The Secure SysTick shall be resumed on non-secure callable functions */
/* For the purpose of this example, however the Secure SysTick is kept*/
/* running to toggle the secure IO and the following is commented: */
/* HAL_SuspendTick(); */
/*************** Setup and jump to non-secure *******************************/
NonSecure_Init();
/* Non-secure software does not return, this code is not executed */
/* Infinite loop */
while (1);
}</code></pre>
<p data-line="61" dir="auto">上面的代码是位于安全区的工程main函数,从中可以看出其启动流程是:</p>
<ol data-line="62" dir="auto">
<li data-line="62" dir="auto">设置安全属性,包括SAU、GTZC。在GTZC中要设置SRAM的安全区地址和非安全区地址,为外设分配安全属性。</li>
<li data-line="63" dir="auto">为非安全区分配资源,包括GPIO、中断和DMA。从下图中,可以看出在复位之后,有的外设是安全区,有的外设是非安全的。如果要在非安全的工程中使用处于安全区的外设,就要进行配置,将其分配到非安全区。例如GPIO全部位于安全区,如果在非安全区要用到UART或者GPIO,那么就要将对应的引脚分配到非安全区。</li>
<li data-line="65" dir="auto">安全区外设的初始化,初始化在安全区使用的外设。</li>
<li data-line="66" dir="auto">跳转到非安全区,那么如何从安全区跳转到非安全区呢?跳转函数如下所示。</li>
</ol>
<pre>
<code>#define VTOR_TABLE_NS_START_ADDR0x08100000UL
static void NonSecure_Init(void)
{
funcptr_NS NonSecure_ResetHandler;
SCB_NS->VTOR = VTOR_TABLE_NS_START_ADDR;
/* Set non-secure main stack (MSP_NS) */
__TZ_set_MSP_NS((*(uint32_t *)VTOR_TABLE_NS_START_ADDR));
/* Get non-secure reset handler */
NonSecure_ResetHandler = (funcptr_NS)(*((uint32_t *)((VTOR_TABLE_NS_START_ADDR) + 4U)));
/* Start non-secure state software application */
NonSecure_ResetHandler();
}</code></pre>
<p data-line="83" dir="auto">这个代码和IAP的代码挺像的,都是实现了程序区的跳转。步骤如下:</p>
<ol data-line="62" dir="auto">
<li data-line="84" dir="ltr">将非安全区的中断向量表赋值给程序控制块。</li>
<li data-line="85" dir="ltr">设置使用的栈顶地址,需要注意的是内核的SP寄存器(栈顶指针寄存器)是有2个的,分别用于安全区和非安全区,所以这个实际上设置的是非安全区的栈顶指针。</li>
<li data-line="86" dir="ltr">最后跳转到非安全区的重启函数出。</li>
</ol>
<p>从上面的内容中,可以看出STM32启动的时候先运行安全区的代码,将安全属性、外设资源等分配好,就会跳转到非安全区的main函数执行。因此代码主要执行非安全区的代码,非安全区的代码可以通过NSC函数调用安全区的函数实现两个区域的交互。</p>
</div><script> var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;" style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
if(parseInt(discuz_uid)==0){
(function($){
var postHeight = getTextHeight(400);
$(".showpostmsg").html($(".showpostmsg").html());
$(".showpostmsg").after(loginstr);
$(".showpostmsg").css({height:postHeight,overflow:"hidden"});
})(jQuery);
} </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script> 感谢分享 <p>STM32启动的时候先运行安全区的代码确实这样,最后的总结写的好,谢谢</p>
<p>测评汇总:免费申请|ST NUCLEO-U575ZI-Q https://bbs.eeworld.com.cn/thread-1228653-1-1.html</p>
页:
[1]