[fpc-devel] How can I distribute code in two different memory areas? (.section)

Michael Ring mail at michael-ring.org
Sun Jun 16 21:39:35 CEST 2013

I had some time this weekend (while beeing grilled by the sun on my 
balcony) to work on another thing that did not work correct and that I 
did not understand (Now I do, I least I hope ;-)

As said before in this thread, I wanted to distribute Code in two 
different memory areas because this needs to be done so that pic32 
startup code works correctly.

But when I linked my binary the elf-file had always a startup address 
somewhere in the wrong memory area.

This is what I tried:

procedure reset; assembler; nostackframe; public name'_reset';
   .section ".reset,\"ax\", at progbits"
   la      $k0, _startup
   jr      $k0                      //Jump to startup code

but this does not what I expected. I thought that the code would go to 
the segment I assigned to .reset in the linker script (that worked) and 
I also thought that the symbol _reset would point to this location

... which did not happen ...

the symbol _reset will get defined somewhere in the .text segment even 
though the code resides in another segment (please see the generated 
assembler listing created by inline asm later in this mail). All in all 
that makes perfect sense, the compiler is doing exactly what I wrote but 
not what I wanted ;-) ;-)

So I created a 'real' assembler file for the startup code, there i wrote:

         .section .reset,"ax", at progbits
         .set noreorder
         .ent _reset
         la      $k0, _startup
         jr      $k0                      # Jump to startup code

         .end _reset
         .globl _reset

this worked perfect, now the linker uses the address of the _reset 
procedure in the correct memory area as the startup address.

So is there a way I can get this behaviour in inline assembler?

Something like:

procedure reset; assembler; nostackframe; public name '_reset'; section 
'.reset,"ax", at progbits';




---- generated assemblerfile:

.section .text.n_pic32mx1xxfxxxb_$$_reset
         .balign 4
         .type   PIC32MX1XXFXXXB_$$_RESET, at function
.globl  _reset
         .type   _reset, at function
         .ent    PIC32MX1XXFXXXB_$$_RESET

.section .reset,"ax", at progbits
         la      $k0, _startup
         jr      $k0

.section .text.n_pic32mx1xxfxxxb_$$_reset
# path: mipsel/
# file: pic32mx_start.inc
# indx: 2
         jr      $ra
         .set    macro
         .set    reorder
         .end    PIC32MX1XXFXXXB_$$_RESET
         .size   PIC32MX1XXFXXXB_$$_RESET, .Le1 - PIC32MX1XXFXXXB_$$_RESET

Am 03.06.13 08:07, schrieb Michael Ring:
> This version worked,
> thank you for your help!
> Michael
> Am 02.06.13 23:20, schrieb Jeppe Græsdal Johansen:
>> Den 02-06-2013 23:15, Michael Ring skrev:
>>> Unfortunately that does not seem to work (or I use it wrong):
>>> This procedure:
>>> procedure _general_exception_handler; assembler; nostackframe; 
>>> asm
>>>   .section "reset"
>>>   sdbbp 0;
>>>   .Lloopb:
>>>    b .Lloopb
>>> end;
>>> translates to:
>>> .section .text.n_pic32mx1xxfxxxc_$$__general_exception_handler
>>>         .balign 4
>>>         .type PIC32MX1XXFXXXC_$$__GENERAL_EXCEPTION_HANDLER, at function
>>>         .type   _GENERAL_EXCEPTION_HANDLER, at function
>>> .section reset
>>>         sdbbp   0
>>> .Lj11:
>>>         b       .Lj11
>>>         jr      $ra
>>>         nop
>>>         .set    macro
>>>         .set    reorder
>>> .Lt3:
>>> .Le2:
>>>         .size PIC32MX1XXFXXXC_$$__GENERAL_EXCEPTION_HANDLER, .Le2 - 
>>> .Ll8:
>>> which creates an assembler error:
>>> /Users/ring/devel/fpc/rtl/units/mipsel-embedded/pic32mx1xxfxxxc.s:94: Error: 
>>> operation combines symbols in different segments
>>> the error is from the .size line.
>>> Am 02.06.13 22:51, schrieb Jeppe Græsdal Johansen:
>>>> Den 02-06-2013 22:41, Michael Ring skrev:
>>>>> Hi, perhaps I am overseeing a simple solution for my problem:
>>>>> On the pic32 there are two flash areas, one at 0x9d000000 for the 
>>>>> main program and another at 0xbfc00000 that is called Boot Flash. 
>>>>> On reset the program starts in the boot flash at the first address.
>>>>> I have written the startup code for the chips now but I need to 
>>>>> distribute some procedures between the two memory areas, for 
>>>>> obvious reasons I must have some code at address 0xbfc00000 or the 
>>>>> chip will not boot correctly ;-).
>>>>> My thought was now to tweak the linker script in the same way the 
>>>>> original linker scripts of pic32 work:
>>>>> MEMORY
>>>>> {
>>>>>   kseg0_program_mem    (rx)  : ORIGIN = 0x9D000000, LENGTH = 0x80000
>>>>>   kseg1_boot_mem             : ORIGIN = 0xBFC00000, LENGTH = 0x490
>>>>> }
>>>>> {
>>>>>   .reset _RESET_ADDR :
>>>>>   {
>>>>>     KEEP(*(.reset))
>>>>>     KEEP(*(.reset.startup))
>>>>>   } > kseg1_boot_mem
>>>>> }
>>>>> In assembler I can then simply write:
>>>>>  .section .reset,code and
>>>>>  .section .reset.startup,code
>>>>> and then the code, this will automagically end up in the 
>>>>> kseg1_boot_mem, but this does not work with the inline assembler. 
>>>>> Any ideas on how to do this the correct way? Is there something 
>>>>> more intelligent than to write a plain assembler file?
>>>>> TnX,
>>>>> Michael
>>>> You should be able to use
>>>> .section ".reset" 
>> Try
>> procedure _general_exception_handler; assembler; nostackframe; public 
>> asm
>>   .section "reset"
>>   sdbbp 0;
>>   .Lloopb:
>>    b .Lloopb
>>   .text
>> end;
>> _______________________________________________
>> fpc-devel maillist  -fpc-devel at lists.freepascal.org
>> http://lists.freepascal.org/mailman/listinfo/fpc-devel
> _______________________________________________
> fpc-devel maillist  -  fpc-devel at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-devel

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20130616/57d974a7/attachment.html>

More information about the fpc-devel mailing list