Hi,
I'm using Arm DS Version: 2022.2 as a trial version.
I've no arm chip yet thus i'm using Cortex-M55 FVP.
I'm trying to write kind of a boot rom sw that runs and load another 'hello world' application into code and data to different execution addresses in memory.
After boot rom ends with loading the code and data into memory it jumps into the 'hello world' Reset_Handler address and starts execution.
So far so good, the 'hello world' begin to run but I've noticed that the "__scatterload_copy" from arm c library is overwriting the RW data section with default pattern of 0xDFDFDFCF.
As a result a "SystemCoreClock" variable from "system_ARMCM55.c" initial value is being overwritten from "0x17D7840" into 0xDFDFDFCF and code based on this variable isn't working as expected..
I would be happy to understand how to avoid the "__scatterload_copy" operation in order not to overwrite the data the boot rom already loaded into data memory?
Thanks,Ronen
Hello Ronen,
Are 'boot rom' and 'hello world' built as two separate applications? Is it the scatterload of helloworld over-writing the clock as set in bootrom? It is likely that you simply need to edit the scatterloading file of the helloworld application such that it does not go near the RW section of the bootrom code.
It is likely that this is an over simplification. Perhaps if you could share a concrete example? If you wish to share with Arm privately, please raise a support case from the support menu above (referencing this thread).
Regards, Ronan
Hi Ronan,Thanks for your reply.
I will try answer your guiding questions:1. Correct - 'boot rom' and 'hello world' built as two separate applications.
2. This is the scatterload of the helloworld that over-writing the clock data as being placed at data memory location previo9usly by the boot rom.
3. I've verified that boot rom and helloworld are not accessing the same RW data memories - there is no overlap between them.
4. sure - attached pls find "rw_example.zip" which containd both the boot rom and the helloworld
Note:
+ I forgot mentioning that i'm using "objcopy --dump-section" on the helloworld output axf file and using its output binaries as an arrays in my boot rom application which doing memcpy of the arrays to the helloworld code and data addresses.The data content is then being over-written by the scatterload of the helloworld that starts running.Sorry if my description is too messy.
+ Yesterday i've moved from Arm DS evaluation into golden edition, since that i'm unable to run debugger due to some FVP license issue (i've open a support case for that case 03400501 - Wrong version of armctmodel)Thanks in advanced,
Ronen
rw_example.zip
Hi Ronan,I've also attached here a memory image diagram to show ther is no overlapping between boot rom and helloworld.
Hi Ronen
I'm trying to understand the code flow here... I don't think it is quite as simple as you may hope.
I think you have the 'hello' code embedded into the bootrom image at 0x10000000, however this includes a second set of init code... this would not work 'as is', as part of the Cortex-M initialization is to take stack pointer and reset vector address from the first two values... so things likely go awry immediately.
Does helloworld need to access SystemCoreClock or other such things? You should be able write helloworld as a typical C app, starting from main. Its scatterloading (a component of the c-library init code) ... do you expect helloworld to ever return?
I _think_ you may just need to define the entry point as __main. However if interrupts etc start to be involved I could see this getting messy. Are you using the same vector table for both boot and hello.
Hi Ronan,
That is right, the 'hello' code embedded into the bootrom image at 0x10000000. The 'hello' data is embedded into the bootrom image at 0x30000000.Currently it is embedded into the bootrom image only as a proof of concept - the bootrom takes these pieces of code+data and placed them into the memory according to the 'hello' image addresses set by its scatter file, In the future these pieces of code +data wil be fetched by hte boot rom from flash or arrived by some peripheral interfaces via host application to boot rom.My question is how can i avoid the "second set of init code"? i.e. i would like the arm c library to skip the startup code or to specifically skip the __scatterload_copy, is it possible?
>>"Does helloworld need to access SystemCoreClock or other such things?"Yes, the 'hello' prints a clock counts, so the SystemCoreClock is really needed.>>"do you expect helloworld to ever return?"No, the 'hello' should never returned.
I would try to " define the entry point as __main" and ping you for the result.Thanks,Ronen
Hi again Ronen,
There are two 'start up code sections to consider...
The system level code can be removed from your helloworld project by opening the .rteconfig file in the project, and deselecting Device > Startup. Also remove reference to this (ResetHandler) from the scatterloading file. The entry point should now be __main, at 0x10000000 (I see in your example you have hardcoded the entry point address of helloworld in your boot example.
To remove scatterloading, you could try to use the $Sub notation to patch in your own version of the __scatterload() function (which just returns):https://developer.arm.com/documentation/101754/0619/armlink-Reference/Accessing-and-Managing-Symbols-with-armlink/Use-of--Super---and--Sub---to-patch-symbol-definitions
But I believe you are going to hit runtime issues downstream... scatterloading also does things like set up RW Data... at a minimum, link with datacompressor off (or better, check that you have no RW data at all):https://developer.arm.com/documentation/101754/0619/armlink-Reference/armlink-Command-line-Options/--datacompressor-opt
Ronan
Hi Ronan,Thank you for your detailed response.
Will try the first approach once my DS Golden Edition is back to work (currently the FVP connection is broken due to some license issue in which you are trying to help as well :-)) .Will ping you right after,
I just used "#if 0" for the entire "Reset_Handler" function instead of removing the Startup from .retconfig (i hope this is OK)
But eventually it didn't help.Regarding the entry point of the destination image ('helloworld') that should be "__main" as you have suggested - I thinks this won't work as the "__scatterload" of the C library still will be called. Pls see below snapshot from Arm Application Note 241:I tried that and it appears that the "__scatterload" is the actual entry point of the application, pls see below snapshot of the debugger:
my boot rom code target address to jump into is : #define IMG_ENTRY_POINT_ADDRESS (0x100007c1)
So all in all it seems i can't avoid the __scatterload call.
Hi Ronen,
The entry point is __main, who's first instruction is a call to __scatterload.
If you implement (something like):
void $Sub$$__scatterload { return; }
The linker should point that function call to your implementation.
I got your point, thanks.
I've tried that and really the scatter load does nothing as expected. However the hello world isn't working as expected (SystemCoreClock isn't initialized to its default data value - this is also understood - we skipped the scatter load).
Feels like a ctach-22.
Ronan, sorry but maybe I'm missing something here, I will try again:How a typical boot rom application (that gets its destination fw binary data+code through external host, flash memory etc) can branch (and not returned) to its fw application and continue running from there?My understanding is that the boot rom accepts the fw code+data, copy it into a different memory locations (according to the fw scatter file definition and sizes) and branch into the fw application entry point,.
Thanks for your great support.Finally it worked for me.
The turning point was your last suggestion to skip the scatter load functionality from the hello world app itself.Rather than that i had two other bugs:1. I was branching into the vector section instead to the Reset_Handler (i.e. my Image Entry point was wrong).2. The hello world Code section (as an array in the boot rom) was wrong (different than the code we saw in disassembly). That happened due to a wrong path.