I am working on firmware for a PIC32MX microcontroller. The program memory should be split into three segments:
startup_region)program1)program2)The firmware is only stored in either Section 2 or 3. The other is reserved for future updates. As such the active region can safely override the other to store the update. A config bit is flipped and the main() function of Section 0 now jumps to the other program on reboot.
As such I need the linker to put all functions except isr and main into Section 1 and everything else into Section 2. Section 3 must be left completely empty, as it may be overridden in the future.
I already tried to achieve this by modifying the default linker script, however I had no success.
linkerscript.ld:
/* [...] */
INCLUDE procdefs.gld
/* [...] */
SECTIONS
{
/* [...] */
.text :
{
/* isr() and main() should be at the very first locations in program memory */
*(.text.isr)
*(.text.main)
/* [...] */
. = ALIGN(4) ;
} >kseg0_program_mem
.program1 :
{
*(*.text)
} >program1
/* [...] */
}
procdefs.gld:
/* [...] */
MEMORY
{
kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x10000
startup_region (rx) : ORIGIN = 0x9D000000, LENGTH = 0x01000
program1 (rx) : ORIGIN = 0x9D002000, LENGTH = 0x07000
program2 (rx) : ORIGIN = 0x9D009000, LENGTH = 0x07000
kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970
/* [...] */
}
/* [...] */
This results in the following:
isr() and main() are where they are supposed to be (0x9D00000 is the KSEG0 virtual address of the beginning of the program flash)
.text 0x9d000000 0x94
*(.text.isr)
.text.isr 0x9d000000 0x60 build/default/production/main.o
0x9d000000 isr
*(.text.main)
.text.main 0x9d000060 0x34 build/default/production/main.o
0x9d000060 main
The program1 region is correctly placed and most object files are listed correctly (notice however, that main.o is listed again -- it was already used).
.program1 0x9d002000 0xc44
*(*.text)
.text 0x9d002000 0x0 /opt/microchip/xc32/v2.10/bin/bin/../../lib/gcc/pic32mx/4.8.3/../../../../pic32mx/lib/./proc/32MX330F064H/crt0_mips32r2.o
.text 0x9d002000 0x0 /opt/microchip/xc32/v2.10/bin/bin/../../lib/gcc/pic32mx/4.8.3/../../../../pic32mx/lib/debug-exception-return.o
.text 0x9d002000 0x0 build/default/production/main.o
.text 0x9d002000 0x0 build/default/production/commands.o
/* [...] */
.text 0x9d002000 0x0 build/default/production/micro-ecc/uECC.o
However, some function are located outside of this region:
.text.uECC_verify
0x9d000b04 0x7c0
.text.uECC_verify
0x9d000b04 0x7c0 build/default/production/micro-ecc/uECC.o
0x9d000b04 uECC_verify
.text.vli_mmod_fast_secp256r1
0x9d0012c4 0x520
.text.vli_mmod_fast_secp256r1
0x9d0012c4 0x520 build/default/production/micro-ecc/uECC.o
I do not understand why this happens.
My questions are:
main and isr) into program1.program2, so that it remains free.I am compiling the software with the -ffunction-segments switch, so that each function gets its own segment.
The original linkerscript also contains this suspicious looking comment:
/* Code Sections - Note that input sections *(.text) and *(.text.*)
are not mapped here. Starting in C32 v2.00, the best-fit allocator
locates them, so that .text may flow around absolute sections
as needed.
*/
The object file main.o is not the same as the function’s memory segment .tex.main. If this object file produces some other text segments they will be placed elsewhere. This is what you see in your map file.
As @Ctx mentioned the syntax of your text segment is wrong instead of *(*.text) it should be
.program1 :
{
*(.text*)
} >program1
This way all other text segments will be properly placed in the program1 memory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With