Hello,
we are using RT1011 and we are having troubles with XIP from FLASH on FLEXSPI through OTFAD. Our application is correctrly encrypted and we can see that the startup code at the reset vector is executed correctly. However, when clocks are setup (*) the OTFAD module stops working and FLASH data is corrupted. Since our application does not fit in RAM, we need to execute code and to retrieve data from FLASH at run time. How can we avoid OTFAD to stop working - or restore it?
I've also tried to disable OTFAD for as long as the clocks are being configured, but it doesn't work - actually, resetting the GE bit of CR register produces no change (RRAE=0).
Thank you in advance!
Stefano Voulaz
(*) The project has been developed in MCUXpresso and as such it contains the usual BOARD_BootClockRUN function to configure clocks systemwide. All the relevant code, including fsl library code, has been allocated to RAM.
Additional information
The same happens on the RT1011 evaluation board when running the iled_blinky sample project using encrypted binary. As soon as the PERIPH_CLK MUX is switched (clock_config.c, line 166), the OTFAD module ceases working and FLASH memory readout is corrupted.
Hi all,
About the OTFAD issues, please note these information:
1. Reason
When OTFAD is enabled, if the encrypted app is XIP running, in the app, core frequency need to be higher than FlexSPI frequency. If core frequency is lower than flexSPI, when core access the encrypted Flash area, OTFA can't decrypte the code, and will case the instruction messing issues, will case the hardfault.
In the BOARD_BootClockRUN(), we can see the core frequency from 396Mhz to external OSC24 Mhz switch, it will make the core smaller than FlexSPI frequency, as you know, the slowest FlexSPI is 30Mhz. This is the root issue caused the OTFAD limit issues.
2. Solution
When configure the clock, don't switch to the external OSC then switch to the PLL, we can switch to PLL directly. Put the Audio(Enet) Pll init code to the front side. The modification code is:
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 */
// delete...
/* 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);
// delete...
/* 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);
// delete...
/* Set SystemCoreClock variable. */
SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK;
}
Kerry
Hi Stefano Voulaz,
Some test result on my side.
In the previous time, I use the __ramfunc at the BOARD_BootClockRUN, and the internal related API, it's not working.
Then, I modify the BOARD_BootClockRUN function, copy the whole and the internal related API to the flash address 0x60005000, in the IAR linker file, divide one flash section to put these API.
Use the following code to put in the specific flash area
#pragma default_function_attributes = @ ".xtal24mhz"
Related API
#pragma default_function_attributes =
Linker file related code:
define symbol m_text1_start = 0x60005000;
define symbol m_text1_end = 0x60FFFFFF;
place at address mem:m_text1_start { section .xtal24mhz };
In the MCUbootUtility OTFAD side, I just secure the no BOARD_BootClockRUN code.
Then modify the led_blinky code:
int main(void)
{
unsigned int i, j;
BOARD_InitPins();
Flash_bootclockrun();
// BOARD_BootClockRUN();
//BOARD_InitDebugConsole();
if (SysTick_Config(SystemCoreClock / 1000U))
{
while (1)
{
}
}
while (1)
{
/*
for(i=0;i<300;i++) for(j=0;j<65535;j++);
GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);
for(i=0;i<300;i++) for(j=0;j<65535;j++);
GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);
*/
SysTick_DelayTicks(1000U);
if (g_pinSet)
{
GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);
g_pinSet = false;
}
else
{
GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);
g_pinSet = true;
}
}
}
After the OTFAD secure, the led is blinking now.
I share you the related led_blinky.c and the linker file, you can test it on your SDK led_blinky code in the IAR version.
But, to be honest, I find it still has some issues, eg, if I add BOARD_InitDebugConsole(); then the OTFAD secure even failed, I am still trying to find the root issues.
Because our internal expert is really busy, then the talk and reply will have delay, anyway, I will do more testing on my own side.
This time, I think you can use my code and method to test it on your side, whether it also works for you or not?
Any updated information, please kindly let me know.
Thanks so much for your effort and patient.
Best Regards,
Kerry
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------
Hi
Would it be possible to have a complete list of (known) restrictions (or things that need to be worked around, and how) when using on-the-fly decryption based on OTFAD?
Also is anything known with using BEE? - Based on experience running fairly complex projects using BEE based on-the-fly decryption this method seems to have none, but a confirmation of this would be useful.
Regards
Mark
Hi Stefano Voulaz,
Totally reproduce your issue, download the OTFAD code, non XIP works, XIP didn't boot OK.
Still double checking with our internal related team, still struggling it,
Thanks so much for your issue sharing.
You mentioned:
(*) The project has been developed in MCUXpresso and as such it contains the usual BOARD_BootClockRUN function to configure clocks systemwide. All the relevant code, including fsl library code, has been allocated to RAM.
Additional information
The same happens on the RT1011 evaluation board when running the iled_blinky sample project using encrypted binary. As soon as the PERIPH_CLK MUX is switched (clock_config.c, line 166), the OTFAD module ceases working and FLASH memory readout is corrupted.
Could you please tell me, how do you track to this point? As I find, when I do the OTFAD XIP boot, it is failed, and still in the serial download mode.
Anyway, any updated information from my side, I will let you know, I am still talking with some of our department colleagues about your issue, and test it on my side.
Thanks so much for your patient, please don't worry, as I know, some of our customers already use the RT1010 OTFAD successfully in the product, maybe you and I still didn't find any small point which needs to workaround.
Best Regards,
kerry
Hi kerryzhou,
in order to track to the point where the FLASH memory readout is corrupted I put a trap at the very beginning of ResetISR() function in startup_mimxrt1011.c - a while loop on an SNVS register, to avoid using any memory, in the form of:
while(SNVS->LPGPR_ALIAS[1] == 0);
This way the (encrypted) program starts and I can attach the debugger to follow the execution step by step down to BOARD_BootClockRUN(). In this condition, I can see the content of the flash correctly decoded, right until PERIPH_CLK MUX is switched.
Probably you are right, we are just missing a bit value - I hope so. At this time we are able to successfully run an encrypted image only if code and data are run and stored in RAM after boot - no XIP.
Thank you and best regards,
Stefano
Hi Stefano Voulaz,
Today, I do the test that comment the BOARD_BootClockRUN();
unsigned int i, j;
BOARD_InitPins();
//BOARD_BootClockRUN();
while (1)
{
for(i=0;i<300;i++) for(j=0;j<65535;j++);
GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);
for(i=0;i<300;i++) for(j=0;j<65535;j++);
GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);
}
Just use the software delay to toggle the LED, and it is the XIP, the OTFAD is working.
I also find the AN 12670 have this note:
Don't encrypted a code section with frequency adjustment.
Then I checked with our internal department again with my test result, I get the information that, XTAL 24Mhz initialize code don't put in the OTFAD encrypted area.
So, I think we need to copy the BOARD_BootClockRUN() code to the no encrypted area, it should works OK.
You also can try it on your side, at least, without the frequency adjustment, the XIP code OTFAD can work.
Best Regards,
Kerry
Hi Kerry Zhou,
I’ve already tried to run BOARD_BootClockRUN() code from RAM, but without success. Maybe is some re-programming of the OTFAD module required after clock changes? As the Security Reference Manual for the RT1010 is not yet available, we have very few information available about OTFAD module registers and use.
Best regards,
Stefano
Hi Stefano Voulaz,
Secure reference manual is avaliable now:
https://www.nxp.com/webapp/Download?colCode=IMXRT1010SRM&appType=moderatedWithoutFAE
Best regards,
Stefano
Could you tell me how do you run BOARD_BootClockRUN() code from RAM? Please give me your detail modification, as you know, the BOARD_BootClockRUN() also calls other API code, I think the related frequency modified code all need to put in the RAM or the none OTFAD secured area.
About the SRM, I also don't have it, although I have checked with a lot of internal expert, they told me the document is still not finished, please keep patient to wait for it.
Best Regards,
Kerry
Hi kerryzhou,
that was quite complex on our project, but of course I put in RAM also the clock driver's and all additional code. But you can verify by yourself very easily by running the non-XIP version of blinky: just keep a memory window open on the encrypted section of the flash (with refresh enabled) and you'll see that the data gets scrambled as soon as PERIPH_CLK MUX is switched.
Best regards,
Stefano
OK, I will try it on my side!
Best Regards,
Kerry
Do you use the OTFAD Encrypted image boot?
Could you tell me how do you download the encrypted image to your chip?
Do you try to use the MCUBootUtility tool which already support the RT1011 OTFAD encrypted image boot:
Best Regards,
Kerry
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------
Follow-up: to double check, I just tried the whole process using MCUBootUtility to flash the encrypted image of the iled_blinky sample project ont the RT1011 EVK. Also in this case the encrypted image boots correctly but it crashes as soon as clocks are initialized in BOARD_BootClockRUN (reading from the FLASH returns corrupted data, which does not even match the raw encrypted data). The application was indeed built with XIP_BOOT_HEADER_ENABLE=0.
Best regards,
Stefano
Hi Stefano Voulaz,
Do you modify the BOARD_BootClockRUN code, or just use the official SDK BOARD_BootClockRUN code directly.
The iled_blinky project also have the BOARD_BootClockRUN();
int main(void)
{
/* Board pin init */
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
So, do you mean, you even use the official SDK iled_blinky generate the .s19 firmware, then use the MCUBootUtility download the code with OTFAD mode, right?
Please confirm it, then when I have time, I will also test it on my side.
Kerry
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------
Hi kerryzhou,
I confirm the above - just taken the iled_blinky project (no code change), set XIP_BOOT_HEADER_ENABLE=0 and built. Then I processed the .axf output file with MCUBootUtiliy to generate and flash the encrypted image.
As a second run, I added a trap at the ResetISR function to be able to hook with the debugger. So I could step into BOARD_BootClockRUN() until the OTFAD stops working.
SDK: 2.6.0 (latest) "SDK_2.x_MIMXRT1011xxxxx [API version=2.0.0, Format version=3.5]"
IDE: "MCUXpresso IDE v11.1.1 [Build 3241] [2020-03-02]"
Thank you.
Stefano
Hi Stefano Voulaz,
What about the firmware under the MCUBootutility directly:
NXP-MCUBootUtility-2.3.0\apps\NXP_MIMXRT1010-EVK_Rev.A
When I find time, I will do the testing on my side with the MIMXRT1010-EVK, please give me more time, really a lot of cases in the queue need to do the testing now.
Best Regards,
Kerry
Hi kerryzhou,
checked with the firmware under NXP-MCUBootUtility-2.3.0\apps\NXP_MIMXRT1010-EVK_Rev.A: images running in RAM (i.e., led_blinky_0x00003000) work fine, but images runnin in FLASH (i.e., led_blinky_0x60002000) don't.
Best regards,
Stefano
Hi Stefano Voulaz,
Could you please also share the fuse map about your board with the MCUBootUtility tool?
I also need to compare with my test result!
Best Regards,
Kerry
Hi Stefano Voulaz,
I also meet some issues when I use the MCUBootUtility the OTFAD download, I didn't enable the HAB.
This is my fuse which is similiar to you, just I do not use the fuse boot.
but, after I download the code, I find the app still the plaintex.
Although the OTFAD DEK Keyblob is generated.
So, do you also check, when you download the code, the app is encrypted or the plaintext?
Tomorrow, I will also check my situation with the tool author.
This is my user key with 2 regions:
Any updated information, I will let you know.
Best Regards,
Kerry