How do I place the libaplc library in external memory ?

Discussion about Parallella (and Epiphany) Software Development

Moderators: amylaar, jeremybennett, simoncook

How do I place the libaplc library in external memory ?

Postby Dr.BeauWebber » Sun Jun 02, 2013 12:07 pm

Hi,
The Aplc run-time library libaplc.a is a bit too big to fit into internal memory.
I have looked at fast.ldf, but am still not clear how to move the aplc library into the external memory as per newlib.
The linking looks like :
Code: Select all
ESDK=${EPIPHANY_HOME}
ELDF=${ESDK}/bsps/current/fast.ldf

e-gcc -T ${ELDF} -L ${LIBAPLC} src/${PROGRAM}.c -o Debug/${PROGRAM}.elf -laplc -lm  -le-lib

The error message I get is :
Code: Select all
/opt/adapteva/esdk/tools/e-gnu.arm7l/bin/../lib/gcc/epiphany-elf/4.7.0/../../../../epiphany-elf/bin/ld: Debug/aplc_helloworld_ed.elf section `.text' will not fit in region `INTERNAL_RAM'
/opt/adapteva/esdk/tools/e-gnu.arm7l/bin/../lib/gcc/epiphany-elf/4.7.0/../../../../epiphany-elf/bin/ld: region `INTERNAL_RAM' overflowed by 79368 bytes
collect2: error: ld returned 1 exit status

help appreciated
cheers,
Beau
User avatar
Dr.BeauWebber
 
Posts: 114
Joined: Mon Dec 17, 2012 4:01 am
Location: England

Re: How do I place the libaplc library in external memory ?

Postby Dr.BeauWebber » Sun Jun 02, 2013 5:46 pm

Well I have looked at the existing code in fast.ldf carefully, and tried the following, however it does not seem to be finding the .o files in the library.
A first question - my library is currently a .a - does it need to be a .so ?
Second question - is my syntax wrong ?
Code: Select all
       /* the aplc (libaplc ) library is mapped to the dedicated section */
        /* create offset with location counter                                    */
        . = (ORIGIN(EXTERNAL_DRAM_0) + __PROG_SIZE_FOR_CORE_ * __CORE_NUM_);

        APLC_LIB_RO           . : {libaplc-*.o(.text  .rodata)   } > EXTERNAL_DRAM_0
        APLC_LIB_WR           . : {libaplc-*.o(.data)            } > EXTERNAL_DRAM_0

I have also tried listing the .o names explicitly :
Code: Select all
APLC_LIB_RO           . : {libaplc-runio_ex.o
etc
Code: Select all
$ ./build_ed.sh
/opt/adapteva/esdk/tools/e-gnu.arm7l/bin/../lib/gcc/epiphany-elf/4.7.0/../../../../epiphany-elf/bin/ld: cannot find lib_aplc-runio_ex.o
collect2: error: ld returned 1 exit status

Hmm, it is 35 years since I worked with 8 and 16 bit micros where I had to worry where the program went - more recently I have been working with 32 and 64 bit computers, and with FPGAs.
Help appreciated.
cheers, Beau
User avatar
Dr.BeauWebber
 
Posts: 114
Joined: Mon Dec 17, 2012 4:01 am
Location: England

Re: How do I place the libaplc library in external memory ?

Postby ed2k » Tue Jun 04, 2013 6:08 am

does it work on legacy.ldf? I mean try the other way around, start from legacy.ldf and move the needed lib into internal.
as mentioned in this post http://forums.parallella.org/viewtopic.php?f=13&t=332
ed2k
 
Posts: 113
Joined: Mon Dec 17, 2012 3:27 am

Re: How do I place the libaplc library in external memory ?

Postby Dr.BeauWebber » Tue Jun 04, 2013 10:40 am

Thanks yes that partly works, I am using the legacy.ldf at the moment.
I have two problems :
1) I am using a buffer as a buffer for std out replacement, and that is overlapping the working program, I do not know how to separate them using the .ldf.
2) when I try and move functions they 'are not found' I think my syntax is wrong

- is there a .ldf guide anywhere ? Is it particular to the parallella ? I have seen some for the Blackfin, but that looks different.
User avatar
Dr.BeauWebber
 
Posts: 114
Joined: Mon Dec 17, 2012 4:01 am
Location: England

Re: How do I place the libaplc library in external memory ?

Postby ysapir » Tue Jun 04, 2013 5:01 pm

When using the legacy or fast profiles, some code is placed at the external memory. Normally, it will occupy a 1MB-pre-core region, starting at 0x8e000000. This means that the code will occupy up to 16MB of the external space.

The upper 16MB are allocated for the program heap, again, 1MB per core. When using malloc(), *printf() and other stdio functions that use malloc internally, they will use this heap space for their operation. If you look carefully you'll notice that the heap segments are locates in the "shared_dram" section. This means that what you see is most probably the heap running over your mailbox, or vice-versa.

If this is indeed the case, you can solve it by doing one of these:

1. Using a custom LDF, shrink down the heap and locate it in the upper part of "shared_dram";

2. Assuming that the program operation does not require too much heap space, and that the heap grows linearly, you can place your mailbox in the upper area of the section. In order to do this, you can:

2.1. Change your outbuf from a string to a pointer and assign it a specific address (say 0x8fffff00), discarding the SECTION() attribute. Remember to change the mailbox address in the host program accordingly;

2.2. In a custom LDF, define a new section in a specific address (say 0x8fffff00) and change the outpuf attribute to that section name. See the matmul example for an how-to reference.

The GNU website has a reference manual for linker scripts, if you want to go deeper in the LDF mechanics:

http://sourceware.org/binutils/docs/ld/Scripts.html#Scripts

and here's another one:

http://www.bravegnu.org/gnu-eprog/lds.html
User avatar
ysapir
 
Posts: 393
Joined: Tue Dec 11, 2012 7:05 pm

Re: How do I place the libaplc library in external memory ?

Postby Dr.BeauWebber » Wed Jun 05, 2013 12:33 am

Ah thanks indeed ysapir.
I have some my best to implement option 2.2 - does not work yet, so if you could look through th following and point out the error I would really appreciate it.
I particularly found the bravegnu link very clear, and now know why my attempt at a combined internal/external .ldf was probably failing.

I want to be able to output about a page of array text, for these initial tests, so I am allocating a buffer of 4k.
1. Using a custom LDF, shrink down the heap and locate it in the upper part of "shared_dram"

Code: Select all
 /* __HEAP_SIZE_FOR_CORE_ = 512K; */
__HEAP_SIZE_FOR_CORE_ = 508K;
 

2.2. In a custom LDF, define a new section in a specific address (say 0x8fffff00) and change the outpuf attribute to that section name.

I believe the heap is in dram section 1, so :
Code: Select all
 __BUFFER_SIZE_        = 4K;   /* for host communication */
__BUFFER_LOCATION_ =   0x8ffff000;
 

Code: Select all
               . = (__BUFFER_LOCATION_);
        BUFFER_SPACE    . : {}  > EXTERNAL_DRAM_1
 

Then the buffer declaration in the program becomes :
Code: Select all
 /* char outbuf[128] SECTION("shared_dram"); */
char outbuf[4096] SECTION("buffer_location");
 

Remember to change the mailbox address in the host program accordingly;

Code: Select all
 // #define _BufSize   (128)
#define _BufSize   (4096)
// #define _BufOffset (0x01000000)
#define _BufOffset (0x00fff000)
 

Well It compiles, but I get garbage when I run : the page keeps clearing, for each line of output.
If I reduce the above read buffer size to 15 characters, it is better behaved, but still garbage :
Code: Select all
  0: Message from eCore 0x8ca ( 3, 2): "@ɨÉA¼CÐ @AA"
  1: Message from eCore 0x84b ( 1, 3): "@ɨÉA¼CÐ @AA"
  2: Message from eCore 0x84b ( 1, 3): "@ɨÉA¼CÐ @AA"
  3: Message from eCore 0x888 ( 2, 0): "@ɨÉA¼CÐ @AA"
 
etc.
I have also tried with a 128 byte buffer at 0x8fffff00 :
Code: Select all
harness_01.elf: e_alloc(): mmap failure.
  0: Message from eCore 0x8ca ( 3, 2):


Can you see what I am doing wrong ?
User avatar
Dr.BeauWebber
 
Posts: 114
Joined: Mon Dec 17, 2012 4:01 am
Location: England

Re: How do I place the libaplc library in external memory ?

Postby ysapir » Wed Jun 05, 2013 1:00 am

From a glance, before really verifying your LDF code, I think that the host buffer address should be 0x01fff000, and not 0x00fff000 (I assume that the buffer is above the heap, and the heaps start at 0x01000000).

Also, there is a problem with e_alloc() when the offset is not a multiple of page size (4KB on this system), which is why you get the mmap() failure when allocating the 128 bytes buffer. I am actually right now working on a fix for this problem, which I found a couple of days ago, so it should be OK in the next release.
User avatar
ysapir
 
Posts: 393
Joined: Tue Dec 11, 2012 7:05 pm

Re: How do I place the libaplc library in external memory ?

Postby Dr.BeauWebber » Wed Jun 05, 2013 7:32 am

Thanks ysapir,
yes I woke up realising the buffer is now in dram1, not 0, and should have the offset 0x01fff000 as you say.
Yes that now runs, but I just get different garbage : more verbose with a 4k read buffer (as though I am reading program), ends with :
Code: Select all
PuTTYPuTTYPuTTYPuTTYPuTTYPuTTYPuTTYPuTTYPuTTYPuTTYPuTTYPuTTYPuTTYPuTTYPuTTYPuTTYPuTTYPuTTYPuTTYPuTT

and with a 15 byte read buffer :
Code: Select all
  0: Message from eCore 0x8ca ( 3, 2): "×~íëéO˼ëÚ©Ýwë"
  1: Message from eCore 0x84b ( 1, 3): "×~íëéO˼ëÚ©Ýwë"
  2: Message from eCore 0x84b ( 1, 3): "×~íëéO˼ëÚ©Ýwë"
etc.

Other variations I have tried have been no better.
Can't think of what to try next.
User avatar
Dr.BeauWebber
 
Posts: 114
Joined: Mon Dec 17, 2012 4:01 am
Location: England

Re: How do I place the libaplc library in external memory ?

Postby Dr.BeauWebber » Wed Jun 05, 2013 7:58 am

The modified legacy file :
Code: Select all
/*
  apl_legacy.ldf J.B.W.Webber@kent.ac.uk
  from legacy.ldf

  Copyright (C) 2012 Adapteva, Inc.
  Contributed by Yaniv Sapir <yaniv@adapteva.com>

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program, see the file COPYING.  If not, see
  <http://www.gnu.org/licenses/>.
*/


/* Linker script for supporing legacy code, with 4k com buffer */
OUTPUT_FORMAT("elf32-epiphany", "elf32-epiphany", "elf32-epiphany")
OUTPUT_ARCH(epiphany)
ENTRY(_start)

PROVIDE (___bss_start = __bss_start);

/* BSP specific */
__BUFFER_SIZE_         = 4k;   /* for host communication */
/*__BUFFER_LOCATION_ =   BUFFER_SPACE ; */
__BUFFER_LOCATION_ =   0x8ffff000; 
/* __BUFFER_LOCATION_ =   0x8fffff00; */
/* __BUFFER_LOCATION_ =   0x0000000; */ 


__PROG_SIZE_FOR_CORE_ = 1M;
/* __HEAP_SIZE_FOR_CORE_ = 512K; */
__HEAP_SIZE_FOR_CORE_ = 507K;
__HALF_BANK_SIZE_     = 4K;
__NUM_ROWS_IN_CHIP_   = 4;
__NUM_COLS_IN_CHIP_   = 4;
__FIRST_CORE_ROW_     = 32;
__FIRST_CORE_COL_     = 8;
__CORE_ROW_ = DEFINED(__CORE_ROW_) ? __CORE_ROW_ : __FIRST_CORE_ROW_;
__CORE_COL_ = DEFINED(__CORE_COL_) ? __CORE_COL_ : __FIRST_CORE_COL_;
/* generic don't touch */
/* used to calculated the slice address in the external memory */
__CORE_NUM_ = (__CORE_ROW_ - __FIRST_CORE_ROW_) * __NUM_COLS_IN_CHIP_ + (__CORE_COL_ - __FIRST_CORE_COL_);

__SHARED_DRAM_ = 0x8e000000;

MEMORY
{
   EXTERNAL_DRAM_0 (WXAI)   : ORIGIN = 0x8e000000, LENGTH = 0x01000000  /* .text, data, rodata, bss and .stack  */
/*   EXTERNAL_DRAM_0 (WXAI)   : ORIGIN = 0x8e001000, LENGTH = 0x00999000 */ /* .text, data, rodata, bss and .stack  */
   EXTERNAL_DRAM_1 (WXAI)   : ORIGIN = 0x8f000000, LENGTH = 0x01000000 /* .heap                                */

   /* run time lib and crt0 */
   IVT_RAM (WXAI) : ORIGIN = 0, LENGTH = 0x32

   /* user program, continuous placement */
   INTERNAL_RAM (WXAI)      : ORIGIN = LENGTH(IVT_RAM), LENGTH = 32K - LENGTH(IVT_RAM)

        /* user program, per bank usage */

   BANK0_SRAM (WXAI)        : ORIGIN = LENGTH(IVT_RAM), LENGTH = 8K - LENGTH(IVT_RAM)
   BANK1_SRAM (WXAI)        : ORIGIN = 0x2000, LENGTH = 8K
   BANK2_SRAM (WXAI)        : ORIGIN = 0x4000, LENGTH = 8K
   BANK3_SRAM (WXAI)        : ORIGIN = 0x6000, LENGTH = 8K

   /* system registers */
   MMR (WAI) : ORIGIN = 0xF0000, LENGTH = 32K

   /* multicore (global) space */
   CORE_0x20_0x08_INTERNAL_RAM : ORIGIN = 0x80800000 + LENGTH(IVT_RAM), LENGTH = 32K - LENGTH(IVT_RAM)
   CORE_0x20_0x09_INTERNAL_RAM : ORIGIN = 0x80900000 + LENGTH(IVT_RAM), LENGTH = 32K - LENGTH(IVT_RAM)
   CORE_0x20_0x0a_INTERNAL_RAM : ORIGIN = 0x80a00000 + LENGTH(IVT_RAM), LENGTH = 32K - LENGTH(IVT_RAM)
   CORE_0x20_0x0b_INTERNAL_RAM : ORIGIN = 0x80b00000 + LENGTH(IVT_RAM), LENGTH = 32K - LENGTH(IVT_RAM)
   CORE_0x21_0x08_INTERNAL_RAM : ORIGIN = 0x84800000 + LENGTH(IVT_RAM), LENGTH = 32K - LENGTH(IVT_RAM)
   CORE_0x21_0x09_INTERNAL_RAM : ORIGIN = 0x84900000 + LENGTH(IVT_RAM), LENGTH = 32K - LENGTH(IVT_RAM)
   CORE_0x21_0x0a_INTERNAL_RAM : ORIGIN = 0x84a00000 + LENGTH(IVT_RAM), LENGTH = 32K - LENGTH(IVT_RAM)
   CORE_0x21_0x0b_INTERNAL_RAM : ORIGIN = 0x84b00000 + LENGTH(IVT_RAM), LENGTH = 32K - LENGTH(IVT_RAM)
   CORE_0x22_0x08_INTERNAL_RAM : ORIGIN = 0x88800000 + LENGTH(IVT_RAM), LENGTH = 32K - LENGTH(IVT_RAM)
   CORE_0x22_0x09_INTERNAL_RAM : ORIGIN = 0x88900000 + LENGTH(IVT_RAM), LENGTH = 32K - LENGTH(IVT_RAM)
   CORE_0x22_0x0a_INTERNAL_RAM : ORIGIN = 0x88a00000 + LENGTH(IVT_RAM), LENGTH = 32K - LENGTH(IVT_RAM)
   CORE_0x22_0x0b_INTERNAL_RAM : ORIGIN = 0x88b00000 + LENGTH(IVT_RAM), LENGTH = 32K - LENGTH(IVT_RAM)
   CORE_0x23_0x08_INTERNAL_RAM : ORIGIN = 0x8c800000 + LENGTH(IVT_RAM), LENGTH = 32K - LENGTH(IVT_RAM)
   CORE_0x23_0x09_INTERNAL_RAM : ORIGIN = 0x8c900000 + LENGTH(IVT_RAM), LENGTH = 32K - LENGTH(IVT_RAM)
   CORE_0x23_0x0a_INTERNAL_RAM : ORIGIN = 0x8ca00000 + LENGTH(IVT_RAM), LENGTH = 32K - LENGTH(IVT_RAM)
   CORE_0x23_0x0b_INTERNAL_RAM : ORIGIN = 0x8cb00000 + LENGTH(IVT_RAM), LENGTH = 32K - LENGTH(IVT_RAM)
}

SECTIONS
{
   ivt_reset               0   : {*.o(IVT_RESET)}                    > IVT_RAM
   ivt_software_exception  4   : {*.o(ivt_entry_software_exception)} > IVT_RAM
   ivt_page_miss           8   : {*.o(ivt_entry_page_miss)}          > IVT_RAM
   ivt_timer0              12  : {*.o(ivt_entry_timer0)}             > IVT_RAM
   ivt_timer1              16  : {*.o(ivt_entry_timer1)}             > IVT_RAM
   ivt_message             20  : {*.o(ivt_entry_message)}            > IVT_RAM
   ivt_dma0                24  : {*.o(ivt_entry_dma0)}               > IVT_RAM
   ivt_dma1                28  : {*.o(ivt_entry_dma1)}               > IVT_RAM
   ivt_swi                 32  : {*.o(ivt_entry_swi)}                > IVT_RAM

   /* place the ISR handlers after IVT */
   .reserved_crt0  ORIGIN(IVT_RAM) + LENGTH(IVT_RAM) : {*.o(RESERVED_CRT0) *.o(reserved_crt0)} > INTERNAL_RAM

   . = ADDR(.reserved_crt0) + SIZEOF(.reserved_crt0);
   .data_bank0 . : {*.o(.data_bank0)} > BANK0_SRAM
   . = ADDR(.data_bank0) + SIZEOF(.data_bank0);
   .text_bank0 . : {*.o(.text_bank0)} > BANK0_SRAM
   
   .data_bank1   : {*.o(.data_bank1)} > BANK1_SRAM
   .text_bank1   : {*.o(.text_bank1)} > BANK1_SRAM

   .data_bank2   : {*.o(.data_bank2)} > BANK2_SRAM
   .text_bank2   : {*.o(.text_bank2)} > BANK2_SRAM

   .data_bank3   : {*.o(.data_bank3)} > BANK3_SRAM
   .text_bank3   : {*.o(.text_bank3)} > BANK3_SRAM

   .code_dram    : {*.o(code_dram)  } > EXTERNAL_DRAM_0
   .shared_dram  : {*.o(shared_dram)} > EXTERNAL_DRAM_1
   .heap_dram   ORIGIN(EXTERNAL_DRAM_1) + LENGTH(EXTERNAL_DRAM_1) - __HEAP_SIZE_FOR_CORE_ * __NUM_ROWS_IN_CHIP_ * __NUM_COLS_IN_CHIP_ : {*.o(heap_dram)} > EXTERNAL_DRAM_1


      . = (__BUFFER_LOCATION_);
   BUFFER_SPACE    . : { }  > EXTERNAL_DRAM_1
   /* . = ( .  + __BUFFER_SIZE_); */
   
   /* the newlib  (libc and libm) library is mapped to the dedicated section */
   /* create offset with location counter                                    */

      . = (ORIGIN(EXTERNAL_DRAM_0) + __PROG_SIZE_FOR_CORE_ * __CORE_NUM_); 

   NEW_LIB_RO           . : {lib_a-*.o(.text  .rodata)  *.o(libgloss_epiphany) } > EXTERNAL_DRAM_0
   NEW_LIB_WR           . : {lib_a-*.o(.data)                                  } > EXTERNAL_DRAM_0
   GNU_C_BUILTIN_LIB_RO . :
   {
      *mulsi3.o(.text  .rodata)   *modsi3.o(.text  .rodata)
      *divsi3.o(.text  .rodata)   *udivsi3.o(.text .rodata)
      *umodsi3.o(.text .rodata)  _*.o(.text  .rodata)
   } > EXTERNAL_DRAM_0

  /* Read-only sections, merged into text segment: */

  .interp            : { *(.interp) }
  .note.gnu.build-id : { *(.note.gnu.build-id) }
  .hash              : { *(.hash) }
  .gnu.hash          : { *(.gnu.hash) }
  .dynsym            : { *(.dynsym) }
  .dynstr            : { *(.dynstr) }
  .gnu.version       : { *(.gnu.version) }
  .gnu.version_d     : { *(.gnu.version_d) }
  .gnu.version_r     : { *(.gnu.version_r) }
  .rela.init         : { *(.rela.init) }
  .rela.text         : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
  .rela.fini         : { *(.rela.fini) }
  .rela.rodata       : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
  .rela.data.rel.ro  : { *(.rela.data.rel.ro* .rela.gnu.linkonce.d.rel.ro.*) }
  .rela.data         : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
  .rela.tdata        : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
  .rela.tbss         : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
  .rela.ctors        : { *(.rela.ctors) }
  .rela.dtors        : { *(.rela.dtors) }
  .rela.got          : { *(.rela.got) }
  .rela.sdata        : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }
  .rela.sbss         : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) }
  .rela.sdata2       : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }
  .rela.sbss2        : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
  .rela.bss          : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
  .rela.iplt         :
    {
      PROVIDE_HIDDEN (__rela_iplt_start = .);
      *(.rela.iplt)
      PROVIDE_HIDDEN (__rela_iplt_end = .);
    }
  .rela.plt :
    {
      *(.rela.plt)
    }

  .init :
  {
    KEEP (*(.init))
  } > EXTERNAL_DRAM_0 =0

  .plt  : { *(.plt) }
  .iplt : { *(.iplt) }
  .text :
  {
    *(.text.unlikely .text.*_unlikely)
    *(.text.exit .text.exit.*)
    *(.text.startup .text.startup.*)
    *(.text.hot .text.hot.*)
    *(.text .stub .text.* .gnu.linkonce.t.*)
    /* .gnu.warning sections are handled specially by elf32.em. */
    *(.gnu.warning)
  } > EXTERNAL_DRAM_0 =0
  .fini :
  {
    KEEP (*(.fini))
  } > EXTERNAL_DRAM_0 =0
  PROVIDE (__etext = .);
  PROVIDE (_etext = .);
  PROVIDE (etext = .);
  .rodata1        : { *(.rodata1) }
  .sdata2         :
  {
    *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
  }
  .sbss2          : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
  .eh_frame_hdr : { *(.eh_frame_hdr) }
  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table
  .gcc_except_table.*) }
  /* These sections are generated by the Sun/Oracle C++ compiler. */
  .exception_ranges   : ONLY_IF_RO { *(.exception_ranges
  .exception_ranges*) }
  /* Adjust the address for the data segment.  We want to adjust up to
     the same address within the page on the next page up.  */
  . = ALIGN(1) + (. & (1 - 1));
  /* Exception handling  */
  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
  .exception_ranges   : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
  /* Thread Local Storage sections  */
  .tdata  : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
  .tbss   : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  }> EXTERNAL_DRAM_0
  .init_array     :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array))
    PROVIDE_HIDDEN (__init_array_end = .);
  }> EXTERNAL_DRAM_0
  .fini_array     :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array))
    PROVIDE_HIDDEN (__fini_array_end = .);
  }> EXTERNAL_DRAM_0
  .ctors          :
  {
    /* gcc uses crtbegin.o to find the start of
       the constructors, so we make sure it is
       first.  Because this is a wildcard, it
       doesn't matter if the user does not
       actually link against crtbegin.o; the
       linker won't look for a file to match a
       wildcard.  The wildcard also means that it
       doesn't matter which directory crtbegin.o
       is in.  */
    KEEP (*crtbegin.o(.ctors))
    KEEP (*crtbegin?.o(.ctors))
    /* We don't want to include the .ctor section from
       the crtend.o file until after the sorted ctors.
       The .ctor section from the crtend file contains the
       end of ctors marker and it must be last */
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
  }> EXTERNAL_DRAM_0
  .dtors          :
  {
    KEEP (*crtbegin.o(.dtors))
    KEEP (*crtbegin?.o(.dtors))
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
  }> EXTERNAL_DRAM_0
  .jcr            : { KEEP (*(.jcr)) }> EXTERNAL_DRAM_0
  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
  .dynamic        : { *(.dynamic) }
  .data           :
  {
    *(.data .data.* .gnu.linkonce.d.*)
    SORT(CONSTRUCTORS)
  }> EXTERNAL_DRAM_0
  .data1          : { *(.data1) }> EXTERNAL_DRAM_0
  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }> EXTERNAL_DRAM_0
  .got            : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
  /* We want the small data sections together, so single-instruction offsets
     can access them all, and initialized data all before uninitialized, so
     we can shorten the on-disk segment size.  */
  .sdata          :
  {
    *(.sdata .sdata.* .gnu.linkonce.s.*)
  }
  . = ALIGN(8);
  _edata = .; PROVIDE (edata = .);
  __bss_start = .;
  .sbss           :
  {
    *(.dynsbss)
    *(.sbss .sbss.* .gnu.linkonce.sb.*)
    *(.scommon)
  }
  .bss            :
  {
   *(.dynbss)
   *(.bss .bss.* .gnu.linkonce.b.*)
   *(COMMON)
   /* Align here to ensure that the .bss section occupies space up to
      _end.  Align after .bss to ensure correct alignment even if the
      .bss section disappears because there are no input sections.
      FIXME: Why do we need it? When there is no .bss section, we don't
      pad the .data section.  */
   . = ALIGN(. != 0 ? 8 : 1);
  }> EXTERNAL_DRAM_0
  . = ALIGN(8);
  . = ALIGN(8);
  _end = .; PROVIDE (end = .);
  /* Stabs debugging sections.  */
  .stab          0 : { *(.stab) }
  .stabstr       0 : { *(.stabstr) }
  .stab.excl     0 : { *(.stab.excl) }
  .stab.exclstr  0 : { *(.stab.exclstr) }
  .stab.index    0 : { *(.stab.index) }
  .stab.indexstr 0 : { *(.stab.indexstr) }
  .comment       0 : { *(.comment) }
  /* DWARF debug sections.
     Symbols in the DWARF debugging sections are relative to the beginning
     of the section so we begin them at 0.  */
  /* DWARF 1 */
  .debug          0 : { *(.debug) }
  .line           0 : { *(.line) }
  /* GNU DWARF 1 extensions */
  .debug_srcinfo  0 : { *(.debug_srcinfo) }
  .debug_sfnames  0 : { *(.debug_sfnames) }
  /* DWARF 1.1 and DWARF 2 */
  .debug_aranges  0 : { *(.debug_aranges) }
  .debug_pubnames 0 : { *(.debug_pubnames) }
  /* DWARF 2 */
  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
  .debug_abbrev   0 : { *(.debug_abbrev) }
  .debug_line     0 : { *(.debug_line) }
  .debug_frame    0 : { *(.debug_frame) }
  .debug_str      0 : { *(.debug_str) }
  .debug_loc      0 : { *(.debug_loc) }
  .debug_macinfo  0 : { *(.debug_macinfo) }
  /* SGI/MIPS DWARF 2 extensions */
  .debug_weaknames 0 : { *(.debug_weaknames) }
  .debug_funcnames 0 : { *(.debug_funcnames) }
  .debug_typenames 0 : { *(.debug_typenames) }
  .debug_varnames  0 : { *(.debug_varnames) }
  /* DWARF 3 */
  .debug_pubtypes 0 : { *(.debug_pubtypes) }
  .debug_ranges   0 : { *(.debug_ranges) }
  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }

  /**/
  PROVIDE (__stack_start_ = ORIGIN(EXTERNAL_DRAM_0) + __PROG_SIZE_FOR_CORE_ * __CORE_NUM_ + __PROG_SIZE_FOR_CORE_ - 0x10);
  .stack __stack_start_ : { ___stack = .; *(.stack) }
  PROVIDE (___heap_start = ORIGIN(EXTERNAL_DRAM_1) + __HEAP_SIZE_FOR_CORE_ * __CORE_NUM_);
  /*.heap_start __heap_start_ :  { _heap_start_ = .; *(.heap_start) } */
  PROVIDE (___heap_end   = ORIGIN(EXTERNAL_DRAM_1) + __HEAP_SIZE_FOR_CORE_ * __CORE_NUM_ + __HEAP_SIZE_FOR_CORE_ - 4);
  /* .heap_end __heap_end_ : { _heap_end_ = .; *(.heap_end) } */

  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}
 
User avatar
Dr.BeauWebber
 
Posts: 114
Joined: Mon Dec 17, 2012 4:01 am
Location: England

Re: How do I place the libaplc library in external memory ?

Postby ysapir » Wed Jun 05, 2013 3:06 pm

What I see is that you defined an output section named "BUFFER_SPACE", but no input section to map to it. At the same time, you declared your buffer with a section attribute of "buffer_location", but there is no mention of this name in the LDF.


Code: Select all
__BUFFER_LOCATION_ =   0x8ffff000;

Code: Select all
. = (__BUFFER_LOCATION_);
BUFFER_SPACE    . : { }  > EXTERNAL_DRAM_1


Code: Select all
char outbuf[4096] SECTION("buffer_location");
User avatar
ysapir
 
Posts: 393
Joined: Tue Dec 11, 2012 7:05 pm

Next

Return to Programming Q & A

Who is online

Users browsing this forum: No registered users and 2 guests