Hello everyone, I am a ruffian balance, is a serious technical ruffian. Today ruffian balance to share is the system clock configuration will lead to i.MX Rt1XXX series OTFAD encryption startup failure.

As we know, the hardware decryption peripheral of the early models of the I.MX RT1XXX family (RT1050/RT0160/RT1020) was named BEE, which was mainly used to realize the online decryption of XIP by external serial NOR Flash in conjunction with the FlexSPI peripheral. And to the recent I.MxRT1XXX new model (RT1010/RT1170), BEE peripherals have been replaced by OTFAD peripherals, the function remains unchanged, decryption efficiency has been greatly improved, but customers in enabling OTFAD encryption start often encounter App can not run normally. This has to do with one of OTFAD’s own clock limitations (which doesn’t exist on BEE), and here’s what WE’re going to talk about:

I. Problem description

Let’s take i.MX Rt1010 as an example, download an SDK package from the NXP website (v2.9.1 for ruffian), choose any one of the routines, and take the simplest \SDK\boards\ EvKMIMxrt1010 \demo_apps\led_blinky as an example. Compile the led_blinky project (select flexspi_nor_debug build, XIP project) to get the executable (actual bin file size is about 10KB), Use THE NXP-MCUBootUtility tool to download the led_blinky.out executable file into the MimxRt1010-EVK development board (start at 2′ B01 and switch to 2′ B10). You can see the on-board green LED light (D25) flashing. Routines work.

Now let’s try to enable OTFAD encryption, go back to chip download mode again and switch the Secure Boot Type option to OTFAD Encrypted Image Boot with the HELP of THE NXP MCUBootUtility tool. Other Settings are default (encryption range is 0x60001000-0x60001FFF at this time, only IVT and other startup headers are encrypted, app is not included), the executable file is downloaded again (led_blinky.out), and the reset board is switched to chip startup mode. The routine still works normally. It looks like there’s no problem with the OTFAD encryption startup.

Let’s go one step further, set the encryption range to 0x60002000-0x60004FFF, then the encryption area covers the entire APP, operate again according to the above process, and find that the routine does not work properly, at this time the OTFAD encryption startup problem, can’t the APP area be encrypted? So what’s the point of OTFAD encryption?

The app area can be encrypted, of course, so let’s do the experiment again. In the main() function of the led_blinky.c file, We comment out BOARD_BootClockRUN() or make it all __ramfunc in a linked file. This routine simply uses SysTick to periodically flip GPIO. Therefore, the normal operation will not be affected if the clock configuration code is removed. When the project is recompiled and operated according to the above process, the routine can work normally again, indicating that the encrypted APP can be decrypted and executed by OTFAD normally.

The question now becomes why BOARD_BootClockRUN() doesn’t execute in Flash when OTFAD encryption is enabled, and that’s the problem.

Second, cause analysis

When OTFAD is enabled, if the encrypted app code is executed by XIP, the system clock configuration in the app should always ensure that the Core clock is higher than the FlexSPI peripheral clock. If the Core clock is lower than the FlexSPI clock, then the Core accesses the encrypted Flash area and OTFAD cannot decrypt it properly, resulting in instruction confusion and system failure.

We use the above i.MX Rt1010 system clock tree to carefully analyze the OTFAD clock limitation problem. BootROM will first configure the Core to 396MHz and set the FlexSPI clock to 30MHz to 200MHz according to the user’s setting in the FDCB at Flash offset 0x400. Then read the OTFAD DEK KeyBlob data at the address of Flash offset 0 to enable OTFAD, and then read IVT and other header information to jump to App. Obviously, the ivT-only encryption is not affected by the OTFAD restriction at all. This part of the parsing is done in BootROM, and the BootROM clock configuration complies with the OTFAD clock restriction.

CCM_ANALOG->PFD_528[PFD3_FRAC] = 24, PLL2 PFD3 output (528MHz * 18) / 24 = 396MHz CCM->CBCMR[PRE_PERIPH_CLK_SEL] = 2, Clock from PLL2 PFD3 CCM->CBCDR[PERIPH_CLK_SEL] = 0, kernel clock from CCM->CBCMR[PRE_PERIPH_CLK_SEL] CCM->CBCDR[AHB_PODF] = 0, CCM_ANALOG->PFD_480[PFD0_FRAC] = x, PLL3 PFD0 output (480MHz * 18)/x CCM->CSCMR1[FLEXSPI_CLK_SEL] = 3, clock from PLL3 PFD0 CCM->CSCMR1[FLEXSPI_CLK_SRC] = 0, The FlexSPI clock comes from CCM->CSCMR1[FLEXSPI_CLK_SEL] CCM->CSCMR1[FLEXSPI_PODF] = y, and the FlexSPI clock does (y+1) frequency divisionCopy the code

The BOARD_BootClockRUN() function changes the kernel frequency from 396MHz set by BootROM to 24MHz set by external OSC. No matter what FlexSPI clock is configured in the user’s FDCB at this time, it will be at least greater than 30MHz. Then the 24MHz kernel frequency must be lower than the FlexSPI clock frequency. At this time, as long as the kernel accesses the Flash encryption region (the clock configuration code is executed in Flash), The OTFAD clock limit issue is triggered, and the App runs away.

Iii. Solutions

Knowing the reason, the solution is simple. In App clock configuration, do not switch the kernel clock source to external OSC and then switch to PLL, but switch directly to PLL. For example, i.mx RT1010 has an internal PLL6 (also called Audio PLL) fixed at 500MHz, which is exactly the final kernel frequency required by App. In BOARD_BootClockRUN(), we put the Audio(Enet) PLL initialization code at the front. Delete the original switch OSC setting code.

void BOARD_BootClockRUN(void)
{
    // 此处略去...
    /* Set Oscillator ready counter value. */
    CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(127);
-    /* Setting PeriphClk2Mux and PeriphMux to provide stable clock before PLLs are initialed */
-    CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); /* Set PERIPH_CLK2 MUX to OSC */
-    CLOCK_SetMux(kCLOCK_PeriphMux, 1);     /* Set PERIPH_CLK MUX to PERIPH_CLK2 */

    // 此处略去...
    /* Set IPG_PODF. */
    CLOCK_SetDiv(kCLOCK_IpgDiv, 3);
+     /* Init Enet PLL. */
+    CLOCK_InitEnetPll(&enetPllConfig_BOARD_BootClockRUN);
+    /* Set preperiph clock source. */
+    CLOCK_SetMux(kCLOCK_PrePeriphMux, 3);

    // 此处略去...
    /* Enable Audio PLL output. */
    CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK;
-    /* Init Enet PLL. */
-    CLOCK_InitEnetPll(&enetPllConfig_BOARD_BootClockRUN);
-    /* Set preperiph clock source. */
-    CLOCK_SetMux(kCLOCK_PrePeriphMux, 3);

    // 此处略去...
    /* Set SystemCoreClock variable. */
    SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK;
}
Copy the code

Finally, this OTFAD clock restriction problem also exists in I. MX Rt1170, the solution is similar to the above, ruffian balance will not be repeated.

At this point, the improper configuration of the system clock will lead to i.MX Rt1XXX series OTFAD encryption start failure problem ruffian balance will be introduced over, where is the applause ~~~

Welcome to subscribe to

The article will be published on my blog park homepage, CSDN homepage, Zhihu homepage and wechat public account at the same time.

Wechat search “ruffian balance embedded” or scan the following two-dimensional code, you can see the first time on the phone oh.