I'm working with the ARMGCC version of the SDK (using MIMXRT1060-EVK currently). I've built several different examples and small applications that boot from (and run out of) FlexSPI-NOR-flash. I'd like to be able to boot out of FlexSPI-nor, then have the application transfer itself to SDRAM and run from there. Are there any examples of that in the SDK?
I'm guessing it's just a matter of massaging the .ld file and making sure that Reset_Handler copies text space to the correct location in SDRAM, prior to jumping to the relocated _start; but that's easier said than done...
Before I trek this path, has anyone done this already?
Solved! Go to Solution.
Ed
Or have a second SPI connected Flash chip for the other storage needs.
I have all applications running in ITC so they use the QSPI flash for parameter and file systems without any problems with sharing with code. In fact I avoid SDRAM since it doesn't allow code to be protected and I never had a program so large that external memory was needed.
The only time I need to run from QSPI flash and program it at the same time is when the boot loader needs to update programs, in which case just the involved routines are executed from ITC.
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]
Hi Ed
Below is the solution used in the uTasker project. The SDRAM needs either to be configured via DCD or else by initialisation code before the copy/jump. It shows decrypting from encrypted code in SPI flash or plain text, depending on the image.
The image needs just to be linked to the SRDAM address that it will run at.
static void jump_to_application(unsigned long app_link_location)
{
asm(" mov r1, #0"); // cortex-M7 assembler code
asm(" msr control, r1"); // disable potential FPU access flag so that subsequent exceptions do not save FPU registers
asm(" ldr sp, [r0,#0]"); // load the stack pointer value from the program's reset vector
asm(" ldr pc, [r0,#4]"); // load the program counter value from the program's reset vector to cause operation to continue from there
}
static void fnCopyApplicationToRAM(iMX_BOOT_HEADER *ptrHeader, unsigned long ulCodeLength)
{
if ((ptrHeader->usMagicNumber & 0x8000) != 0) { // if AES256 encrypted
unsigned long ulBuffer[512]; // long word aligned buffer
unsigned long ulCopyLength = sizeof(ulBuffer);
const unsigned char *ptrInput = (const void *)(ptrHeader + 1);
unsigned char *ptrDestination = (unsigned char *)(SDRAM_START_ADDRESS);
fnPrepareDecrypt(); // prepare the decrpt key and prime the initial vector
while (ulCodeLength != 0) {
if (ulCodeLength < sizeof(ulBuffer)) {
ulCopyLength = ulCodeLength; // final block that may be smaller that the buffer size
}
uMemcpy(ulBuffer, ptrInput, ulCopyLength); // copy the encrypted input block into the decryption buffer
fnAES_Cipher(AES_COMMAND_AES_DECRYPT, (const unsigned char *)ulBuffer, (unsigned char *)ulBuffer, ulCopyLength); // decrypt the buffer content
uMemcpy(ptrDestination, (const void *)ulBuffer, ulCopyLength); // copy the decrypted code to program RAM
ulCodeLength -= ulCopyLength;
ptrDestination += ulCopyLength;
ptrInput += ulCopyLength;
}
}
else {
uMemcpy((void *)(SDRAM_START_ADDRESS), (const void *)(ptrHeader + 1), ulCodeLength); // copy the unencrypted code
}
}
// Load and start an application stored in QSPI
//
extern void start_application(unsigned long app_link_location)
{
iMX_BOOT_HEADER *ptrHeader = (iMX_BOOT_HEADER *)app_link_location;
unsigned long ulCodeLength = fnCheckValidApplication(ptrHeader); // check the authentication of code in the SPI flash
if (ulCodeLength != 0) { // if the code image is valid
jump_to_application(SDRAM_START_ADDRESS); // and finally jump to the new code
}
}
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]
Thanks Mark, I'm still trying to decide how I want to pursue this. My real goal is just to be able to modify FlexSPI-nor-flash at runtime. Since I can't execute from the flash while operating on it, the only two approaches AFAIK would be to relocate the entire application to SDRAM or just relocate the flash operations. Not sure which way to go yet.
Ed
Or have a second SPI connected Flash chip for the other storage needs.
I have all applications running in ITC so they use the QSPI flash for parameter and file systems without any problems with sharing with code. In fact I avoid SDRAM since it doesn't allow code to be protected and I never had a program so large that external memory was needed.
The only time I need to run from QSPI flash and program it at the same time is when the boot loader needs to update programs, in which case just the involved routines are executed from ITC.
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]
Yea, actually my previous reply wasn't accurate... Didn't really mean SDRAM, just not FlexSPI. I did have SDRAM in mind initially, but actually it would make more sense to run out of internal ram.
Tx