Other Parts Discussed in Thread: UNIFLASH,
Hi,
I've got a test application that I want to start at 0x2000 in Flash instead of the default 0x0000 (I have a bootloader that runs at 0x0000 and then jumps to application code). I took the provided linker file from a TI example, and changed the Flash origin from 0x0000000 to 0x00002000, and changed " .intvecs: > 0x00000000" to ".intvecs: > 0x00002000".
When I was testing via the debugger in Code Composer Studio (not Theia), everything worked fine (I load the application first, then load the bootloader second without erasing Flash memory, that way I can debug). Later, I enabled the option to export a binary file, which uses the tiarmhex.exe utility to create the .bin out of the .out file. Loading this application binary in address 0x2000 using Uniflash (and loading bootloader binary to 0x0000) does not work!
So loading the firmware using the .out file (which is what CCS debugger does) worked fine, but loading the generated .bin did not work. I loaded the firmware on a device using the .out file, then used Uniflash to read the Flash contents back onto a file (I'm calling it the "exported binary"). When I compare this exported binary with the tiarmhex.exe-generated binary, I see that the only difference is that it appears that the .text section starts at 0x20e8 in the exported image (on an 8-byte boundary), whereas on the generated binary, it starts at 0x20e4. (.text is the section after .intvecs) This results in all of the function calls being offset by one 32-bit instruction, or two 16-bit thumb instructions.
Looking at the CCS-generated .map file, it says .text starts at 000020e8, as expected. Also, in the linker (.cmd) file, I have ".text : palign(8) {} > FLASH". The TIArmClang Documentation states that palign(n) tells the linker to place a section's starting AND ending address boundary at n-bytes. So it appears that there is a bug or inaccuracy here, since tiarmhex.exe is not really starting .text on an 8-byte boundary once I change Flash and .intvecs origin from 0x0000 to 0x2000.
I can cause tiarmhex.exe to output a correct binary (where .text starts at 000020e8 and everything works) by changing ".intvecs: > 0x00002000" to ".intvecs: palign(8) > 0x00002000". However, the documentation seems to imply this should be unnecessary. This leads me to these questions:
- Why is palign(8) required in the .intvecs section, when I have Flash origin set to 0x2000, when it was not present or necessary when Flash origin was set to 0x0000? In other words, why isn't palign(8) in the section AFTER .intvecs sufficient? Is this a bug or expected behavior?
- Am I okay going forward with the linker that I now have?
- Why are all of these sections 8-byte aligned, instead of, say 4-bytes (32 bits)? It is a 32 bit processor after all. I'm trying to improve my limited knowledge here.
Regards,
Charlie
/*****************************************************************************
Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the
distribution.
Neither the name of Texas Instruments Incorporated nor the names of
its contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
-uinterruptVectors
--stack_size=256
MEMORY
{
FLASH (RX) : origin = 0x00002000, length = 0x0000DFF8
SRAM (RWX) : origin = 0x20000000, length = 0x00001000
}
SECTIONS
{
.intvecs: palign(8) > 0x00002000 //next section won't actually start at 8-byte boundary unless palign(8) is here.
.text : palign(8) {} > FLASH
.const : palign(8) {} > FLASH
.cinit : palign(8) {} > FLASH
.pinit : palign(8) {} > FLASH
.rodata : palign(8) {} > FLASH
.ARM.exidx : palign(8) {} > FLASH
.init_array : palign(8) {} > FLASH
.binit : palign(8) {} > FLASH
.TI.ramfunc : load = FLASH, palign(8), run=SRAM, table(BINIT)
.vtable : > SRAM
.args : > SRAM
.data : > SRAM
.bss : > SRAM
.sysmem : > SRAM
.stack : > SRAM (HIGH)
}